PostgreSQL中的UTF-8问题

时间:2012-08-14 09:53:24

标签: php postgresql unicode utf-8

我的数据库是UTF-8(PostgreSQL)。我将'TESTμTEST'保存到数据库中,没关系。但是当我从数据库中选择这个值时,我看到了'TESTÂμTEST'。

此外,当我提出请求select * from tbl where f='TESTµTEST'时,我收到了此错误:

  

错误:编码“UTF8”的字节序列无效:0xb5。

请你给我解决方案吗?

2 个答案:

答案 0 :(得分:3)

该错误表明您正在尝试将latin-1文本解码为utf-8。很可能PHP中的client_encoding设置与您实际发送的数据的编码不匹配。

字符串“TESTÂμTEST”是通过将数据从Unicode编码为utf-8字节序列,然后将其解码为latin-1而生成的。你可以在psql中看到这个:

regress=# select convert_from(convert_to('TESTµTEST','utf-8'),'latin-1');
 convert_from 
--------------
 TESTµTEST

如果PostgreSQL数据库是utf-8,如果latin-1被正确设置为utf-8,它会将client_encoding输入转换为latin-1。如果client_encoding未正确设置为utf-8且您发送latin-1编码数据,PostgreSQL将拒绝接受以下消息:

invalid byte sequence for encoding "UTF8": 0xb5

...当你运行你展示的SELECT时会发生什么。所以 - 我说你的客户端设置为client_encoding = 'utf-8',但你的PHP脚本实际上是在发送latin-1数据。我希望这是因为,正如@dezso所说,你正在用一个使用latin-1编码的文本编辑器编辑你的PHP脚本。

要找出PHP使用的编码,请使用PHP数据库连接运行SHOW client_encoding;

要显示数据库编码,请运行:

SELECT d.datname, pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding" 
FROM pg_database d WHERE datname = 'my_db_name_here';

哦,另一种可能性是Apache(或其他)希望你的PHP脚本被utf-8编码,但它们实际上是latin-1编码的文件。

答案 1 :(得分:0)

将表复制到包含相同符号(来自standard nutrient database v26的表)的PostgreSQL 9.1时,我遇到了同样的错误。我使用新编码重新创建了数据库,但我还必须指定适当的locale and template

CREATE DATABASE testdb
  WITH OWNER = postgres
  ENCODING = 'LATIN1'
  LC_COLLATE = 'eng_canada.28591'
  LC_CTYPE = 'eng_canada.28591'
  TEMPLATE = template0;