PHP json_decode()返回带有有效JSON的NULL?


104

我将这个JSON对象存储在纯文本文件中:

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

当我尝试用解码时json_decode(),它返回NULL。为什么?该文件是可读的(我尝试了回显file_get_contents(),但工作正常)。

我已经针对http://jsonlint.com/测试了JSON ,它是完全有效的。

怎么了

在Google上寻找答案,我回到SO:调用webservice后json_decode返回NULL。我的JSON文件具有UTF BOM序列(一些不应包含的二进制字符),因此破坏了JSON结构。进入十六进制编辑器,删除了字节。一切恢复正常。为什么会这样呢?因为我使用Microsoft Windows的记事本编辑了文件。好主意!


5
使用PHP 5.2.9; 因此,我不能使用json_last_error()
Joel A. Villarreal Bertoldi 2010年

1
另请注意,文件中间的其他无效字符可能会发生这种情况。我只是让json_decode()返回null,因为字符串包含那些特殊的破折号之一,可能是从MS Word粘贴的,然后可能被错误编码了。要确定潜在的问题字符,请打开JSON文件(我在Notepad ++中使用过),更改编码(不进行转换),然后另存为副本。然后比较两个文件(我使用WinMerge)。
LinusR 2012年

(Windows记事本的问题)请咨询本,我分享的问题也和它固定它:stackoverflow.com/questions/10290849/...
费利克斯Aballi


对我来说,这没什么特别的,只是对象元素末尾的逗号。带走:任何使您的JSON不一致的东西,都将引发错误。温馨提示:不要相信jsonviewer.stack.hu使用jsonlint之类的东西
Aman Alam

Answers:


68

它可以是特殊字符的编码。您可以要求json_last_error()获得确切的信息。

更新:问题已解决,请查看问题中的“解决方案”段落。


自启动应用程序以来,我一直在使用特殊字符,以前没有任何问题。在本地,JSON解码效果很好。在我的服务器上,没有。我不能打电话,json_last_error()因为它是PHP 5.2.9。该功能出现在PHP 5.3.0上。
Joel A. Villarreal Bertoldi 2010年

1
不,这应该有效。我现在无法进行更多测试,如果稍后再进行测试,我将在此处发布。用户提供的注释中也有一些提示:de.php.net/json_decode也许有帮助。
Pekka 2010年

1
对我来说,在PHP 5.3上,当文本以UTF-8编码时,它可以正常工作。但是,如果我先通过文本utf8_decode(),则json_decode()默默失败。
马修

1
@Pekka在Google上寻找答案,我回到了:stackoverflow.com/questions/689185/json-decode-returns-null-php。我的JSON文件具有UTF BOM序列(一些不应包含的二进制字符),因此破坏了JSON结构。进入十六进制编辑器,删除了字节。一切恢复正常。为什么会这样呢?因为我使用Micro $ oft Windows的记事本编辑了文件。好主意!
Joel A. Villarreal Bertoldi 2010年

2
应该向PHP人员报告此错误。如果BOM是有效的UTF8,则不应默默地阻止它。
jmucchiello 2010年

85

这对我有用

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );

2
我已经使用了它并得到了数组,但是我的语言特定字符(ş,ç,ö,..)也已删除。
zkanoca 2014年

5
如果json数据是UTF-8编码的(或者我猜是任何UTF编码),这是不正确的。它将删除有效的UTF-8编码数据。只要文件仅包含英语,它就可能起作用,但这始终是一个冒险的假设。我不会用这个。
DaedalusAlpha

有了它,它起作用了,但是没有它就不起作用了,即使两个字符串都一样,我是否丢失了某些东西?
鲁迪·维瑟

它确实有效!但为什么?我尝试解码的字符串中没有任何特殊字符
Tobias Gassmann

太棒了 为我工作。:)
Sohil


22

如果您在chrome中检查请求,您会看到JSON是文本,因此已向JSON添加了空白代码。

您可以使用清除它

$k=preg_replace('/\s+/', '',$k);

然后,您可以使用:

json_decode($k)

print_r 然后将显示数组。


谢谢您-希望您找到缺少的英语。
Dean_Wilson

伙计,你是传奇,整天都在纠结。
Sboniso Marcus Nzimande '02

为我做了!!我做了一个简单的调整,就是在替换中添加一个空格,正在使用它,而且似乎也在替换我的空间。现在工作正常。$k=preg_replace('/\s+/', ' ',$k);
卡什

