pgSQL“错误:解析电子邮件时编码”UTF8“:0x86”的无效字节序列

时间:2015-07-04 13:04:17

标签: php postgresql email encoding utf-8

我正在将票证系统迁移到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。

由于解析电子邮件,我还没有找到特定于此错误的线程。

2 个答案:

答案 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序列中的第一个字节。

可能的解释包括:

  • 电子邮件不是utf-8编码
  • 电子邮件是utf-8编码但电子邮件中的utf-8格式错误
  • 通过非utf-8感知子字符串代码在utf-8序列中以无效字节偏移量切割字符串
  • 您的应用是错误处理MIME部分中的编码
  • ...

一般情况下,您在向PostgreSQL中插入电子邮件时会遇到问题,因为PostgreSQL对文本编码的正确性非常严格,而邮件客户端会产生并接受各种可怕的垃圾。您将需要清理传入的邮件(使用编码猜测,剥离可疑的部分/字符等)或将其以原始字节序列形式存储为bytea

我强烈建议将其存储为bytea,因为:

  • 一条MIME邮件可以包含不同编码的部分
  • 如果电子邮件附件不是Content-Transfer-Encoding,则可以发送包含NULL字节的MIME部分,但大多数客户都不会这样做,并且会对它们进行base64编码。 PostgreSQL的text类型不能存储空字节。

当然,这在很大程度上取决于您的处理方式。您可能更愿意将其存储为text并丢弃无法使用其声明的文本编码进行解码的部分。