Based on my understanding of this subject, I’ve come up with the following function for translating a string from PHP to JSON, strictly conforming to the RFC4627.
function json_string($string)
{
//http://www.ietf.org/rfc/rfc4627.txt
$replacements = array(
'@[\\\\"]@' => '\\\\$0', //escape backslashes and double quotes
'@\n@' => '\n', //convert new lines to their alias for readability
'@\r@' => '\r', //convert carriage returns to their alias for readability
'@\t@' => '\t', //convert tabs to their alias for readability
'@[[:cntrl:]]@e' => 'sprintf("\\u%04x", ord("$0"))', //escape control characters
'@</([A-Z])@i' => '<\/$1', //escape slashes that could fool browsers
);
$result = preg_replace(array_keys($replacements), array_values($replacements), $string);
$result = '"' . $result . '"';
return $result;
}
A simple test like this
$test = array(
'a null: '.chr(0).'; a new line: '.chr(10).'; a carriage return: '.chr(13).';',
'a js regex: /(["\'])\w+\1/',
'a script element: <script type="test/javascript" src="http://example.com/all.js"></script>',
'a japanese word: みず'
);
echo '<pre>';
echo 'Zend_Json_Encoder::_encodeString: ', htmlspecialchars(print_r(array_map('_encodeString', $test), true));
echo 'json_string: ', htmlspecialchars(print_r(array_map('json_string', $test), true));
echo '</pre>';
yields (in comparison to the _encodeString method of the Zend_Json_Encoder class of Zend Framework)
Zend_Json_Encoder::_encodeString: Array
(
[0] => "a null: ; a new line: \n; a carriage return: \r;"
[1] => "a js regex: \/([\"'])\\w+\\1\/"
[2] => "a script element: <script type=\"test\/javascript\" src=\"http:\/\/example.com\/all.js\"><\/script>"
[3] => "a japanese word: \u307f\u305a"
)
json_string: Array
(
[0] => "a null: \u0000; a new line: \n; a carriage return: \r;"
[1] => "a js regex: /([\"'])\\w+\\1/"
[2] => "a script element: <script type=\"test/javascript\" src=\"http://example.com/all.js\"><\/script>"
[3] => "a japanese word: みず"
)