Вопрос по php, json – Json_encode PHP не экранирует все управляющие символы JSON

26

Существуют ли причины, по которым функция json_encode в PHP не скрывает всеJSON управляющие символы в строке?

Например, давайте возьмем строку, которая занимает две строки и содержит управляющие символы (\ r \ n & quot; / \):

<code><?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: \\."
?>
</code>

Обратите внимание, что символы возврата каретки и перевода строки не экранированы. Зачем?

Я использую jQuery в качестве своей библиотеки JS, и функция $ .getJSON () будет работать, когда вы полностью, 100% доверяете входящим данным. В противном случае я использую библиотеку JSON.org json2.js, как и все остальные. Но если вы попытаетесь разобрать эту закодированную строку, она выдаст ошибку:

<code><script type="text/javascript">

JSON.parse(<?php echo $s ?>);  // Will throw SyntaxError 

</script>
</code>

И вы не можете получить данные! Если вы удалите или уберете \ r \ n & quot; и \ в этой строке JSON.parse () не выдаст ошибку.

Есть ли какая-либо существующая, хорошая функция PHP для экранирования управляющих символов. Простое str_replace с поиском и заменой массивов не будет работать.

Вместо & lt;? Php echo $ s? & Gt; научитесь использовать & lt;? = $ s? & gt; :) Просто мой совет. Thinker
@mewm Вы правы, и я сделал свой комментарий несколько лет назад, когда все было иначе. Я уже некоторое время использую короткие эхо-теги. Удаленные комментарии, чтобы избежать плохой информации для будущих посетителей. BadHorsie
@Thinker Кроме того, если на сервере отключены короткие открытые теги, ваш код не только ломается, но и выводится в браузер. charliefortune
@BadHorsie Проверьте себя, прежде чем сделать неправильный комментарий. & lt;? = не является плохой практикой и всегда активируется даже при отключенных коротких тегах начиная с PHP 5.4. Также, пожалуйста, прочитайтеphp-fig.org/psr/psr-1 о стандартах кодирования Thinker
Спасибо за совет, но этот синтаксис эхо ярлыка работает только тогда, когда включен short_open_tag, и я никогда не использовал открывающие теги, потому что я предпочитаю & lt;? Php, чем & lt; ". Gustav

Ваш Ответ

13   ответов
4

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

Надеюсь, это поможет...

0

за исключением новой строки в textarea.value. JSON_encode на PHP & gt; 5.2 сделает это так, как вы ожидали.

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

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

$s=preg_replace('/\r */','',$s);
echo preg_replace('/ *\n */','&#13;',$s);
-1

Write data into input like and read it in JS:

<input type="hidden" value="<?= htmlencode(json_encode($data)) ?>"/>

Use addslashes

var json = '<?= addslashes(json_encode($data)) ?>';
0

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

Исходный скрипт (ajax) возьмет массив и json_encode его. Пример:

$return['value'] = 'test';
$return['value2'] = 'derp';

echo json_encode($return);

Мой javascript сделает AJAX-вызов и получит эхо-запрос "json_encode ($ return)" в качестве входных данных и в сценарии я буду использовать следующее:

myVar = jQuery.parseJSON(msg.replace(/&quot;/ig,'"'));

с "msg" возвращаемое значение. Итак, для вас что-то вроде ...

var msg = '<?php echo $s ?>';
myVar = jQuery.parseJSON(msg.replace(/&quot;/ig,'"'));

... может работать на тебя.

27
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;
  }

которая экранирует обратную косую черту (должна быть первой в массивах) и должна иметь дело с фидами и возвратными пространствами (я не думаю, что\f а также\b поддерживаются в PHP).

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
1

<script type="text/javascript">

JSON.parse("<?php echo $s ?>");  // Will throw SyntaxError 

</script>

(обратите внимание на разные цитаты)

Error: User Rate Limit Exceeded Gustav
12

JSON.parse, конечно, ожидает строку:

<script type="text/javascript">

JSON.parse(<?php echo json_encode($s) ?>);

</script>
Error: User Rate Limit Exceeded Gustav
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Gustav
Error: User Rate Limit Exceeded
0

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

<script type="text/javascript">
    JSON.parse(<?php echo $s ?>);
</script>
Error: User Rate Limit Exceeded Gustav
3
$search = array("\n", "\r", "\u", "\t", "\f", "\b", "/", '"');
$replace = array("\\n", "\\r",, "\\u", "\\t", "\\f", "\\b", "\/", "\"");
$encoded_string = str_replace($search, $replace, $json);

Error: User Rate Limit Exceeded
0

как работает var_export, поэтому я буду обновляться, если у меня возникнут проблемы, но мне кажется, что это работает:

<script>
    window.things = JSON.parse(<?php var_export(json_encode($s)); ?>);
</script>
-1

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

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

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

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

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

2

Json_encode PHP выполняет правильную кодировку, но переосмысление этого внутри java-скрипта может вызвать проблемы. подобно

1) исходная строка - [строка сnnn перевод строки в нем] (где nnn - фактический символ перевода строки)

2) json_encode преобразует это в   [строка с & quot; \\ n & quot; перевод строки в нем] (управляющий символ преобразован в «\\ n» - литерал »\ n»;

3) Однако, если вы напечатаете это снова в литеральной строке, используя php echo, то & quot; \\ n & quot; интерпретируется как & quot; \ n & quot; и это вызывает душевную боль. Потому что JSON.parse будет понимать буквально напечатанный & quot; \ n & quot; как новая строка - управляющий символ (nnn)

так что обойти это: -

A) Сначала закодируйте объект json в php с помощью json_enocde и получите строку. Затем запустите его через фильтр, который делает его безопасным для использования внутри html и java-скриптов.

B) использовать строку JSON из PHP в качестве & quot; литерала & quot; и поместите его в одинарные кавычки вместо двойных.

<?php
       function form_safe_json($json) {
            $json = empty($json) ? '[]' : $json ;
            $search = array('\\',"\n","\r","\f","\t","\b","'") ;
            $replace = array('\\\\',"\\n", "\\r","\\f","\\t","\\b", "&#039");
            $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 в двойные кавычки приведет к сбою синтаксического анализатора в маркерах атрибута (что-то вроде {& quot; id & quot;: & quot; value & quot;}). Никакого другого экранирования не требуется, если вы поставили строку как & quot; literal & quot; и пусть анализатор JSON сделает всю работу.

-1
$val = array("\n","\r");

$string = str_replace($val, "", $string);

from json string   в PHP

Похожие вопросы