【问题标题】:PHP json_decode() returns NULL with valid JSON?PHP json_decode() 使用有效的 JSON 返回 NULL?
【发布时间】:2011-01-25 12:05:52
【问题描述】:

我将此 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,它完全有效。

这里有什么问题?

更新(对我 2010 年问题的有效回复)

在谷歌上寻找答案,我回到了 SO:json_decode returns NULL after webservice call。我的 JSON 文件具有 UTF BOM 序列(一些不应该存在的二进制字符),因此破坏了 JSON 结构。去十六进制编辑器,擦除字节。一切恢复正常。 为什么会这样? 因为我使用 Microsoft Windows 的记事本编辑了文件。糟糕的想法!

【问题讨论】:

  • 使用 PHP 5.2.9;因此,我不能使用json_last_error()
  • 另请注意,文件中间的其他无效字符可能会发生这种情况。我刚刚让 json_decode() 返回 null,因为字符串包含其中一个特殊的破折号,可能是从 MS Word 粘贴的,然后可能是错误编码的。要识别潜在的问题字符,请打开 JSON 文件(我在 Notepad++ 中使用),更改编码(无需转换),然后另存为副本。然后比较这两个文件(我使用了 WinMerge)。
  • (Windows 记事本问题)请参考这个问题,我也分享了这个问题并修复了它:stackoverflow.com/questions/10290849/…
  • 对我来说,这没什么特别的,只是对象元素末尾的一个额外的逗号。带走:任何使您的 JSON 不一致的东西都会引发错误。额外提示:不要相信 jsonviewer.stack.hu 使用类似 jsonlint 的东西

标签: php json null


【解决方案1】:

我遇到了同样的问题,但没有一个答案对我有帮助。 我的 JSON 对象中的一个变量的值为 Andaman & Nicobar。我删除了这个&,我的代码运行良好。

