MongoDB PHP UTF-8 问题另请参见

2022-08-31 00:57:17

假设我需要插入以下文档:

{
    title: 'Péter'
}

(注意 é)

当我使用以下PHP代码时,它给了我一个错误... :

$db->collection->insert(array("title" => "Péter"));

...因为它需要是utf-8。

所以我应该使用这行代码:

$db->collection->insert(array("title" => utf8_encode("Péter")));

现在,当我请求文档时,我仍然需要对其进行解码... :

$document = $db->collection->findOne(array("_id" => new MongoId("__someID__")));
$title = utf8_decode($document['title']);

有没有办法自动化这个过程?我可以更改MongoDB的字符编码吗(我正在迁移使用cp1252西欧(latin1)的MySQL数据库?

我已经考虑过更改Content-Type-header,问题是所有静态字符串(硬编码)都不是utf8...

提前致谢!提姆


答案 1

JSON和BSON只能编码/解码有效的UTF-8字符串,如果您的数据(包含的输入)不是UTF-8,则需要在将其传递到任何JSON依赖系统之前对其进行转换,如下所示:

$string = iconv('UTF-8', 'UTF-8//IGNORE', $string); // or
$string = iconv('UTF-8', 'UTF-8//TRANSLIT', $string); // or even
$string = iconv('UTF-8', 'UTF-8//TRANSLIT//IGNORE', $string); // not sure how this behaves

就个人而言,我更喜欢第一个选项,请参阅iconv()手册页面。其他替代方案包括:

您应该始终确保您的字符串是UTF-8编码的,甚至是用户提交的字符串,但是既然您提到要从MySQL迁移到MongoDB,您是否尝试过将当前数据库导出为CSV并使用Mongo附带的导入脚本?他们应该处理这个问题...


编辑:我提到BSON只能处理UTF-8,但我不确定这是否完全正确,我有一个模糊的想法,BSON使用UTF-16或UTF-32来编码/解码数据,但我现在无法检查。


答案 2

如前所述@gates,BSON中的所有字符串数据都编码为UTF-8。MongoDB假设了这一点。

两个答案都没有解决的另一个关键点:PHP不是Unicode感知的。无论如何,截至5.3。PHP 6应该是Unicode感知的。这意味着您必须知道操作系统默认使用哪种编码以及PHP使用的编码。

让我们回到你最初的问题:“有没有办法自动化这个过程?我的建议是确保在整个应用程序中始终使用 UTF-8。配置,输入,数据存储,演示,一切。那么“自动化”部分是,你的大多数PHP代码会更简单,因为它总是假设UTF-8。无需转换。哎呀,没有人说自动化很便宜。:)

这是题外话。如果您创建了一个小的PHP脚本来测试该代码,请弄清楚文件的编码是什么,然后在插入之前转换为UTF-8。例如,如果您知道文件是 ISO-8859-1,请尝试以下操作:insert()

$title = mb_convert_encoding("Péter", "UTF-8", "ISO-8859-1");
$db->collection->insert(array("title" => $title));

另请参见


推荐