Json_encode PHP не экранирует все управляющие символы JSON - PullRequest
26 голосов
/ 26 июня 2009

Есть ли причины, по которым функция 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 с массивами поиска и замены не будет работать.

Ответы [ 13 ]

0 голосов
/ 13 февраля 2014

Управляющие символы не имеют специального значения в HTML, за исключением новой строки в textarea.value. JSON_encode на PHP> 5.2 сделает это так, как вы ожидали.

Если вы просто хотите показать текст, вам не нужно идти после JSON. JSON предназначен для массивов и объектов в JavaScript (и индексированного и ассоциативного массива для PHP).

Если вам нужен перевод строки для тега texarea:

$s=preg_replace('/\r */','',$s);
echo preg_replace('/ *\n */','&#13;',$s);
0 голосов
/ 05 октября 2013

При использовании любой формы Ajax в Интернете, похоже, отсутствует подробная документация для формата ответов, полученных от сервера CGI. Некоторые примечания здесь и записи на stackoverflow.com указывают на то, что переводы строки в возвращаемом тексте или данных json должны быть экранированы, чтобы предотвратить бесконечные циклы (зависания) при преобразовании JSON (возможно, создаваемые путем генерирования необработанного исключения), независимо от того, выполняется ли это автоматически с помощью jQuery или вручную с помощью Система Javascript или библиотека JSON-разбор вызовов.

В каждом случае, когда программисты публикуют эту проблему, представлены неадекватные решения (чаще всего замена \ n на \\ n на стороне отправителя), и вопрос упускается. Их неадекватность выявляется при передаче строковых значений, которые случайно встраивают управляющие управляющие последовательности, такие как пути Windows. Примером является «C: \ Chris \ Roberts.php», который содержит управляющие символы ^ c и ^ r, что может вызвать преобразование JSON строки {"file": "C: \ Chris \ Roberts.php"} в цикл навсегда. Одним из способов получения таких значений является намеренная попытка передачи предупреждений и сообщений об ошибках PHP от сервера клиенту, разумная идея.

По определению, Ajax использует HTTP-соединения за кулисами. Такие соединения передают данные, используя GET и POST, оба из которых требуют кодирования отправленных данных, чтобы избежать неправильного синтаксиса, включая управляющие символы.

Это дает достаточно подсказки для построения того, что кажется решением (требуется дополнительное тестирование): использовать rawurlencode на стороне PHP (отправляющей) для кодирования данных и unescape на стороне Javascript (принимающей) для декодирования данные. В некоторых случаях вы будете применять их ко всем текстовым строкам, в других случаях вы будете применять их только к значениям внутри JSON.

Если эта идея окажется верной, можно построить простые примеры, чтобы помочь программистам на всех уровнях решить эту проблему раз и навсегда.

0 голосов
/ 26 июня 2009

Просто дополнение к ответу Грега : вывод json_encode() уже содержится в двойных кавычках ("), поэтому нет необходимости снова заключать их в кавычки:

<script type="text/javascript">
    JSON.parse(<?php echo $s ?>);
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...