Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 转义转义字符_Php_Escaping_Json_Str Replace - Fatal编程技术网

Php 转义转义字符

Php 转义转义字符,php,escaping,json,str-replace,Php,Escaping,Json,Str Replace,我试图模拟PHP 5.3.0中实现的json_encode位掩码标志,下面是我的字符串: $s = addslashes('O\'Rei"lly'); // O\'Rei\"lly 执行json_编码($s,json_HEX_APOS | json_HEX_QUOT)输出以下内容: "O\\\u0027Rei\\\u0022lly" 我目前正在5.3.0以上的PHP版本中执行此操作: str_replace(array('\\"', "\\'"), array('\\u0022', '\\\

我试图模拟PHP 5.3.0中实现的
json_encode
位掩码标志,下面是我的字符串:

$s = addslashes('O\'Rei"lly'); // O\'Rei\"lly
执行
json_编码($s,json_HEX_APOS | json_HEX_QUOT)
输出以下内容:

"O\\\u0027Rei\\\u0022lly"
我目前正在5.3.0以上的PHP版本中执行此操作:

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));
}
<?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>
if(get_magic_quotes_gpc()&&version_compare(PHP_version,'6.0.0','=')==true)
{
$GET=json编码($GET,json HEX APOS,json HEX);
$邮政=json编码($邮政,json十六进制,json十六进制);
$COOKIE=json编码($COOKIE,json十六进制,json十六进制);
$请求=json编码($请求,json十六进制,json十六进制);
}
/*模仿JSON“uHex”和JSON“uHex”的行为*/
else if(已加载扩展名('json')==true)
{
$\u GET=str\u replace(array(),array('\\u0022','\\u0027'),json\u encode($\u GET));
$\u POST=str_replace(数组(),数组('\\u0022','\\u0027'),json_encode($\u POST));
$\u COOKIE=str\u replace(array(),array('\\u0022','\\u0027'),json\u encode($\u COOKIE));
$\u REQUEST=str\u replace(array(),array('\\u0022','\\u0027'),json\u encode($\u REQUEST));
}
$\u GET=json\u解码(stripslashes($\u GET));
$_POST=json_解码(带斜杠($_POST));
$_COOKIE=json_解码(条带斜杠($_COOKIE));
$_请求=json_解码(带斜杠($_请求));
}

它避开了反斜杠和引号。处理越狱很困难,就像你在这里做的那样,因为它很快就会变成反斜杠计数游戏-/

由于要对字符串
\
进行
json\u编码
,因此必须先对
\
进行编码,然后对
'
进行编码。因此,您将拥有
\
\u0027
。连接这些结果
\\\u0027

addslashes()
生成的
\
通过
json\u encode()
重新转义。你可能是想说做json编码($s,json'u HEX'u APOS | json'u HEX'u QUOT)会输出以下内容,但是你使用了
$str
而不是
$s
,这让大家都很困惑

如果您在JavaScript中计算字符串
“O\\\u0027Rei\\\u002lly”
,您将得到
“O\\\rei\\\u002lly”
,我很确定这不是您想要的。当您计算它时,您可能需要删除所有控制代码。继续,在文件中插入此代码:
警报(“O\\\u0027Rei\\\\u002lly”)

结论:您正在两次转义引号,这很可能不是您需要的。
json_encode
已经转义了所有需要的内容,以便任何JavaScript解析器都将返回原始数据结构。在您的情况下,这是调用
addslashes
后获得的字符串


证明:

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

如果我理解正确,您只想知道为什么需要使用

“\\\u0027”
而不仅仅是
“\\u0027”

您正在转义斜杠和字符unicode值。这样您告诉json它应该在那里放一个撇号,但它需要反斜杠和u来知道下一个是unicode十六进制字符代码

由于要转义此字符串:

$s = addslashes('O\'Rei"lly'); // O\'Rei\"lly
第一个反斜杠实际上是转义撇号之前的反斜杠。然后下一个斜杠用于转义json用于将字符标识为unicode字符的反斜杠

如果将算法应用于O'Reilly而不是O'Rei\'lly,则后者就足够了

我希望你觉得这有用。我只给您留下这个链接,以便您可以阅读更多关于如何构造json的内容,因为您显然已经了解PHP:

PHP字符串

'O\'Rei"lly'
这只是PHP获取文本值的方式

O'Rei"lly
转换成可以使用的字符串。对该字符串调用
addslashes
,将其更改为以下11个字符

O\'Rei\"lly
i、 e.
strlen(addslashes('O'Rei“lly'))==11

这是发送到
json\u escape
的值

在JSON中,反斜杠是一个转义字符,因此需要转义,即

\
将成为
\

单引号和双引号也会引起问题。因此,用一种方法将它们转换为unicode等价物以避免问题。因此,PHP的json_编码的后续版本会发生变化

将成为
\u0027

将成为
\u0022

因此,将这三条规则应用于

O\'Rei\"lly
给我们

O\\\u0027Rei\\\u0022lly
然后将该字符串用双引号包装,使其成为JSON字符串。替换表达式包括前导的正斜杠。这意味着
json_encode
返回的前导双引号和尾随双引号不受转义的约束,这是不应该的

所以在PHP的早期版本中

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

"O\\'Rei\\\"lly"
我们想把
'
改成
\u0027
我们想把
\“
改为
\u0022
,因为
\”
中的
\
只是将
放入字符串中,因为它以双引号开头和结尾

所以这就是为什么我们

"O\\\u0027Rei\\\u0022lly"

当您为json编码字符串时,无论选项如何,有些内容都必须转义。正如其他人所指出的,这包括“\”,因此通过json编码运行的任何反斜杠都将加倍。由于您首先通过addslashes运行字符串,而addslashes也会将反斜杠添加到引号中,因此您添加了大量额外的反斜杠跟随功能