当有“ñ”字母时,带有火鸟的 PDO 会抛出“�”

PDO with firebird throws "�" ​when there is a "ñ" letter

我的table:

+--------+----------+
| U_COD  |  U_NAME  |
+--------+----------+
|   01   |  Daniel  |
+--------+----------+
|   02   |  Ñandu   |
+--------+----------+
|   03   |  Pañ     |
+--------+----------+

我正在连接并像这样对我的 firebird 数据库进行简单查询:

$host = 'firebird:dbname=my/dir/db_test.gdb;charset=UTF8';
$password = 'mypass';
$username = 'myuname';

try{
  $db = new PDO($host, $username, $password);
  $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
  echo "Failed: " . $e->getMessage();
}

$getData=$db->prepare("SELECT * FROM T_TEST ORDER BY U_NAME ASC");
$getData->execute();
$arrData=$getData->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($arrData);

但是当我运行文件时,我的数据库中所有包含一些“ñ”字母的值都显示为空,像这样:

[
    {"U_COD":"01","U_NAME":"Daniel"}, 
    {"U_COD":"02","U_NAME":null},
    {"U_COD":"03","U_NAME":null}
]

我想知道我做错了什么,如果您需要我的 firebird 数据库中的任何其他详细信息,请告诉我。

编辑

a var_dump($arrData) 显示值,但在应该有“ñ”字母时带有“�”:

array(3) {
  [0]=>
  array(2) {
    ["U_COD"]=>
    string(2) "01"
    ["U_NAME"]=>
    string(6) "Daniel"
  },
  array(2) {
    ["U_COD"]=>
    string(2) "02"
    ["U_NAME"]=>
    string(5) "�andu"
  },
  array(2) {
    ["U_COD"]=>
    string(2) "03"
    ["U_NAME"]=>
    string(3) "Pa�"
  }
}

问题是该列的字符集是 NONE,并且该列中存储的字节(例如,它是使用 WIN1252 等编码存储的)和您的字节之间可能不匹配连接字符集 (UTF8)。鉴于源列没有明确的字符集,Firebird 无法将字符音译为连接字符集,而是按原样发送字节,ñ 的字节在 UTF8 中无效,因此 PHP 将其替换为 unicode 替换字符。

作为短期解决方案,您可以尝试明确指定正确的连接字符集(例如 WIN1252)或明确强制转换列(例如 cast(U_NAME as varchar(100) character set win1252)),但对于长期解决方案,您需要确保使用明确的字符集定义列。在您当前的设置中,如果您 write 来自多个应用程序的数据,每个应用程序都使用自己的隐式或显式连接字符集(例如,一个应用程序使用 WIN1252 写入,另一个应用程序使用UTF8,然后 - 如果列没有明确的字符集 - 一个人无法正确读取另一个人写入的数据)。