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

Posted

技术标签:

【中文标题】当有“ñ”字母时,带有firebird的PDO会抛出“�”【英文标题】:PDO with firebird throws "�" ​when there is a "ñ" letter 【发布时间】:2021-04-16 16:05:14 【问题描述】:

我的桌子:

+--------+----------+
| 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 数据库中的任何其他详细信息,请告诉我。

编辑

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�"
  

【问题讨论】:

也许这会有所帮助***.com/questions/4475548/… @RiggsFolly 好的,我已经尝试了这些解决方案,但没有人解决我的问题,可能是 Firebase 问题。 也许这应该是我的第一个问题:¿ php+pdo+firebase utf8 兼容吗? 您是否阅读了 firebird 标签信息...。请在所有问题中引用您的 firebird 版本 查看右侧的“聊天”列以及用于诊断不同 PHP 和 Firebird 方面的字符集设置的查询topanswers.xyz/databases?q=1462 【参考方案1】:

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

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

【讨论】:

我明白了。 firebird 数据库是使用 Delphi 5.0 创建的,我正在尝试使用 php7 读取数据。你建议我做什么? @RobertoSepúlveda 见第二段。最简单的可能是使用显式字符集重新创建数据库结构并抽取数据(确保使用正确的字符集)。短期解决方法可能是使用不同的连接字符集(与存储数据的实际字符集匹配的字符集)。 从这个答案中,我正在搜索解决方案,并且在我的 php 文件顶部使用此代码行,我现在可以正确获取所有“ñ”字母:header('Content-type: text/plain; charset=ISO-8859-1');。我尝试了许多字符集,最后这有所帮助。唯一缺少的是json_encode在出现“ñ”时仍然输入空值,所以我通过迭代结果并“手动”制作json字符串来解决它。

以上是关于当有“ñ”字母时,带有firebird的PDO会抛出“�”的主要内容,如果未能解决你的问题,请参考以下文章

Firebird 数据库无法识别 unicode/西里尔字母

MAC自制php pdo firebird驱动程序

Firebird 程序不仅仅在 PDO 中执行

“连接被远程接口拒绝”使用 PDO 连接到 Firebird 3

BASH在名称中查找带有ñ的文件

编码俄语字母时的有缺陷的字符