Выход из символов ESC

Я пытаюсь подражать json_encode флаги битовой маски, реализованные в PHP 5.3.0, вот являются строкой, которую я имею:

$s = addslashes('O\'Rei"lly'); // O\'Rei\"lly

Выполнение json_encode($s, JSON_HEX_APOS | JSON_HEX_QUOT) производит следующее:

"O\\\u0027Rei\\\u0022lly"

И я в настоящее время делаю это в версиях PHP, более старых, чем 5.3.0:

str_replace(array('\\"', "\\'"), array('\\u0022', '\\\u0027'), json_encode($s))
or
str_replace(array('\\"', '\\\''), array('\\u0022', '\\\u0027'), json_encode($s))

Который правильно производит тот же результат:

"O\\\u0027Rei\\\u0022lly"

Я испытываю затруднения при понимании, почему я должен заменить одинарные кавычки ('\\\'' или даже "\\'" [окружая кавычки, исключенные]) с '\\\u0027' и не просто '\\u0027'.


Вот код, который я испытываю затруднения при портировании на PHP <5.3:

if (get_magic_quotes_gpc() && version_compare(PHP_VERSION, '6.0.0', '<'))
{
    /* JSON_HEX_APOS and JSON_HEX_QUOT are availiable */
    if (version_compare(PHP_VERSION, '5.3.0', '>=') === true)
    {
        $_GET = json_encode($_GET, JSON_HEX_APOS | JSON_HEX_QUOT);
        $_POST = json_encode($_POST, JSON_HEX_APOS | JSON_HEX_QUOT);
        $_COOKIE = json_encode($_COOKIE, JSON_HEX_APOS | JSON_HEX_QUOT);
        $_REQUEST = json_encode($_REQUEST, JSON_HEX_APOS | JSON_HEX_QUOT);
    }

    /* mimic the behaviour of JSON_HEX_APOS and JSON_HEX_QUOT */
    else if (extension_loaded('json') === true)
    {
        $_GET = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_GET));
        $_POST = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_POST));
        $_COOKIE = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_COOKIE));
        $_REQUEST = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_REQUEST));
    }

    $_GET = json_decode(stripslashes($_GET));
    $_POST = json_decode(stripslashes($_POST));
    $_COOKIE = json_decode(stripslashes($_COOKIE));
    $_REQUEST = json_decode(stripslashes($_REQUEST));
}
9
задан Alix Axel 27 May 2010 в 23:37
поделиться

6 ответов

PHP-строка

'O\'Rei"lly'

- это просто способ PHP получить литеральное значение

O'Rei"lly

в строку, которую можно использовать. Вызов addslashes на этой строке изменяет ее на буквальные 11 символов

O\'Rei\"lly

т.е. strlen(addslashes('O\'Rei "lly')) == 11

Это и есть значение, которое передается в json_escape.

В JSON обратная косая черта является управляющим символом, поэтому ее нужно экранировать, т.е.

\ должен быть \\\

Также одинарные и двойные кавычки могут вызвать проблемы. Поэтому преобразование их в их эквивалент в юникоде является одним из способов избежать проблем. Более поздние версии PHP json_encode изменяют

' на \u0027

и

" на \u0022

Таким образом, применение этих трех правил к

O\'Rei\"lly

дает нам

O\\\u0027Rei\\\u0022lly

Эта строка затем обертывается в двойные кавычки, чтобы сделать ее строкой JSON. Ваши выражения replace включают ведущие прямые косые черты. Случайно или намеренно это означает, что ведущие и последующие двойные кавычки, возвращаемые json_encode, не подвергаются экранированию, чего не должно быть.

Так в ранних версиях PHP

$s = addslashes('O\'Rei"lly');
print json_encode($s);

выводилось

"O\\'Rei\\\"lly"

и мы хотим изменить ' на \u0027 и мы хотим изменить \" на \u0022, потому что \ в \" просто для того, чтобы вписать " в строку, потому что она начинается и заканчивается двойными кавычками.

Поэтому мы получаем

"O\\\u0027Rei\\\u0022lly"
13
ответ дан 4 December 2019 в 10:30
поделиться

