Есть ли причины, по которым функция json_encode PHP не удаляет все управляющие символы 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% доверяете входящим данным. В противном случае я использую библиотеку json2.js JSON.org, как и все остальные. Но если вы попытаетесь разобрать эту закодированную строку, она выдает ошибку:
<script type="text/javascript"> JSON.parse(<?php echo $s ?>); // Will throw SyntaxError </script>
И вы не можете получить данные! Если вы удалите или убери \ r \ n "и \ в этой строке, то JSON.parse () не будет вызывать ошибку.
Есть ли какая-либо существующая хорошая функция PHP для экранирования управляющих символов. Простая str_replace с поиском и заменой массивов не будет работать.
D'oh – вам нужно дважды закодировать: JSON.parse ожидает строку, конечно:
<script type="text/javascript"> JSON.parse(<?php echo json_encode($s) ?>); </script>
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; }
Я использую вышеуказанную функцию, которая избегает обратную косую черту (должна быть первой в массивах) и должна иметь дело с formfeeds и backspaces (я не думаю, что \f
и \b
поддерживаются в PHP).
Я до сих пор не понял никакого решения без str_replace
..
Попробуйте этот код.
$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);
Надеюсь, это поможет…
$search = array("\n", "\r", "\u", "\t", "\f", "\b", "/", '"'); $replace = array("\\n", "\\r", "\\u", "\\t", "\\f", "\\b", "\/", "\""); $encoded_string = str_replace($search, $replace, $json);
Это правильный способ
Преобразование между PHP и PHP не должно быть проблемой. PHP json_encode делает правильную кодировку, но переинтерпретирует, что внутри java-скрипта могут возникнуть проблемы. подобно
1) исходная строка – [строка с nnn новой строкой в ней] (где nnn является фактическим символом новой строки)
2) json_encode преобразует это в [string с «\\ n» новой строкой в нем] (управляющий символ преобразован в «\\ n» – Literal "\ n"
3) Однако, когда вы печатаете это снова в литеральной строке, используя php echo, тогда «\\ n» интерпретируется как «\ n» и вызывает сердечную боль. Поскольку JSON.parse поймет буквально напечатанную «\ n» как новую строку – контрольный символ (nnn)
поэтому, чтобы обойти это: –
A) Сначала закодируйте json-объект в php с помощью json_enocde и получите строку. Затем запустите его через фильтр, который делает его безопасным для использования внутри html и java-скрипта.
B) используйте строку JSON, исходящую из PHP, как «литерал» и помещаем ее в одинарные кавычки вместо двойных кавычек.
<?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>
Поместите строку внутри одной кавычки в java-скрипт. Ввод строки JSON внутри двойных кавычек приведет к сбою синтаксического анализатора в марке атрибутов (что-то вроде {"id": "value"}). Никакое другое экранирование не требуется, если вы поместите строку как «литерал», и пусть JSON-парсер выполнит эту работу.
Может быть, я слепой, но в вашем примере они сбежали. Как насчет
<script type="text/javascript"> JSON.parse("<?php echo $s ?>"); // Will throw SyntaxError </script>
(обратите внимание на разные кавычки)
Я не совсем понимаю, как работает var_export, поэтому я буду обновлять, если у меня возникнут проблемы, но это, похоже, работает для меня:
<script> window.things = JSON.parse(<?php var_export(json_encode($s)); ?>); </script>
$ val = array ("\ n", "\ r");
$ string = str_replace ($ val, "", $ string);
он удалит всю строку из строки json в php
Просто добавление к ответу Грега : вывод json_encode()
уже содержится в двойных кавычках ( "
), поэтому нет необходимости снова окружать их кавычками:
<script type="text/javascript"> JSON.parse(<?php echo $s ?>); </script>
Управляющие символы не имеют особого значения в HTML, кроме новой строки в textarea.value. JSON_encode на PHP> 5.2 сделает это так, как вы ожидали.
Если вы просто хотите показать текст, вам не нужно идти после JSON. JSON предназначен для массивов и объектов в JavaScript (и индексированного и ассоциативного массива для PHP).
Если вам нужна строка для техасского тега:
$s=preg_replace('/\r */','',$s); echo preg_replace('/ *\n */',' ',$s);
Это то, что я использую лично, и это никогда не срабатывает. Первоначально имели подобные проблемы.
Исходный скрипт (ajax) будет принимать массив и json_encode. Пример:
$return['value'] = 'test'; $return['value2'] = 'derp'; echo json_encode($return);
Мой javascript сделает вызов AJAX и получит эхо-сообщение «json_encode ($ return)» в качестве его ввода, а в скрипте я буду использовать следующее:
myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
msgstr "возвращаемое значение. Итак, для вас, что-то вроде …
var msg = '<?php echo $s ?>'; myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
… может сработать для вас.
Есть два решения, если не используется AJAX:
Записывайте данные во входные данные и читайте их в JS:
<input type="hidden" value="<?= htmlencode(json_encode($data)) ?>"/>
Использовать addlashes
var json = '<?= addslashes(json_encode($data)) ?>';
При использовании любой формы Ajax в Интернете отсутствует подробная документация для формата ответов, полученных с сервера CGI. Некоторые примечания здесь и записи в stackoverflow.com указывают, что новые строки в возвращаемых текстах или json-данных должны быть экранированы для предотвращения бесконечных циклов (зависаний) в преобразовании JSON (возможно, созданных путем бросания неперехваченного исключения), независимо от того, выполняется ли это вручную с помощью jQuery или вручную Javascript система или библиотека JSON разбор звонков.
В каждом случае, когда программисты публикуют эту проблему, представлены неадекватные решения (чаще всего заменяя \ n на \\ n на отправляющей стороне), и дело отбрасывается. Их неадекватность обнаруживается при передаче строковых значений, которые случайно вставляют управляющие escape-последовательности, такие как имена путей Windows. Пример: «C: \ Chris \ Roberts.php», который содержит управляющие символы ^ c и ^ r, что может привести к преобразованию JSON строки {"file": "C: \ Chris \ Roberts.php"} в цикл навсегда. Одним из способов генерации таких значений является намерение попытаться передать предупреждения PHP и сообщения об ошибках с сервера на клиент, разумную идею.
По определению Ajax использует HTTP-соединения за кулисами. Такие соединения передают данные с использованием GET и POST, оба из которых требуют кодирования отправленных данных, чтобы избежать неправильного синтаксиса, включая управляющие символы.
Это дает достаточно намека на то, что кажется решением (требуется больше тестирования): использовать rawurlencode на стороне PHP (отправки) для кодирования данных и unescape на стороне Javascript (получателя) для декодирования данных. В некоторых случаях вы будете применять их ко всем текстовым строкам, в других случаях вы будете применять их только к значениям внутри JSON.
Если эта идея окажется правильной, можно создать простые примеры, чтобы помочь программистам на всех уровнях решить эту проблему раз и навсегда.