问题
当使用本机PHP ODBC功能(PDO_ODBC或更旧的
odbc_功能)和Access
ODBC驱动程序时,即使文本以Unipre字符存储在Access数据库中,文本也不是UTF-8编码的。因此,对于一个名为“ Teams”的示例表
Team-----------------------Boston BruinsCanadiens de MontréalФедерация хоккея России
编码
<?phpheader('Content-Type: text/html; charset=utf-8');?><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Access character test</title></head><body><?php$connStr = 'odbc:' . 'Driver={Microsoft Access Driver (*.mdb)};' . 'Dbq=C:\Users\Public\__SO\28311687.mdb;' . 'Uid=Admin;';$db = new PDO($connStr);$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);$sql = "SELECt Team FROM Teams";foreach ($db->query($sql) as $row) { $s = $row["Team"]; echo $s . "<br/>n";}?></body></html>在浏览器中显示
Boston BruinsCanadiens de Montr�al????????? ?????? ??????
简单但不完整的修复
Access
ODBC返回的文本实际上与该字符集中的字符的Windows-1252字符编码匹配,因此只需更改该行
$s = $row["Team"];
至
$s = utf8_enpre($row["Team"]);
将允许第二个条目正确显示
Boston BruinsCanadiens de Montréal????????? ?????? ??????
但是utf8_enpre()函数是从ISO-8859-1(而不是Windows-1252
)转换的,因此某些字符(特别是欧元符号“€”)将消失。更好的解决方案是使用
$s = mb_convert_encoding($row["Team"], "UTF-8", "Windows-1252");
但这仍然无法解决示例表中第三个条目的问题。
完整修复
为了获得完整的UTF-8支持,我们需要将COM与ADODB
Connection和Recordset对象一起使用,如下所示
<?phpheader('Content-Type: text/html; charset=utf-8');?><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Access character test</title></head><body><?php$connStr = 'Driver={Microsoft Access Driver (*.mdb)};' . 'Dbq=C:\Users\Public\__SO\28311687.mdb';$con = new COM("ADODB.Connection", NULL, CP_UTF8); // specify UTF-8 pre page$con->Open($connStr);$rst = new COM("ADODB.Recordset");$sql = "SELECt Team FROM Teams";$rst->Open($sql, $con, 3, 3); // adOpenStatic, adLockOptimisticwhile (!$rst->EOF) { $s = $rst->Fields("Team"); echo $s . "<br/>n"; $rst->MoveNext;}$rst->Close();$con->Close();?></body></html>


