PHP serialize() 带有重音字符导致不完整的序列化

Posted

技术标签:

【中文标题】PHP serialize() 带有重音字符导致不完整的序列化【英文标题】:PHP serialize() with accent characters causing incomplete serialization 【发布时间】:2018-08-17 02:15:52 【问题描述】:

我正在使用 PayPal IPN 并将 IPN 数据消息插入到我们的数据库中。我注意到它是一个部分对象。我假设序列化失败而不是插入。数据库或服务器均未报告错误。

例如,这是一个部分序列化。第一部分被我遗漏了:

... s:1:"4";s:12:"address_city";s:23:"COACALCO DE BERRIOZ

它在 BERRIOZ 之后直接停止。没有结束引号等。

该值为 address_city=COACALCO DE BERRIOZÁBAL。所以它停在重音字符处。

字符编码为 UTF-8。我验证了编码:

echo mb_internal_encoding();

它报告 UTF-8。 我还确保 mysqli 字符集是 UTF-8:

mysqli_set_charset($connect, "utf8");

就像我报告的那样,没有来自数据库或通过 error_handler 的错误? IPN 对象使用非重音值很好地序列化。我在尝试查看记录时发现了这个问题,并且 unserialize() 报告了一个问题。

【问题讨论】:

大概mb_check_encoding() 上的 PayPal 响应本身(我假设来自 cURL)返回 true?您还没有遇到应用程序全是 UTF-8,数据库是 UTF-8,但 PayPal 的响应不是这样的情况? 嗯。从来自 PayPal 的 POST 响应中强制使用 UTF-8 的最佳方法是什么? 你是如何插入数据的?您是否正确转义(使用准备好的语句)?我个人没有让serialize 在字符串中的任何内容上失败......不管它是 utf8、iso 还是二进制。 由于某种原因,php 没有正确读取您的多字节字符串。它声明长度为23,但该长度应为24 s:24:"COACALCO DE BERRIOZÁBAL" 无论哪个脚本负责序列化,编码都不是UTF8。 另外,这不会发生在数据库插入上,你只会得到一个奇怪的字符,比如 � 等,这发生在serialize() 【参考方案1】:

这听起来像是 MySQL 的 utf8/utf8mb4 中的“截断”问题。见Trouble with UTF-8 characters; what I see is not what I stored中的“截断”

Á 可能不是以 utf8(十六进制 C381)编码,而是以 latin1(十六进制 C1)编码。

A 计划:让客户使用 utf8 而不是 latin1。

B 计划:通过说来声明客户端正在使用 latin1

mysqli_set_charset($connect, "latin1");

【讨论】:

嗯..这很有趣。我查看了 DB 表,排序规则是 latin1_swedish_ci.. 很奇怪。您认为将其设置为 utf8_general_ci 会解决此问题吗?我正在通过 mysqli_set_charset($connect, "utf8"); 在代码中设置字符集 @hanji - 该命令在 client 中宣布编码。它必须与客户所拥有的相匹配。该表不需要匹配它;转换将在 INSERTSELECT 期间即时完成。 @hanji mysqli_set_charsetconnector 表本身 should also use a utf8 collation(例如 utf8_general_ci)上设置字符集 - 是的。注意MySQL 默认为瑞典语,因为 Mony Widenius 是芬兰人 ... errr - 是的 :)

以上是关于PHP serialize() 带有重音字符导致不完整的序列化的主要内容,如果未能解决你的问题,请参考以下文章

MS SQL Server 中 JSON 函数路径中的重音字符导致错误

带有重音字符的 Java 属性文件

Outlook 无法在我的 mailto 字符串中接受法语重音字符?

如何将重音字符与 PHP preg 匹配?

PHP 过滤器用无重音符号替换重音字符

PHP字符逃逸导致的对象注入