PHP 的json_encode不会转义所有 JSON 控制字符

2022-08-30 16:02:56

PHP 的 json_encode 函数不转义字符串中的所有 JSON 控件字符,这有什么原因吗?

例如,让我们取一个跨越两行的字符串,其中有控制字符(\r \n“ / \):

<?php
$s = <<<END
First row.
Second row w/ "double quotes" and backslash: \.
END;

$s = json_encode($s);
echo $s;
// Will output: "First row.\r\nSecond row w\/ \"double quotes\" and backslash: \\."
?>

请注意,回车符和换行符是未转义的。为什么?

我使用jQuery作为我的JS库,它的$.getJSON()函数在你完全100%信任传入数据时会做得很好。否则,我像其他人一样使用JSON.org的库json2.js。但是,如果您尝试解析该编码字符串,则会引发错误:

<script type="text/javascript">

JSON.parse(<?php echo $s ?>);  // Will throw SyntaxError 

</script>

而且你无法获得数据!如果删除或转义该字符串中的 \r \n “ 和 \,则 JSON.parse() 不会引发错误。

是否有任何现有的,好的PHP函数用于转义控制字符。使用搜索和替换数组的简单str_replace将不起作用。


答案 1
function escapeJsonString($value) {
    # list from www.json.org: (\b backspace, \f formfeed)    
    $escapers =     array("\\",     "/",   "\"",  "\n",  "\r",  "\t", "\x08", "\x0c");
    $replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t",  "\\f",  "\\b");
    $result = str_replace($escapers, $replacements, $value);
    return $result;
  }

我正在使用上面的函数,它转义了反斜杠(必须在数组中的第一个),并且应该处理表单馈送和退格(我不认为PHP中支持)。\f\b


答案 2

D'oh - 你需要双重编码:JSON.parse当然需要一个字符串:

<script type="text/javascript">

JSON.parse(<?php echo json_encode($s) ?>);

</script>

推荐