有没有办法防止json_encode()
对包含无效(非UTF-8)字符的字符串返回null
?
在复杂的系统中调试可能会很麻烦。实际上看到无效字符或者至少将其忽略会更合适。目前,json_encode()
将静默地删除整个字符串。
示例(UTF-8格式):
$string =
array(utf8_decode("Düsseldorf"), // Deliberately produce broken string
"Washington",
"Nairobi");
print_r(json_encode($string));
结果
[null,"Washington","Nairobi"]
预期结果:
["D�sseldorf","Washington","Nairobi"]
Note:我不是希望在json_encode()中使用损坏的字符串。我正在寻找更容易诊断编码错误的方法。null
字符串对此没有帮助。
8条答案
按热度按时间q35jwt9p1#
php确实会尝试弹出一个错误,但是只有当你关闭display_errors的时候.这很奇怪,因为
display_errors
的设置只是用来控制错误是否被打印到标准输出,而不是控制错误是否被触发.我想强调的是,当你打开display_errors
的时候,即使你可能会看到各种各样的php错误,php并不只是隐藏这个错误,* 它甚至不会触发它 *。这意味着它不会出现在任何错误日志中,也不会调用任何自定义error_handlers。错误就是永远不会发生。下面的代码演示了这一点:
这种奇怪而不幸的行为与这个bug https://bugs.php.net/bug.php?id=47494和其他一些bug有关,而且看起来永远不会被修复。
在将字符串传递给json_encode之前对其进行清理可能是一个可行的解决方案。
http://php.net/manual/en/function.iconv.php
手册上说
//IGNORE
会自动丢弃目标字符集中的非法字符。因此,通过首先删除有问题的字符,理论上json_encode()不应该得到任何它会窒息和失败的东西。我还没有验证带有
//IGNORE
标志的iconv的输出与json_encodes关于什么是有效的utf8字符的概念完全兼容,所以买家要小心...因为可能有边缘情况下它仍然失败。唉,我讨厌字符集问题。在php 7.2+中,似乎有一些新的
json_encode
标志:JSON_INVALID_UTF8_IGNORE
和JSON_INVALID_UTF8_SUBSTITUTE
虽然文档还不多,但是现在,这个测试应该可以帮助您理解预期的行为:https://github.com/php/php-src/blob/master/ext/json/tests/json_encode_invalid_utf8.phpt
在php7.3+中,有一个新的标记
JSON_THROW_ON_ERROR
,参见http://php.net/manual/en/class.jsonexception.phpsq1bmfud2#
此函数将删除字符串中所有无效的UTF8字符:
我在将Excel文档转换为json后使用它,因为Excel文档不能保证是UTF8格式。
我不认为有一种特别明智的方法可以将无效字符转换为可见但有效的字符。你可以通过改变上面的正则表达式来用U+FFFD替换无效字符,这是unicode replacement character,但这并没有提供比丢弃无效字符更好的用户体验。
qnakjoqk3#
这就解决了问题,我不明白为什么php的人没有通过修复
json_encode()
来使生活变得更容易。无论如何,使用上面的方法允许json_encode()创建对象,即使数据包含特殊字符(例如瑞典字母)。
然后,您可以在JavaScript中使用结果,而无需将数据解码回其原始编码(使用
escape()
、unescape()
、encodeURIComponent()
、decodeURIComponent()
);我在php(smarty)中是这样使用它的:
然后我将结果发送到javascript,并在我的文档中添加
innerHTML
就绪模板(html peace)。简单地说,上面的行应该以某种方式在
json_encode()
中实现,以便允许它与任何编码一起工作。nxowjjhe4#
你需要知道你正在处理的所有字符串的编码,否则你将进入一个痛苦的世界。
UTF-8是一种易于使用的编码方式。另外,JSON被定义为使用UTF-8(http://www.json.org/JSONRequest.html)。那么为什么不使用它呢?
简短回答:避免json_encode()丢弃字符串的方法是确保它们是有效的UTF-8。
h6my8fg25#
除了使用iconv函数,您可以直接使用json_encode和JSON_UNESCAPED_UNICODE选项(〉= PHP5.4.0)
确保你在php文件的头中输入了"charset = utf-8":
header('内容类型:应用程序/json;字符集= utf-8');
mwngjboj6#
要获得有关JSON失败的信息性错误通知,我们使用此帮助器:
flseospp7#
WordPress有一个JSON的 Package 器来防止这个问题,你可以看看wp_json_encode的源代码,但它归结为:
对于递归数组、对象或可能包含非标量的数据,请检查_wp_json_sanity_check以获取更详细的代码。
unhi4e5o8#
从字符串中删除不可打印的字符
通过https://alvinalexander.com/php/how-to-remove-non-printable-characters-in-string-regex/求解