PHP json_decode()在看似有效的JSON中返回NULL?

171

我有一个存储在纯文本文件中的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 验证,它是完全有效的。这里出了什么问题?

7
我正在使用 PHP 5.2.9,因此无法使用 json_last_error() - Joel A. Villarreal Bertoldi
1
还要注意的是,文件中间可能存在其他无效字符导致这种情况发生。我曾经遇到过json_decode()返回null的情况,因为字符串包含一个特殊的en-dash,可能是从MS Word复制粘贴而来,然后可能出现了误编码。为了识别潜在的问题字符,打开JSON文件(我用的是Notepad++),更改编码(不要进行转换),并另存为副本。然后比较两个文件的差异(我使用的是WinMerge)。 - LinusR
(Windows 记事本问题)请参考此链接,我也遇到了同样的问题,通过这个链接解决了:https://dev59.com/y2kv5IYBdhLWcg3w4kl2 - Felix Aballi
可能是重复的问题:json_decode 在调用 Web 服务后返回 NULL - user
对我来说,这并不是什么特别的事情,只是一个对象元素末尾多了一个逗号而已。重点是:任何使您的 JSON 不一致的因素都会引发错误。额外提示:不要相信 jsonviewer.stack.hu,使用类似 jsonlint 的工具。 - Aman Alam
@Cristik 问我在11年后编辑问题有点有趣,哈哈。无论如何,我会进行编辑以澄清。 - Joel A. Villarreal Bertoldi
29个回答

3
很可能是BOM,正如其他人所提到的。你可以尝试这个方法:
    // BOM (Byte Order Mark) issue, needs removing to decode
    $bom = pack('H*','EFBBBF');
    $response = preg_replace("/^$bom/", '', $response);
    unset($tmp_bom);
    $response = json_decode($response);

这是一些SDK(如Authorize.NET)已知的bug。


3

这是我如何解决我的问题的 https://dev59.com/6WQm5IYBdhLWcg3w8Sre ..... JSON文件必须采用UTF-8编码,我的文件采用带BOM的UTF-8编码,这导致json字符串输出中添加了奇怪的& 65279;字符,使得json_decode()返回null


3

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

json_last_error_msg();

Ie.

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

你可以通过以下方式来解决这个问题:
$new_json = preg_replace('/[[:cntrl:]]/', '', $json);

2

这是因为您在值或键中使用了(')而不是({")。

这里是错误的格式。

{'name':'ichsan'}

如果您对它们进行解码,它们将返回NULL。

您应该像这样传递JSON请求。

{"name":"ichsan"}

2

在我的情况下,我遇到了同样的问题,但是这是由于json字符串内部的斜杠引起的,因此使用

json_decode(stripslashes($YourJsonString))

或者

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

如果上述方法不起作用,首先将引号替换为HTML引号。如果您正在从JavaScript发送数据到PHP,则可能会发生这种情况。
    $YourJsonString = stripslashes($YourJsonString);
    $YourJsonString = str_replace('"', '"', $YourJsonString);
    $YourJsonString = str_replace('["', '[', $YourJsonString);
    $YourJsonString = str_replace('"]', ']', $YourJsonString);
    $YourJsonString = str_replace('"{', '{', $YourJsonString);
    $YourJsonString = str_replace('}"', '}', $YourJsonString);
    $YourJsonObject = json_decode($YourJsonString);

我会解决它,

2
如果您从数据库获取JSON,请放置:
mysqli_set_charset($con, "utf8");

在定义连接链接 $con 之后

谢谢TomoMiha。这正是解决我在MySQL中包含特殊字符并被json_decode转换时,导致该特定字段为null的所有问题的方法。 - KLL

2
  • 我也遇到了同样的问题...
  • 我通过以下步骤解决了问题... 1) 在浏览器中打印该变量 2) 通过freeformatter验证该变量数据 3) 将该数据复制/参考到后续处理中
  • 之后,我就没有遇到任何问题了。

2

我花了大约一个小时才理解,尾随逗号(在JavaScript中有效)在PHP中失败。
这是解决问题的方法:

str_replace([PHP_EOL, ",}"], ["", "}"], $JSON);

2
所以,html_entity_decode() 对我有效。请尝试这个方法。
$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);

1

只是节省一些时间。我花了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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接