php – 将SQL_Latin1_General_CP1_CI_AS编码为UTF-8

前端之家收集整理的这篇文章主要介绍了php – 将SQL_Latin1_General_CP1_CI_AS编码为UTF-8前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用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);

猜你在找的PHP相关文章