【讨论】:

    【解决方案2】:

    在应用 PHP 相关解决方案之前,请验证您的 JSON 格式。也许这就是问题所在。试试这个在线 JSON 格式验证器。 https://jsonformatter.org/

    【讨论】:

      【解决方案3】:

      对我来说,php 函数 stripslashes() 在从 javascript 接收 json 时起作用。当从 python 接收 json 时,调用 json_decode 的第二个可选参数起到了作用,因为数组是关联的。像魅力一样为我工作。

      $json = stripslashes($json); //add this line if json from javascript
      $edit = json_decode($json, true); //adding parameter true if json from python
      

      【讨论】:

        【解决方案4】:

        这是我如何解决我的https://stackoverflow.com/questions/17219916/64923728 .. JSON 文件必须采用 UTF-8 编码,我的采用 UTF-8 和 BOM,这会添加一个奇怪的 &65279; 到json字符串输出导致json_decode()返回null

        【讨论】:

          【解决方案5】:

          在我的情况下,我遇到了同样的问题,但它是由 json 字符串中的斜杠引起的,所以使用

          json_decode(stripslashes($YourJsonString))
          

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

          如果上述方法不起作用,请先替换 html quote 中的引号,如果您将数据从 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);
          

          会解决的,

          【讨论】:

            【解决方案6】:

            我遇到了完全相同的问题 但它已被此代码修复

            $zip = file_get_contents($file);
            $zip = json_decode(stripslashes($zip), true);
            

            【讨论】:

              【解决方案7】:
              • 我也面临同样的问题...
              • 我修复了以下步骤... 1) 我在浏览器中打印该变量 2) 通过 freeformatter 验证该变量数据 3) 在进一步处理中复制/引用该数据
              • 在那之后,我没有遇到任何问题。

              【讨论】:

                【解决方案8】:

                我建议创建一个 .json 文件(例如:config.json)。 然后粘贴所有 json 对象并 format 它。因此,您将能够删除所有破坏 json-object 的东西,并获得干净的复制粘贴 json-object。

                【讨论】:

                  【解决方案9】:

                  我花了大约一个小时才弄明白,但尾随逗号(适用于 JavaScript)在 PHP 中失败。
                  这就是为我解决的问题:

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

                  【讨论】:

                    【解决方案10】:

                    所以,html_entity_decode() 对我有用。请试试这个。

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

                    【讨论】:

                      【解决方案11】:

                      最重要的是要记住,当您从有效的 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);
                      

                      【讨论】:

                        【解决方案12】:

                        对我来说,我必须关闭 error_reporting,才能让 json_decode() 正常工作。这听起来很奇怪,但在我的情况下是真的。因为在我尝试解码的 JSON 字符串之间打印了一些通知。

                        【讨论】:

                          【解决方案13】:

                          对于我来说,这是因为 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"}"
                          

                          【讨论】:

                            【解决方案14】:

                            在这里您可以找到带有纠正措施的小型 JSON 包装器,可解决 BOM 和非 ASCI 问题:https://stackoverflow.com/a/43694325/2254935

                            【讨论】:

                              【解决方案15】:

                              您应该确保这些要点

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

                              【讨论】:

                                【解决方案16】:

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

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

                                【讨论】:

                                • 从 PHP 5.5.0 开始,您可以使用方法 json_last_error_msg 来获取一些有用的消息
                                【解决方案17】:

                                我通过打印 JSON,然后检查页面源 (CTRL/CMD + U) 解决了这个问题:

                                print_r(file_get_contents($url));
                                

                                原来有一个尾随&lt;pre&gt;标签。

                                【讨论】:

                                  【解决方案18】:

                                  也许有些隐藏的字符弄乱了你的 json,试试这个:

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

                                  【讨论】:

                                  • 在尝试了上述所有解决方案之后,这个终于为我工作了。非常感谢!
                                  【解决方案19】:

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

                                  你可以使用清除它

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

                                  那么你可以使用:

                                  json_decode($k)

                                  print_r 然后将显示该数组。

                                  【讨论】:

                                  • 谢谢你 - 希望你能找到你丢失的英语。
                                  • 你是传奇人物,整天都在琢磨这个。
                                  • 为我做的!!我做的一个简单的调整是在替换中添加一个空格,我正在使用它,它似乎也替换了我的空格。现在工作正常。 $k=preg_replace('/\s+/', ' ',$k);
                                  • 问题是,这会删除每个空格,让英文文本都粘在一起不是吗?
                                  【解决方案20】:

                                  你可以试试。

                                  json_decode(stripslashes($_POST['data']))
                                  

                                  【讨论】:

                                  • 我不小心调用了两次stripslashes(),删除了必要的斜线并导致无效的JSON字符串。这个答案帮助我发现了错误
                                  • 非常感谢您的回答,您节省了我的时间!
                                  【解决方案21】:

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

                                  【讨论】:

                                    【解决方案22】:
                                    $k=preg_replace('/\s+/', '',$k); 
                                    

                                    为我做的。是的,在 Chrome 上进行测试。感谢 user2254008

                                    【讨论】:

                                      【解决方案23】:

                                      如果你是从数据库中获取json,放

                                      mysqli_set_charset($con, "utf8");
                                      

                                      定义连接链接$con后

                                      【讨论】:

                                      • 谢谢 TomoMiha。这正是我对包含特殊字符的 MySQL 的所有问题,当通过 json_decode 转换时,该特定字段被 yield = null ....
                                      【解决方案24】:

                                      这对我有用

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

                                      【讨论】:

                                      • 我已经使用了这个并得到了数组,但是我的语言特定字符(ş,ç,ö,..)也被删除了。
                                      • 如果 json 数据是 UTF-8 编码(或者我猜是任何 UTF 编码),这是不正确的。它将删除有效的 UTF-8 编码数据。只要文件仅包含英语,它就可能会起作用,但这始终是一个冒险的假设。我不会用这个。
                                      • 有了这个它可以工作,但没有它就不行,即使两个字符串相同,我是否遗漏了什么?
                                      • 它确实有效!但为什么?我尝试解码的字符串中没有任何特殊字符
                                      • 太棒了。为我工作。 :)
                                      【解决方案25】:

                                      我遇到了同样的问题,我只是通过在解码之前替换引号字符来解决它。

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

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

                                      【讨论】:

                                      • 在这种情况下,可能使用了函数 htmlspecialchars 并且无法再解析 JSON。要反转它,可以使用“htmlspecialchars_decode”函数而不是手动替换“
                                      【解决方案26】:

                                      只是想我会添加这个,因为我今天遇到了这个问题。如果您的 JSON 字符串周围有任何字符串填充,则 json_decode 将返回 NULL。

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

                                      $jsonData = trim($jsonData);
                                      

                                      【讨论】:

                                        【解决方案27】:
                                        <?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>";
                                        ?>
                                        

                                        【讨论】:

                                          【解决方案28】:

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

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

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

                                          【讨论】:

                                            【解决方案29】:

                                            可能是特殊字符的编码。你可以向json_last_error()询问确切的信息。

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

                                            【讨论】:

                                            • 自从我启动应用程序以来,我一直在使用特殊字符,之前没有任何问题。在本地,JSON 解码工作完美。在我的服务器上,它没有。我不能打电话给json_last_error(),因为它是 PHP 5.2.9。该函数出现在 PHP 5.3.0 上。
                                            • 不,这应该可以。我现在不能做更多的测试,如果我稍后会在这里发布。用户贡献的笔记中也有一些提示:de.php.net/json_decode也许有帮助。
                                            • 对我来说,在 PHP 5.3 上,当文本以 UTF-8 编码时,它可以正常工作。但是如果我先通过utf8_decode() 传递文本,那么json_decode() 会默默地失败。
                                            • @Pekka 在谷歌上寻找答案,我回到了 SO:stackoverflow.com/questions/689185/json-decode-returns-null-php。我的 JSON 文件具有 UTF BOM 序列(一些不应该存在的二进制字符),因此破坏了 JSON 结构。去十六进制编辑器,擦除字节。一切恢复正常。为什么会这样?因为我使用 Micro$oft Windows 的记事本编辑了文件。好主意!
                                            • 这应该作为一个错误报告给 PHP 人员。如果 BOM 是有效的 UTF8,它不应该默默地阻塞它。
                                            猜你喜欢
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 2019-04-27
                                            • 1970-01-01
                                            • 2018-02-27
                                            • 1970-01-01
                                            相关资源
                                            最近更新 更多