PHP 的 json_encode 不会转义所有 JSON 控制字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1048487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP's json_encode does not escape all JSON control characters
提问by Gustav
Is there any reasons why PHP's json_encode function does not escape all JSONcontrol characters in a string?
PHP 的 json_encode 函数没有转义字符串中的所有JSON控制字符有什么原因吗?
For example let's take a string which spans two rows and has control characters (\r \n " / \) in it:
例如,让我们采用一个跨越两行并包含控制字符 (\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: \."
?>
Note that carriage return and newline chars are unescaped. Why?
请注意,回车符和换行符是未转义的。为什么?
I'm using jQuery as my JS library and it's $.getJSON() function will do fine when you fully, 100% trust incoming data. Otherwise I use JSON.org's library json2.js like everybody else. But if you try to parse that encoded string it throws an error:
我使用 jQuery 作为我的 JS 库,当您完全 100% 信任传入数据时,它的 $.getJSON() 函数会很好。否则我像其他人一样使用 JSON.org 的库 json2.js。但是,如果您尝试解析该编码字符串,则会引发错误:
<script type="text/javascript">
JSON.parse(<?php echo $s ?>); // Will throw SyntaxError
</script>
And you can't get the data! If you remove or escape \r \n " and \ in that string then JSON.parse() will not throw error.
而且你拿不到数据!如果您在该字符串中删除或转义 \r \n " 和 \,则 JSON.parse() 不会抛出错误。
Is there any existing, good PHP function for escaping control characters. Simple str_replace with search and replace arrays will not work.
是否有任何现有的、好的 PHP 函数来转义控制字符。带有搜索和替换数组的简单 str_replace 将不起作用。
采纳答案by Greg
D'oh - you need to double-encode: JSON.parse is expecting a string of course:
D'oh - 你需要双重编码:JSON.parse 当然需要一个字符串:
<script type="text/javascript">
JSON.parse(<?php echo json_encode($s) ?>);
</script>
回答by Peter Whitefield
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;
}
I'm using the above function which escapes a backslash (must be first in the arrays) and should deal with formfeeds and backspaces (I don't think \fand \bare supported in PHP).
我正在使用上面的函数来转义反斜杠(必须是数组中的第一个)并且应该处理换页符和退格符(我不认为\f并且\b在 PHP 中受支持)。
回答by sp2hari
I still haven't figured out any solution without str_replace..
我仍然没有想出任何解决方案没有str_replace..
Try this code.
试试这个代码。
$json_encoded_string = json_encode(...);
$json_encoded_string = str_replace("\r", '\r', $json_encoded_string);
$json_encoded_string = str_replace("\n", '\n', $json_encoded_string);
Hope that helps...
希望有帮助...
回答by JunioR
$search = array("\n", "\r", "\u", "\t", "\f", "\b", "/", '"');
$replace = array("\n", "\r", "\u", "\t", "\f", "\b", "\/", "\"");
$encoded_string = str_replace($search, $replace, $json);
This is the correct way
这是正确的方法
回答by rjha94
Converting to and fro from PHP should not be an issue. PHP's json_encode does proper encoding but reinterpreting that inside java script can cause issues. Like
从 PHP 来回转换应该不是问题。PHP 的 json_encode 进行了正确的编码,但在 java 脚本中重新解释它可能会导致问题。喜欢
1) original string - [string with nnnnewline in it] (where nnn is actual newline character)
1) 原始字符串 - [包含nnn换行符的字符串](其中 nnn 是实际的换行符)
2) json_encode will convert this to [string with "\\n" newline in it] (control character converted to "\\n" - Literal "\n"
2) json_encode 将把它转换为 [string with "\\n" newline in it] (控制字符转换为 "\\n" - 文字 "\n"
3) However when you print this again in a literal string using php echo then "\\n" is interpreted as "\n" and that causes heartache. Because JSON.parse will understand a literal printed "\n" as newline - a control character (nnn)
3) 但是,当您使用 php echo 在文字字符串中再次打印此内容时,“\\n”将被解释为“\n”,这会导致心痛。因为 JSON.parse 会将打印的 "\n" 理解为换行符 - 控制字符 (nnn)
so to work around this: -
所以要解决这个问题: -
A) First encode the json object in php using json_enocde and get a string. Then run it through a filter that makes it safe to be used inside html and java script.
A) 首先使用 json_enocde 在 php 中对 json 对象进行编码并得到一个字符串。然后通过过滤器运行它,使其可以安全地在 html 和 java 脚本中使用。
B) use the JSON string coming from PHP as a "literal" and put it inside single quotes instead of double quotes.
B) 使用来自 PHP 的 JSON 字符串作为“文字”并将其放在单引号内而不是双引号内。
<?php
function form_safe_json($json) {
$json = empty($json) ? '[]' : $json ;
$search = array('\',"\n","\r","\f","\t","\b","'") ;
$replace = array('\\',"\n", "\r","\f","\t","\b", "'");
$json = str_replace($search,$replace,$json);
return $json;
}
$title = "Tiger's /new \found \/freedom " ;
$description = <<<END
Tiger was caged
in a Zoo
And now he is in jungle
with freedom
END;
$book = new \stdClass ;
$book->title = $title ;
$book->description = $description ;
$strBook = json_encode($book);
$strBook = form_safe_json($strBook);
?>
<!DOCTYPE html>
<html>
<head>
<title> title</title>
<meta charset="utf-8">
<script type="text/javascript" src="/3p/jquery/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var strBookObj = '<?php echo $strBook; ?>' ;
try{
bookObj = JSON.parse(strBookObj) ;
console.log(bookObj.title);
console.log(bookObj.description);
$("#title").html(bookObj.title);
$("#description").html(bookObj.description);
} catch(ex) {
console.log("Error parsing book object json");
}
});
</script>
</head>
<body>
<h2> Json parsing test page </h2>
<div id="title"> </div>
<div id="description"> </div>
</body>
</html>
Put the string inside single quote in java script. Putting JSON string inside double quotes would cause the parser to fail at attribute markers (something like { "id" : "value" } ). No other escaping should be required if you put the string as "literal" and let JSON parser do the work.
将字符串放在java脚本中的单引号内。将 JSON 字符串放在双引号内会导致解析器在属性标记处失败(类似于 { "id" : "value" } )。如果您将字符串作为“文字”并让 JSON 解析器完成工作,则不需要其他转义。
回答by nothrow
Maybe I'm blind, but in your example they ARE escaped. What about
也许我是盲人,但在你的例子中,他们逃脱了。关于什么
<script type="text/javascript">
JSON.parse("<?php echo $s ?>"); // Will throw SyntaxError
</script>
(note different quotes)
(注意不同的引号)
回答by Stefan Gehrig
回答by B.F.
Control characters have no special meaning in HTML except for new line in textarea.value . JSON_encode on PHP > 5.2 will do it like you expected.
除了 textarea.value 中的换行符之外,控制字符在 HTML 中没有特殊含义。PHP > 5.2 上的 JSON_encode 会像你预期的那样做。
If you just want to show text you don't need to go after JSON. JSON is for arrays and objects in JavaScript (and indexed and associative array for PHP).
如果您只想显示文本,则无需追求 JSON。JSON 用于 JavaScript 中的数组和对象(以及用于 PHP 的索引和关联数组)。
If you need a line feed for the texarea-tag:
如果您需要为 texarea-tag 换行:
$s=preg_replace('/\r */','',$s);
echo preg_replace('/ *\n */',' ',$s);
回答by colllin
I don't fully understand how var_export works, so I will update if I run into trouble, but this seems to be working for me:
我不完全理解 var_export 是如何工作的,所以如果遇到麻烦我会更新,但这似乎对我有用:
<script>
window.things = JSON.parse(<?php var_export(json_encode($s)); ?>);
</script>
回答by Anthony Tomasino
This is what I use personally and it's never not worked. Had similar problems originally.
这是我个人使用的,它从来没有不起作用。原来也有类似的问题。
Source script (ajax) will take an array and json_encode it. Example:
源脚本 (ajax) 将采用一个数组并对其进行 json_encode。例子:
$return['value'] = 'test';
$return['value2'] = 'derp';
echo json_encode($return);
My javascript will make an AJAX call and get the echoed "json_encode($return)" as its input, and in the script I'll use the following:
我的 javascript 将进行 AJAX 调用并获取回显的“json_encode($return)”作为其输入,并且在脚本中我将使用以下内容:
myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
with "msg" being the returned value. So, for you, something like...
“msg”是返回值。所以,对你来说,像...
var msg = '<?php echo $s ?>';
myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
...might work for you.
...可能对你有用。