问题是,这会删除每个空格,使英文文本全部粘在一起,不是吗?
CodeGuru '19

14

我有同样的问题,我只需在解码之前替换引号就解决了。

$json = str_replace('"', '"', $json);
$object = json_decode($json);

我的JSON值是由JSON.stringify函数生成的。


在这种情况下,可能已经使用了htmlspecialchars函数,并且无法再解析JSON。要对其进行逆转,可以使用函数“ htmlspecialchars_decode”,而不是手动替换“
戴维

11

也许有些隐藏的字符弄乱了您的json,请尝试以下操作:

$json = utf8_encode($yourString);
$data = json_decode($json);

在尝试了上述所有解决方案之后,这个最终为我工作了。万分感谢!!
Anis R.

7
$k=preg_replace('/\s+/', '',$k); 

为我做了。是的,在Chrome上进行测试。Thx用户2254008


4

我今天遇到这个问题时,以为我会加上这个。如果您的JSON字符串周围有任何字符串填充,则json_decode将返回NULL。

如果您要从PHP变量以外的其他来源提取JSON,则最好先“修剪”它:

$jsonData = trim($jsonData);

4

这可以帮助您了解错误的类型

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

    echo PHP_EOL;
}
?>

2

只需保存一次即可。我花了3个小时才发现这仅仅是html编码问题。试试这个

if(get_magic_quotes_gpc()){
   $param = stripslashes($row['your column name']);
}else{
  $param = $row['your column name'];
}

$param = json_decode(html_entity_decode($param),true);
$json_errors = array(
JSON_ERROR_NONE => 'No error has occurred',
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
);
echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
print_r($param);

1

正如JürgenMath所说,使用user2254008列出的preg_replace方法也为我修复了它。

这不仅限于Chrome,它似乎是字符集转换问题(至少在我的情况下,是Unicode-> UTF8)。这解决了我遇到的所有问题。

作为未来的节点,我正在解码的JSON对象来自Python的json.dumps函数。这反过来又导致了其他一些不卫生的数据,尽管这些数据很容易处理。


1

如果要从数据库获取json,请放入

mysqli_set_charset($con, "utf8");

定义连接链接$ con之后


谢谢TomoMiha。这正好适合我所有包含特殊字符的MySQL的问题,当通过json_decode转换时,该特定字段的结果为= null...。–
KLL


1

就我而言,这是因为JSON字符串中的单引号。

JSON格式仅接受键和字符串值的双引号。

例:

$jsonString = '{\'hello\': \'PHP\'}'; // valid value should be '{"hello": "PHP"}'
$json = json_decode($jsonString);
print $json; // null

由于Javascript语法,我对此感到困惑。当然,在Javascript中,我们可以这样做:

let json = {
    hello: 'PHP' // no quote for key, single quote for string value
}

// OR:
json = {
    'hello': 'PHP' // single quote for key and value
}

但是稍后将这些对象转换为JSON字符串时:

JSON.stringify(json); // "{"hello":"PHP"}"

0

我已经解决了此问题,方法是打印JSON,然后检查页面源(CTRL / CMD + U):

print_r(file_get_contents($url));

原来有一个尾随<pre>标记。


0

你应该确保这些要点

1.您的json字符串没有任何未知字符

2. json字符串可以从在线json查看器查看(您可以在Google上以json的在线查看器或解析器搜索),它应该查看没有任何错误

3.您的字符串没有html实体,它应该是纯文本/字符串

对于第3点的解释

$html_product_sizes_json=htmlentities($html);
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

(删除htmlentities()函数)

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

0

对我来说,我必须关闭error_reporting,以使json_decode()正常工作。听起来很奇怪,但就我而言是真实的。因为我尝试解码的JSON字符串之间印有一些通知。


0

要记住的最重要的事情是,从有效的JSON数据中获得NULL结果时,请使用以下命令:

json_last_error_msg();

就是

var_dump(json_last_error_msg());
string(53) "Control character error, possibly incorrectly encoded"

然后,您可以通过以下方法解决此问题:

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);

0

因此,html_entity_decode()对我有用。请尝试这个。

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);

-5
<?php 
$json_url = "http://api.testmagazine.com/test.php?type=menu";
$json = file_get_contents($json_url);
$json=str_replace('},

]',"}

]",$json);
$data = json_decode($json);

echo "<pre>";
print_r($data);
echo "</pre>";
?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.