Is there any reasons why PHP's json_encode function does not escape all JSON control 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库,它的$. 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搜索和替换数组将不起作用。
13 个解决方案
#1
12
D'oh - you need to double-encode: JSON.parse is expecting a string of course:
你需要双编码:JSON。解析是期待一个字符串:
<script type="text/javascript">
JSON.parse(<?php echo json_encode($s) ?>);
</script>
#2
26
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 \f
and \b
are supported in PHP).
我正在使用上面的函数,它可以避免反斜杠(必须是数组中的第一个),并且应该处理formfeed和backspace(我不认为\f和\b在PHP中是受支持的)。
#3
4
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...
希望这有助于……
#4
3
$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
这是正确的方法。
#5
2
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 nnn newline 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将把它转换成[字符串],并将其转换为“\\n”换行符。(控制字符转换为“\\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)
然而,当你在一个字串中使用php echo再次打印时,“\\n”被解释为“\n”,这会引起心痛。因为JSON。解析将理解一个文本打印的“\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.
首先,使用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”:“值”})上失败。如果将字符串作为“literal”并让JSON解析器完成工作,则不需要其他的转义。
#6
1
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)
(注意不同的引用)
#7
0
Just an addition to Greg's response: the output of json_encode()
is already contained in double-quotes ("
), so there is no need to surround them with quotes again:
除了Greg的响应之外,json_encode()的输出已经包含在双引号中(“),所以没有必要再用引号包围它们:
<script type="text/javascript">
JSON.parse(<?php echo $s ?>);
</script>
#8
0
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中的新行,控制字符在HTML中没有特殊的含义。价值。JSON_encode在PHP > 5.2上会像您所期望的那样做。
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);
#9
0
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>
#10
0
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.
…可能为你工作。
#11
0
$val = array("\n","\r");
$ val =阵列(“\ n”、“\ r”);
$string = str_replace($val, "", $string);
$string = str_replace($val, ", $string);
it will Remove all the Newline from json string in php
它将在php中删除json字符串中的所有新行。
#12
-1
When using any form of Ajax, detailed documentation for the format of responses received from the CGI server seems to be lacking on the Web. Some Notes here and entries at *.com point out that newlines in returned text or json data must be escaped to prevent infinite loops (hangs) in JSON conversion (possibly created by throwing an uncaught exception), whether done automatically by jQuery or manually using Javascript system or library JSON parsing calls.
当使用任何形式的Ajax时,从CGI服务器收到的响应格式的详细文档似乎在Web上缺乏。这里的一些注释和在*.com上的条目指出,必须转义返回的文本或json数据中的新行,以防止json转换中的无限循环(可能是通过抛出一个未捕获的异常来创建的),无论jQuery是自动执行还是手动使用Javascript系统或库json解析调用。
In each case where programmers post this problem, inadequate solutions are presented (most often replacing \n by \\n on the sending side) and the matter is dropped. Their inadequacy is revealed when passing string values that accidentally embed control escape sequences, such as Windows pathnames. An example is "C:\Chris\Roberts.php", which contains the control characters ^c and ^r, which can cause JSON conversion of the string {"file":"C:\Chris\Roberts.php"} to loop forever. One way of generating such values is deliberately to attempt to pass PHP warning and error messages from server to client, a reasonable idea.
在程序员发布这个问题的每一个例子中,都提出了不充分的解决方案(大多数情况下,在发送方替换\n),并且删除了问题。当传递不小心嵌入控制转义序列(如Windows路径名)的字符串值时,会显示它们的不足。一个例子是“C:\克里斯\罗伯茨。php“,包含了控制字符c和r,这会导致字符串{“文件”的JSON转换:“c:\Chris\Roberts”。php”}永远循环。生成这些值的一种方法是故意尝试将PHP警告和错误消息从服务器传递给客户机,这是一个合理的想法。
By definition, Ajax uses HTTP connections behind the scenes. Such connections pass data using GET and POST, both of which require encoding sent data to avoid incorrect syntax, including control characters.
根据定义,Ajax在幕后使用HTTP连接。这种连接通过GET和POST传递数据,这两种方式都需要编码发送数据以避免不正确的语法,包括控制字符。
This gives enough of a hint to construct what seems to be a solution (it needs more testing): to use rawurlencode on the PHP (sending) side to encode the data, and unescape on the Javascript (receiving) side to decode the data. In some cases, you will apply these to entire text strings, in other cases you will apply them only to values inside JSON.
这提供了足够的提示来构造一个看起来是解决方案(它需要更多的测试):在PHP(发送)端使用rawurlencode对数据进行编码,并在Javascript(接收)方面进行unescape以解码数据。在某些情况下,您将把这些应用到整个文本字符串,在其他情况下,您将只将它们应用到JSON中的值。
If this idea turns out to be correct, simple examples can be constructed to help programmers at all levels solve this problem once and for all.
如果这个想法是正确的,那么可以构造简单的例子来帮助所有级别的程序员一次性解决这个问题。
#13
-1
There are 2 solutions unless AJAX is used:
有两种解决方案,除非使用AJAX:
-
Write data into input like and read it in JS:
将数据写入输入,并将其读入JS:
<input type="hidden" value="<?= htmlencode(json_encode($data)) ?>"/>
-
Use addslashes
使用addslashes
var json = '<?= addslashes(json_encode($data)) ?>';
#1
12
D'oh - you need to double-encode: JSON.parse is expecting a string of course:
你需要双编码:JSON。解析是期待一个字符串:
<script type="text/javascript">
JSON.parse(<?php echo json_encode($s) ?>);
</script>
#2
26
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 \f
and \b
are supported in PHP).
我正在使用上面的函数,它可以避免反斜杠(必须是数组中的第一个),并且应该处理formfeed和backspace(我不认为\f和\b在PHP中是受支持的)。
#3
4
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...
希望这有助于……
#4
3
$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
这是正确的方法。
#5
2
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 nnn newline 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将把它转换成[字符串],并将其转换为“\\n”换行符。(控制字符转换为“\\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)
然而,当你在一个字串中使用php echo再次打印时,“\\n”被解释为“\n”,这会引起心痛。因为JSON。解析将理解一个文本打印的“\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.
首先,使用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”:“值”})上失败。如果将字符串作为“literal”并让JSON解析器完成工作,则不需要其他的转义。
#6
1
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)
(注意不同的引用)
#7
0
Just an addition to Greg's response: the output of json_encode()
is already contained in double-quotes ("
), so there is no need to surround them with quotes again:
除了Greg的响应之外,json_encode()的输出已经包含在双引号中(“),所以没有必要再用引号包围它们:
<script type="text/javascript">
JSON.parse(<?php echo $s ?>);
</script>
#8
0
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中的新行,控制字符在HTML中没有特殊的含义。价值。JSON_encode在PHP > 5.2上会像您所期望的那样做。
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);
#9
0
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>
#10
0
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.
…可能为你工作。
#11
0
$val = array("\n","\r");
$ val =阵列(“\ n”、“\ r”);
$string = str_replace($val, "", $string);
$string = str_replace($val, ", $string);
it will Remove all the Newline from json string in php
它将在php中删除json字符串中的所有新行。
#12
-1
When using any form of Ajax, detailed documentation for the format of responses received from the CGI server seems to be lacking on the Web. Some Notes here and entries at *.com point out that newlines in returned text or json data must be escaped to prevent infinite loops (hangs) in JSON conversion (possibly created by throwing an uncaught exception), whether done automatically by jQuery or manually using Javascript system or library JSON parsing calls.
当使用任何形式的Ajax时,从CGI服务器收到的响应格式的详细文档似乎在Web上缺乏。这里的一些注释和在*.com上的条目指出,必须转义返回的文本或json数据中的新行,以防止json转换中的无限循环(可能是通过抛出一个未捕获的异常来创建的),无论jQuery是自动执行还是手动使用Javascript系统或库json解析调用。
In each case where programmers post this problem, inadequate solutions are presented (most often replacing \n by \\n on the sending side) and the matter is dropped. Their inadequacy is revealed when passing string values that accidentally embed control escape sequences, such as Windows pathnames. An example is "C:\Chris\Roberts.php", which contains the control characters ^c and ^r, which can cause JSON conversion of the string {"file":"C:\Chris\Roberts.php"} to loop forever. One way of generating such values is deliberately to attempt to pass PHP warning and error messages from server to client, a reasonable idea.
在程序员发布这个问题的每一个例子中,都提出了不充分的解决方案(大多数情况下,在发送方替换\n),并且删除了问题。当传递不小心嵌入控制转义序列(如Windows路径名)的字符串值时,会显示它们的不足。一个例子是“C:\克里斯\罗伯茨。php“,包含了控制字符c和r,这会导致字符串{“文件”的JSON转换:“c:\Chris\Roberts”。php”}永远循环。生成这些值的一种方法是故意尝试将PHP警告和错误消息从服务器传递给客户机,这是一个合理的想法。
By definition, Ajax uses HTTP connections behind the scenes. Such connections pass data using GET and POST, both of which require encoding sent data to avoid incorrect syntax, including control characters.
根据定义,Ajax在幕后使用HTTP连接。这种连接通过GET和POST传递数据,这两种方式都需要编码发送数据以避免不正确的语法,包括控制字符。
This gives enough of a hint to construct what seems to be a solution (it needs more testing): to use rawurlencode on the PHP (sending) side to encode the data, and unescape on the Javascript (receiving) side to decode the data. In some cases, you will apply these to entire text strings, in other cases you will apply them only to values inside JSON.
这提供了足够的提示来构造一个看起来是解决方案(它需要更多的测试):在PHP(发送)端使用rawurlencode对数据进行编码,并在Javascript(接收)方面进行unescape以解码数据。在某些情况下,您将把这些应用到整个文本字符串,在其他情况下,您将只将它们应用到JSON中的值。
If this idea turns out to be correct, simple examples can be constructed to help programmers at all levels solve this problem once and for all.
如果这个想法是正确的,那么可以构造简单的例子来帮助所有级别的程序员一次性解决这个问题。
#13
-1
There are 2 solutions unless AJAX is used:
有两种解决方案,除非使用AJAX:
-
Write data into input like and read it in JS:
将数据写入输入,并将其读入JS:
<input type="hidden" value="<?= htmlencode(json_encode($data)) ?>"/>
-
Use addslashes
使用addslashes
var json = '<?= addslashes(json_encode($data)) ?>';