PHP’s json_encode does not escape all JSON control characters

jsonphp

Is there any reasons why PHP's json_encode function does not escape all JSON control characters in a string?

For example let's take a string which spans two rows and has control characters (\r \n " / \) in it:

<?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:

<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.

Is there any existing, good PHP function for escaping control characters. Simple str_replace with search and replace arrays will not work.

Best Solution

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).