【发布时间】:2025-12-30 15:55:06
【问题描述】:
在我的公司中,我们有一个网络服务 zu 将数据从非常旧的项目发送到相当新的项目。旧项目运行 PHP4.4,它本身没有 json_encode 方法。所以我们改用 PEAR 类 Service_JSON。 http://www.abeautifulsite.net/using-json-encode-and-json-decode-in-php4/
今天,我发现这个类不能处理多字节字符,因为它广泛使用ord() 来从字符串中获取字符代码并替换字符。没有 mb_ord() 实现,即使在较新的 PHP 版本中也是如此。它还使用 $string{$index} 来访问索引处的字符,我不完全确定这是否支持多字节字符。
//Excerpt from encode() method
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
$ascii = '';
$strlen_var = $this->strlen8($var);
/*
* Iterate over every character in the string,
* escaping with a slash or encoding to UTF-8 where necessary
*/
for ($c = 0; $c < $strlen_var; ++$c) {
$ord_var_c = ord($var{$c});
//Here comes a switch which replaces chars according o their hex code and writes them to $ascii
我们打电话
$Service_Json = new Service_JSON();
$data = $Service_Json->encode('Marktplatz, Hauptstraße, Endingen');
echo $data; //prints "Marktplatz, Hauptstra\u00dfe, Endinge". The n is missing
我们通过设置另一个接收序列化数组并返回 json_encoded 字符串的 web 服务解决了这个问题。该服务在现代机器上运行,因此它使用 PHP5.4。但是这个“解决方案很尴尬,我应该寻找一个更好的解决方案。有人有想法吗?
问题描述
德语变音符号被正确替换。但是由于 ord 返回了错误的字符,因此字符串在最后被切断。 . mb_strlen() 不会改变任何东西,在这种情况下,它给出的长度与 strlen 相同。
输入字符串为“Marktplatz, Hauptstraße, Endingen”,末尾的n被截断。 ß 被正确编码为 \u00df。对于每个元音变音,它最后会多切一个字符。
这也可能是我们旧的数据库编码的原因,但是替换本身可以正常工作,所以我猜是 ord() 方法。
【问题讨论】:
-
我刚刚下载了
Services_JSON模块并使用您的输入数据对其进行了测试。工作得很好。我得到了相同的编码\u00df,但我没有错过最后的n。如果你这样做strlen($your_input_string),你会得到什么? -
它返回 33 的长度。如果正确,我们的数据库编码有问题。 mb_check_encoding() 返回 false,而 mb_detect_encoding() 返回 utf-8。
-
如果长度为 33,则表示
ß输入为0xDF的单字节字符,而不是0xC39F的 UTF-8 表示形式。我想知道这可能是问题吗? -
问题出现在每个元音变音、äüö 和 ß PHP > 5.2 中的 json_encode 和 Service_JSON 中的 encode() 之间一定有区别,因为在 json_encode() 中它可以工作。你知道我怎样才能检测到正确的编码吗? my_detect_encoding 不起作用 - 它返回 UTF-8 但数据库似乎使用了另一种编码。我猜UTF-8是脚本文件编码? PhpMyAdmin 也显示损坏的变音符号,但是当我在浏览器中输出字符串时,一切都很好。
-
目前我建议通过十六进制转储进行手动检查。最简单的方法是
unpack('H*', $yourstr)。如果您将ß视为0xC39F,那么数据库将为您提供正确的UTF-8(根据我对库的有限经验)应该与Services_JSON 一起使用。如果它为您提供0xDF的单字节表示,那么我建议您首先通过mb_convert_encoding($yourstr, 'UTF-8', 'ASCII')传递它。如果做不到这一点,我们可以把它带到 * 聊天中,希望能解决一些问题。
标签: json encoding php4 multibyte