当前位置: 首页 > 面试题库 >

如何防止json_encode()删除带有无效字符的字符串

暴阳州
2023-03-14
问题内容

有没有办法json_encode()避免返回null包含无效(非UTF-8)字符的字符串?

在复杂的系统中调试可能会很麻烦。实际看到无效字符,或者至少将其省略会更合适。就目前而言,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"]

注意 :我
希望使破碎的字符串在json_encode()中起作用。我正在寻找简化诊断编码错误的方法。一个null字符串是不是该有所帮助。


问题答案:

php确实会尝试产生错误,但前提是 您必须关闭display_errors
。这很奇怪,因为该display_errors设置仅用于控制是否将错误打印到标准输出,而不是控制是否触发错误。我想强调一点display_errors,即使您继续看到其他各种php错误,php也不只是隐藏此错误,
它甚至不会触发它 。这意味着它将不会显示在任何错误日志中,也不会调用任何自定义的error_handlers。该错误永远不会发生。

这是一些演示此代码的代码:

error_reporting(-1);//report all errors
$invalid_utf8_char = chr(193);

ini_set('display_errors', 1);//display errors to standard output
var_dump(json_encode($invalid_utf8_char));
var_dump(error_get_last());//nothing

ini_set('display_errors', 0);//do not display errors to standard output
var_dump(json_encode($invalid_utf8_char));
var_dump(error_get_last());// json_encode(): Invalid UTF-8 sequence in argument

这种怪异和不幸的行为与该错误https://bugs.php.net/bug.php?id=47494和其他一些错误有关,并且看起来永远不会得到修复。

解决方法:

在将字符串传递给json_encode之前对其进行清理可能是一个可行的解决方案。

$stripped_of_invalid_utf8_chars_string = iconv('UTF-8', 'UTF-8//IGNORE', $orig_string);
if ($stripped_of_invalid_utf8_chars_string !== $orig_string) {
    // one or more chars were invalid, and so they were stripped out.
    // if you need to know where in the string the first stripped character was, 
    // then see http://stackoverflow.com/questions/7475437/find-first-character-that-is-different-between-two-strings
}
$json = json_encode($stripped_of_invalid_utf8_chars_string);

http://php.net/manual/zh/function.iconv.php

手册说

//IGNORE 静默丢弃目标字符集中的非法字符。

因此,通过首先删除有问题的字符,理论上json_encode()不应该得到任何会窒息而失败的东西。我尚未验证带//IGNORE标志的iconv的输出与有效utf8字符的json_encodes概念完全兼容,因此请当心……在某些情况下它仍然会失败。恩,我讨厌字符集问题。

在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

并且,在php
7.3+中,有一个新标志JSON_THROW_ON_ERROR。参见http://php.net/manual/en/class.jsonexception.php



 类似资料:
  • 问题内容: 我不知道如何从Java中的字符串中删除无效字符。我正在尝试删除不是数字,字母或()[]的所有字符。我怎样才能做到这一点? 谢谢 问题答案: Javadocs是您的朋友。正则表达式也是您的朋友。 编辑: siad,这仅适用于拉丁字母;您可以据此进行调整。可以用于表示“单词”字符(如果它适用于您的情况),尽管它包括在内。

  • 问题内容: 我在字符串列表的json.Marshal上得到这个: 原因很明显,但是如何在Go中删除/替换这样的字符串?我一直在阅读docst 和包,似乎没有明显/快速的方法。 例如,在Python中,您可以使用一些方法删除无效字符,将其替换为指定字符或严格设置,这会导致无效字符的异常。如何在Go中做等效的事情? 更新:我的意思是得到异常的原因(紧急?)-json.Marshal期望有效的UTF-8

  • 问题内容: 这似乎是骗人的,但请放心,事实并非如此-我在SO和网络的其余部分中搜索了我的问题的答案,并最终一遍又一遍地找到同样不足的“解决方案”。无论如何,这是这样的: 我正在将用户输入从文本区域保存到MySQL数据库(在WordPress环境中,但是我认为这对这个问题无关紧要)。稍后从数据库中检索它,以在站点的后端显示给Admins。当用户提交带有换行符的文本时(即按Enter键),就会出现问题

  • 问题内容: 我有一个字典,想删除所有有空值字符串的键。 做这个的最好方式是什么? 问题答案: Python 2.X Python 2.7-3.X 请注意,您所有的键都有值。只是其中一些值是空字符串。没有值的字典中就没有键。如果它没有价值,就不会在字典中。

  • 我有一个字符串和一个布尔值,如果字符串中有一个*并且布尔值为真,它将忽略*之前的所有内容,只返回*之后的字符。但是如果boolean为false,它将返回*之前的内容,并删除其后的所有内容。 示例:“abc*def”,真 - 布尔值所做的是,如果为真,忽略*之前的所有内容,我不知道如何做到这一点。我想知道的是我是否可以读取字符串,以及*是否从charAT(0)删除到charAT(*)。类似这样的东

  • 问题内容: 仅在句点结束时,如何删除最后一个字符? 问题答案: (参考:PHP.net上的rtrim)