我正在将票证系统迁移到pgSQL。我允许电子邮件回复,其中PHP将每个电子邮件解析为其组件,然后将邮件存储在名为inbox的pgSQL表中。
解析后的第一封电子邮件,然后成功保存。没有错误。现在我收到错误消息
invalid byte sequence for encoding "UTF8": 0x86
我已确认数据库正在使用UTF8编码: - SHOW SERVER_ENCODING给出了UTF8的结果 - 显示CLIENT_ENCODING最初不是UTF8。我把它设置为UTF8。
错误仍然存在。
email_queue.php 包含用于接收和发送电子邮件的各种PHP类和函数。命令“file email_queue.php”给出结果:
email_queue.php: PHP script, UTF-8 Unicode text, with very long lines
email_queue_receive.php 使用接收电子邮件的类和函数。该文件包含email_queue.php以获取该功能。命令“file email_queue_receive.php”给出结果:
email_queue_receive.php: PHP script, ASCII text
从搜索结果我已经完成ASCII是一个有效的UTF8。
由于解析电子邮件,我还没有找到特定于此错误的线程。
答案 0 :(得分:3)
PostgreSQL对编码很严格,但电子邮件基础设施却没有。 正如PHP iconv_mime_decode的文档所示:
ICONV_MIME_DECODE_STRICT如果设置,则完整解码给定标头 符合»RFC2047中定义的标准。这个选项是 默认情况下禁用,因为有很多损坏的邮件用户代理 不符合规范,不生成正确的MIME 头。
电子邮件正文中还有MIME部分违反Content-Type
声明中公布的字符。 SMTP服务器将接受无效邮件,只要它可以路由到收件人,因此发件人不会意识到问题,它是必须处理它的收件人。
因此,必须事先清理必须插入数据库文本字段的电子邮件消息的任何部分。例如,请参阅Remove non-utf8 characters from string了解如何操作。
答案 1 :(得分:2)
(丹尼尔是对的,只是详细阐述):
0x86不能是utf-8序列中的第一个字节。
可能的解释包括:
一般情况下,您在向PostgreSQL中插入电子邮件时会遇到问题,因为PostgreSQL对文本编码的正确性非常严格,而邮件客户端会产生并接受各种可怕的垃圾。您将需要清理传入的邮件(使用编码猜测,剥离可疑的部分/字符等)或将其以原始字节序列形式存储为bytea
。
我强烈建议将其存储为bytea
,因为:
Content-Transfer-Encoding
,则可以发送包含NULL字节的MIME部分,但大多数客户都不会这样做,并且会对它们进行base64编码。 PostgreSQL的text
类型不能存储空字节。当然,这在很大程度上取决于您的处理方式。您可能更愿意将其存储为text
并丢弃无法使用其声明的文本编码进行解码的部分。