Php 转义转义字符
我试图模拟PHP 5.3.0中实现的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', '\\\
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也会将反斜杠添加到引号中,因此您添加了大量额外的反斜杠跟随功能