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 中宣布编码。它必须与客户所拥有的相匹配。该表不需要匹配它;转换将在INSERT
和 SELECT
期间即时完成。
@hanji mysqli_set_charset
在 connector 表本身 should also use a utf8 collation(例如 utf8_general_ci
)上设置字符集 - 是的。注意MySQL 默认为瑞典语,因为 Mony Widenius 是芬兰人 ... errr - 是的 :)以上是关于PHP serialize() 带有重音字符导致不完整的序列化的主要内容,如果未能解决你的问题,请参考以下文章
MS SQL Server 中 JSON 函数路径中的重音字符导致错误