错误在PHP json_decode()传递一个JSON文件时

问题描述:

考虑j.json文件,其内容如下有效的JSON:错误在PHP json_decode()传递一个JSON文件时

{ 
    "t": "\\" 
} 

PHP json_encode不能收杆它:

$r=json_decode(file_get_contents('j.json')); 

var_dump($r); //returns null 

注:问题被清理了,问题是一样的。

+0

那么,你的'j.json'是什么?你编辑它,现在它看起来不像我有效的'JSON'。你有没有这样做?因为现在问题(和答案)不再有什么意义了...... – Nanne 2012-07-24 08:42:45

+0

好的,但问题仍然是一样的,因为你只是简单一些?这是一件好事,但它确实使下面的答案有点难以阅读,也许你可能只是添加了一点解释,这是你的其他代码的简化版本... – Nanne 2012-07-24 08:52:20

不幸的是json_decode被错误地实现,当得到一些有效的JSON 文件或者可以修改它们的值可能返回null,则可以使用下面的功能,可以解码所有有效的JSON字符串:

function r_json_decode($jsonString,$originalJsonValue=false){ 

    $j=($originalJsonValue)?str_replace('\\','\\\\\\\\',$jsonString):str_replace('\\','\\\\',$jsonString); 
    return json_decode($j); 

} 


echo(r_json_decode(file_get_contents('j.json'))->t);  // prints "/" 
echo(r_json_decode(file_get_contents('j.json'),true)->t); //prints "//" 

尝试

json_decode('{ 
    "target": "^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr" 
}'); 

您有一个额外的逗号,你必须(第一为PHP字符串,然后将JSON)逃离反斜线的两倍。

echo "\\"; // outputs "\" 
echo "\\\\"; // outputs "\\", ie what you need for the json 
+0

请告诉OP你改变或修正了什么,并解释为什么...... – 2012-07-22 13:17:47

+0

** - 1 **这不仅仅是关于逗号。我甚至不知道你为什么起身投票....它不[甚至工作](http://codepad.viper-7.com/Yu65PH)。 – Christian 2012-07-22 13:24:55

+0

你是对的,我错过了反斜杠的东西。用一个简短而简单的解释编辑 – AdrienBrault 2012-07-22 13:29:12

<?php 

echo var_export(json_encode((object)array('target'=>'^http://(www|corail)\\.sudoc\\.abes\\.fr'))); 

echo '<br/>'; 

echo '{ 
    "target": "^http://(www|corail)\\.sudoc\\.abes\\.fr" 
}'; 

我在这里做什么是我手动写的对象在PHP中,编码成JSON然后"exported"它,看看它作为一个PHP字符串。

然后我把它和你的字符串进行比较。

这里的结果:

'{"target":"^http:\\/\\/(www|corail)\\\\.sudoc\\\\.abes\\\\.fr"}' 
{ "target": "^http://(www|corail)\.sudoc\.abes\.fr" } 

你可以清楚地看到你的字符串错过了一些字符:你需要逃避所有向前和向后斜杠。

+0

没有意识到'/'也需要转义成'\ /',或者实际上是可选的? – 2012-07-22 14:00:12

+0

@AlvinWong它确实是可选的。我原以为这是有原因的,但尽可能地尝试,我找不到一个。 – Christian 2012-07-22 16:42:46

你需要这样的:

<?php 
json_decode('{ 
    "target": "^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr" 
}') 

你逃过了\\唯一的一次。你需要两次,第一次是PHP,第二次是JSON。

P.S.由于您在JSON字符串看起来像一个正则表达式,你可能需要做一个更多的时间逃离,即双反斜线的数量再次


让我试着想象这是怎么回事。首先在PHP中,你写的字符串是这样的:

$s='{"a":"^http://(www|corail)\\\\\\\\.sudoc\\\\\\\\.abes\\\\\\\\.fr"}' 

在此之后,如果你echo $s,你会发现这一点:

{"a":"^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr"} 

然后,如果你json_decode($s),成员a将使内容:

^http://(www|corail)\\.sudoc\\.abes\\.fr 

最后,当您执行的正则表达式,\\进一步逃到\


如果你尝试:

<?php 
echo '{ 
    "target": "^http://(www|corail)\\.sudoc\\.abes\\.fr" 
}'; 

输出为:

{ 
    "target": "^http://(www|corail)\.sudoc\.abes\.fr" 
} 

见出了什么问题?在JSON(JavaScript的)\.不是有效的转义序列,所以它不是有效的JSON,所以json_decode会失败,返回NULL


如果你尝试:

<?php 
echo '{ 
    "target": "^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr" 
}'; 

输出为:

{ 
    "target": "^http://(www|corail)\\.sudoc\\.abes\\.fr" 
} 

其转义序列\\有效期为JSON。

+1

@Reza **因为你需要逃避所有斜杠。**你不能阅读我的答案吗? – Christian 2012-07-22 13:26:45

+0

实际上,因为[如果json无法解码或者编码数据比递归限制更深,则返回NULL。](http://php.net/manual/en/function。json-decode.php) – 2012-07-22 13:28:12

+0

@AlvinWong我也会解释一下斜杠是用来转义一个PHP字符串的,因此为什么PHP字符串中的双斜杠会导致该字符串中的一个实际斜杠。 – Christian 2012-07-22 13:28:13

的问题是有意逃避。似乎有一些关于如何在PHP中解析JSON的讨论(请参阅手册http://php.net/manual/en/function.json-decode.php上的注释)。

无论如何,你可以从这个“小提琴”http://codepad.viper-7.com/2t4pP0看到,你需要开始添加他们的反斜杠!
它这样做是:

<?php 
    $r=json_decode('{"t": "a"}'); 
    var_dump($r); 
echo "<br/>\n"; 
    $r=json_decode('{"t": "\a"}'); 
    var_dump($r); 
echo "<br/>\n"; 
    $r=json_decode('{"t": "\\a"}'); 
    var_dump($r); 
echo "<br/>\n"; 
    $r=json_decode('{"t": "\\\a"}'); 
    var_dump($r); 
echo "<br/>\n"; 
    $r=json_decode('{"t": "\\\\a"}'); 
    var_dump($r); 

和输出

object(stdClass)#1 (1) { ["t"]=> string(1) "a" } 
NULL 
NULL 
object(stdClass)#1 (1) { ["t"]=> string(2) "\a" } 
object(stdClass)#2 (1) { ["t"]=> string(2) "\a" } 

现在取决于你试图完成什么(你的问题的当前编辑有没有提到任何目标),你应该能够弄清楚该怎么做?