Поскольку вы собираетесь использовать json_encode строку \ ', вам нужно сначала закодировать \ , затем ] '. Таким образом, у вас будут \\ и \ u0027 . Объединяя эти результаты \\ u0027 .

1
ответ дан 4 December 2019 в 10:30
поделиться

\ , сгенерированный addlashes () , повторно экранируется с помощью json_encode () . Вы, вероятно, хотели сказать это Выполнение json_encode ($ s, JSON_HEX_APOS | JSON_HEX_QUOT) выводит следующий , но вы использовали $ str вместо $ s , что сбило с толку всех .

Если вы оцените строку "O \\ u0027Rei \\\ u0022lly" в JavaScript, вы получите "O \ 'rei \" lly ", и я довольно убедитесь, что это , а не то, что вам нужно. Когда вы оцените это, вам, вероятно, потребуется удалить все контрольные коды. Вперед, вставьте это в файл: alert ("O \\\ u0027Rei \\\ u0022lly ") .

Заключение: вы дважды экранируете кавычки, что, скорее всего, не то, что вам нужно. json_encode уже экранирует все, что необходимо, так что любой синтаксический анализатор JavaScript вернет исходный структура данных. В вашем случае это строка, которую вы получили после вызова с добавлением косой черты .


Доказательство:

<?php $out = json_encode(array(10, "h'ello", addslashes("h'ello re-escaped"))); ?>
<script type="text/javascript">
  var out = <?php echo $out; ?>;
  alert(out[0]);
  alert(out[1]);
  alert(out[2]);
</script>
0
ответ дан 4 December 2019 в 10:30
поделиться

Это экранирование обратной косой черты, а также цитаты. Трудно иметь дело с побегами, как вы делаете здесь, так как это быстро превращается в игры со счетом с обратной косой чертой. : - /

2
ответ дан 4 December 2019 в 10:30
поделиться

Если я правильно понял, вы просто хотите знать, почему вам нужно использовать

'\\\\u0027', а не просто '\\\u0027'

Вы экранируете слэш и значение символа unicode. Этим вы говорите json, что он должен поставить здесь апостроф, но ему нужен обратный слеш и u, чтобы понять, что дальше идет шестнадцатеричный код символа.

Поскольку вы экранируете эту строку:

$s = addslashes('O\'Rei"lly'); // O\'Rei\"lly

первый обратный слеш на самом деле экранирует обратный слеш перед апострофом. Затем следующая косая черта используется для экранирования обратной косой черты, используемой json для идентификации символа как символа юникода.

Если бы вы применяли алгорифм к O'Reilly вместо O\'Rei\"lly, то достаточно было бы последнего.

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

http://www.json.org/fatfree.html

2
ответ дан 4 December 2019 в 10:30
поделиться

Когда вы кодируете строку для json, некоторые вещи необходимо экранировать независимо от параметров. Как отмечали другие, это включает '\', поэтому любая обратная косая черта, проходящая через json_encode, будет удвоена. Поскольку вы сначала запускаете свою строку через addlashes, которые также добавляют обратные косые черты к кавычкам, вы добавляете много дополнительных обратных косых черт. Следующая функция будет имитировать, как json_encode будет кодировать строку. Если к строке уже добавлены обратные косые черты, они будут удвоены.

function json_encode_string( $encode , $options ) {
    $escape = '\\\0..\37';
    $needle = array();
    $replace = array();

    if ( $options & JSON_HEX_APOS ) {
        $needle[] = "'";
        $replace[] = '\u0027';
    } else {
        $escape .= "'";
    }

    if ( $options & JSON_HEX_QUOT ) {
        $needle[] = '"';
        $replace[] = '\u0022';
    } else {
        $escape .= '"';
    }

    if ( $options & JSON_HEX_AMP ) {
        $needle[] = '&';
        $replace[] = '\u0026';
    }

    if ( $options & JSON_HEX_TAG ) {
        $needle[] = '<';
        $needle[] = '>';
        $replace[] = '\u003C';
        $replace[] = '\u003E';
    }

    $encode = addcslashes( $encode , $escape );
    $encode = str_replace( $needle , $replace , $encode );

    return $encode;
}
2
ответ дан 4 December 2019 в 10:30
поделиться
Другие вопросы по тегам:

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