PostgreSQL + PHP + UTF8 =用于编码的无效字节序列

时间:2009-11-05 00:23:55

标签: php postgresql encoding utf-8

我正在将数据库从mysql迁移到postgresql。 mysql db的默认排序规则是UTF8,postgres也使用UTF8,我用pg_escape_string()编码数据。无论出于何种原因,我遇到了一些关于错误编码的时髦错误:

pg_query() [function.pg-query]: Query failed: ERROR: invalid byte sequence for encoding "UTF8": 0xeb7374 HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client"

我一直在试图解决这个问题,并注意到php正在做一些奇怪的事情;如果一个字符串中只包含ascii字符(例如“hello”),则编码为ASCII。如果字符串包含任何非ascii字符,则表示编码为UTF8(例如“Hëllo”)。

当我在已经是UTF8的字符串上使用utf8_encode()时,它会杀死特殊的字符并使它们全部搞砸,所以......我能做些什么才能让它工作?

(现在把它挂起的确切字符是“ ”,但不是只搜索/替换,我想找到一个更好的解决方案,所以这种问题不会再发生了)

2 个答案:

答案 0 :(得分:6)

最有可能的是,MySQL数据库中的数据不是UTF8。这是一种非常常见的情况。 MySQL至少习惯于根本不对数据进行任何适当的验证,所以只要你的客户声称它是UTF8,它就会接受你把它作为UTF8的任何东西。他们可能已经解决了这个问题(或者不是,我不知道他们是否认为这是一个问题),但是你可能已经在db中编码了错误的数据。当然,PostgreSQL在加载时会执行完整的验证,因此可能会失败。

您可能希望通过iconv来提供数据,可以将其设置为忽略未知字符,或将其转换为“最佳猜测”。

答案 1 :(得分:1)

BTW,UTF-8中的ASCII字符串完全相同,因为它们共享相同的前127个字符;所以ASCII中的“Hello”与UTF-8中的“Hello”完全相同,不需要转换。

表中的排序规则可能是UTF-8,但您可能无法以相同的编码从中获取信息。现在,如果您对pg_escape_string提供的信息有疑问,可能是因为您假设从MySQL获取的内容是以UTF-8编码的,而不是。我建议您查看this page on MySQL documentation并查看连接的编码;你可能是从一个表格中取出,其中排序规则是UTF-8,但你的连接类似于Latin-1(其中特殊字符如çéèêöà等不会以UTF-8编码)。< / p>