我使用DomDocument生成一个
PHP文件,我需要处理亚洲字符.我使用pdo_mssql驱动程序从MSsql2008服务器提取数据,并对XML属性值应用utf8_encode().只要没有特殊字符,一切都可以正常工作.
服务器是MS sql Server 2008 SP3
数据库,表和列归类都是sql_Latin1_General_CP1_CI_AS
我使用PHP 5.2.17
这是我的PDO对象:
$pdo = new PDO("mssql:host=MyServer,1433;dbname=MyDatabase",user123,password123);
我的查询是一个基本的SELECT.
我知道将特殊字符存储到sql_Latin1_General_CP1_CI_AS列中并不是很好,但是理想情况下,使其工作而不改变它,这是非常好的,因为其他非PHP程序已经使用该列,它的工作正常.在sql Server Management Studio中,我可以正确看到亚洲字符.
考虑到上述所有细节,我应该如何处理数据?
我发现如何解决它,所以希望这将有助于某人.
首先,sql_Latin1_General_CP1_CI_AS是CP-1252和UTF-8的一个奇怪的组合.
基本的角色是CP-1252,所以这就是为什么我只需要做的就是UTF-8,一切正常.亚洲和其他UTF-8字符是以2个字节编码的,PHP pdo_mssql驱动程序似乎讨厌不同长度的字符,所以似乎做了一个CAST到varchar(而不是nvarchar),然后所有的2个字节的字符都成为问号(‘ ?’).
我通过将其转换为二进制来修复它,然后用PHP重建文本:
SELECT CAST(MY_COLUMN AS VARBINARY(MAX)) FROM MY_TABLE;
在PHP中
//Binary to hexadecimal $hex = bin2hex($bin); //And then from hex to string $str = ""; for ($i=0;$i<strlen($hex) -1;$i+=2) { $str .= chr(hexdec($hex[$i].$hex[$i+1])); } //And then from UCS-2LE/sql_Latin1_General_CP1_CI_AS (that's the column format in the DB) to UTF-8 $str = iconv('UCS-2LE','UTF-8',$str);