php json_decode 返回 JSON_ERROR_SYNTAX 但在线格式化程序说 JSON 没问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17219916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 12:30:55  来源:igfitidea点击:

json_decode returns JSON_ERROR_SYNTAX but online formatter says the JSON is OK

phpjson

提问by Jean Fran?ois Manatane

I got a very strange problem.

我遇到了一个非常奇怪的问题。

I have a JSON webservice.

我有一个 JSON 网络服务。

When i check it with this website http://www.freeformatter.com/json-formatter.html#ad-output

当我在这个网站http://www.freeformatter.com/json-formatter.html#ad-output

Everything is OK.

一切都好。

But when i load my JSON with this code :

但是当我用这个代码加载我的 JSON 时:

  $data = file_get_contents('http://www.mywebservice');

if(!empty($data))
{

    $obj = json_decode($data);

 switch (json_last_error()) {
    case JSON_ERROR_NONE:
        echo ' - JSON_ERROR_NONE';
    break;
    case JSON_ERROR_DEPTH:
        echo ' - JSON_ERROR_DEPTH';
    break;
    case JSON_ERROR_STATE_MISMATCH:
        echo ' - JSON_ERROR_STATE_MISMATCH';
    break;
    case JSON_ERROR_CTRL_CHAR:
        echo ' -  JSON_ERROR_CTRL_CHAR';
    break;
    case JSON_ERROR_SYNTAX:
        echo "\r\n\r\n - SYNTAX ERROR \r\n\r\n";
    break;
    case JSON_ERROR_UTF8:
        echo ' - JSON_ERROR_UTF8';
    break;
    default:
        echo ' - Unknown erro';
    break;
}

I got the error : SYNTAX ERROR

我收到错误:语法错误

WHICH IS NOT HELP FULL AT ALL.

这根本没有帮助。

It is a nightmare.

这是一场噩梦。

I see that with PHP 5.5 i could use this function : http://php.net/manual/en/function.json-last-error-msg.php

我看到使用 PHP 5.5 我可以使用这个函数:http: //php.net/manual/en/function.json-last-error-msg.php

(but i did not succeed to install PHP 5.5 yet, and i m not sure this function will give me more detail)

(但我还没有成功安装 PHP 5.5,我不确定这个功能会给我更多细节)

回答by Kris Khairallah

I faced the same issue, actually there are some hidden characters unseen and you need to remove it. Here's a global code that works for many cases:

我遇到了同样的问题,实际上有一些隐藏的字符看不见,您需要将其删除。这是适用于许多情况的全局代码:

<?php
$checkLogin = file_get_contents("http://yourwebsite.com/JsonData");

// This will remove unwanted characters.
// Check http://www.php.net/chr for details
for ($i = 0; $i <= 31; ++$i) { 
    $checkLogin = str_replace(chr($i), "", $checkLogin); 
}
$checkLogin = str_replace(chr(127), "", $checkLogin);

// This is the most common part
// Some file begins with 'efbbbf' to mark the beginning of the file. (binary level)
// here we detect it and we remove it, basically it's the first 3 characters 
if (0 === strpos(bin2hex($checkLogin), 'efbbbf')) {
   $checkLogin = substr($checkLogin, 3);
}

$checkLogin = json_decode( $checkLogin );
print_r($checkLogin);
?>

回答by Greg Rundlett

Removing the BOM(Byte Order Mark) is often-times the solution you need:

删除BOM(字节顺序标记)通常是您需要的解决方案:

function removeBOM($data) {
    if (0 === strpos(bin2hex($data), 'efbbbf')) {
       return substr($data, 3);
    }
    return $data;
}

You shouldn't have a BOM, but if it's there, it is invisible so you won't see it!!

你不应该有 BOM,但如果它在那里,它是不可见的,所以你不会看到它!!

see W3C on BOM's in HTML

在 HTML 中查看BOM 上的 W3C

use BOM Cleanerif you have lot's of files to fix.

如果您有很多文件要修复,请使用BOM Cleaner

回答by hobbito

I solved this issue adding stripslashesto the string, before json_decode.

我解决了这个问题,增加的stripslashes字符串,json_decode之前。

$data = stripslashes($data); 
$obj = json_decode($data);

回答by Krzysztof Przygoda

To put all things together here and there, I've prepared JSON wrapper with decoding auto corrective actions. Most recent version can be found in my GitHub Gist.

为了把所有东西放在一起,我准备了带有解码自动纠正动作的 JSON 包装器。最新版本可以在我的GitHub Gist 中找到。

abstract class Json
{
    public static function getLastError($asString = FALSE)
    {
        $lastError = \json_last_error();

        if (!$asString) return $lastError;

        // Define the errors.
        $constants = \get_defined_constants(TRUE);
        $errorStrings = array();

        foreach ($constants["json"] as $name => $value)
            if (!strncmp($name, "JSON_ERROR_", 11))
                $errorStrings[$value] = $name;

        return isset($errorStrings[$lastError]) ? $errorStrings[$lastError] : FALSE;
    }

    public static function getLastErrorMessage()
    {
        return \json_last_error_msg();
    }

    public static function clean($jsonString)
    {
        if (!is_string($jsonString) || !$jsonString) return '';

        // Remove unsupported characters
        // Check http://www.php.net/chr for details
        for ($i = 0; $i <= 31; ++$i)
            $jsonString = str_replace(chr($i), "", $jsonString);

        $jsonString = str_replace(chr(127), "", $jsonString);

        // Remove the BOM (Byte Order Mark)
        // It's the most common that some file begins with 'efbbbf' to mark the beginning of the file. (binary level)
        // Here we detect it and we remove it, basically it's the first 3 characters.
        if (0 === strpos(bin2hex($jsonString), 'efbbbf')) $jsonString = substr($jsonString, 3);

        return $jsonString;
    }

    public static function encode($value, $options = 0, $depth = 512)
    {
        return \json_encode($value, $options, $depth);
    }

    public static function decode($jsonString, $asArray = TRUE, $depth = 512, $options = JSON_BIGINT_AS_STRING)
    {
        if (!is_string($jsonString) || !$jsonString) return NULL;

        $result = \json_decode($jsonString, $asArray, $depth, $options);

        if ($result === NULL)
            switch (self::getLastError())
            {
                case JSON_ERROR_SYNTAX :
                    // Try to clean json string if syntax error occured
                    $jsonString = self::clean($jsonString);
                    $result = \json_decode($jsonString, $asArray, $depth, $options);
                    break;

                default:
                    // Unsupported error
            }

        return $result;
    }
}

Example usage:

用法示例:

$json_data = file_get_contents("test.json");
$array = Json::decode($json_data, TRUE);
var_dump($array);
echo "Last error (" , Json::getLastError() , "): ", Json::getLastError(TRUE), PHP_EOL;

回答by Bheru Lal Lohar

After trying all the solution without the result this is the one worked for me.

在尝试了所有没有结果的解决方案之后,这对我有用。

Hope it will help someone

希望它会帮助某人

$data = str_replace('&quot;', '"', $data);

回答by Георги Колев

I have the same problem, receiving JSON_ERROR_CTRL_CHARand JSON_ERROR_SYNTAX.
This is my fix.

我有同样的问题,收到JSON_ERROR_CTRL_CHARJSON_ERROR_SYNTAX
这是我的修复。

$content = json_decode(json_encode($content), true);

回答by Dhrupad Joshi

please first clean json data and then load.

请先清理json数据,然后加载。

回答by ?mürcan Cengiz

A JSON string must be double-quoted, the JSON isn't valid because you don't need to escape 'character.

JSON 字符串必须用双引号引起来,JSON 无效,因为您不需要转义'字符。

char = unescaped /
  escape (
      %x22 /          ; "    quotation mark  U+0022
      %x5C /          ; \    reverse solidus U+005C
      %x2F /          ; /    solidus         U+002F
      %x62 /          ; b    backspace       U+0008
      %x66 /          ; f    form feed       U+000C
      %x6E /          ; n    line feed       U+000A
      %x72 /          ; r    carriage return U+000D
      %x74 /          ; t    tab             U+0009
      %x75 4HEXDIG )  ; uXXXX                U+XXXX

The 'is not in the list.

'列表中是没有的。

See this list of special character used in JSON:

请参阅此 JSON 中使用的特殊字符列表:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\  Backslash character

Check out thissite for more documentation.

查看站点以获取更多文档。

回答by meda

You haven't show your JSON but this sound like it could be an Invalid UTF-8 sequence in argument, most online validator wont catch it. make sure your data is UTF-8 and also check if you have foreign characters. You don't need PHP5 to see your error, use error_log()to log the problems.

您还没有显示您的 JSON,但这听起来像是参数中的无效 UTF-8 序列,大多数在线验证器都不会捕捉到它。确保您的数据是 UTF-8 并检查您是否有外来字符。你不需要 PHP5 来查看你的错误,使用error_log()来记录问题。

回答by Stefan Pintilie

One problem from my side, is that there were some invalid numbers starting with 0, Ex: "001", "002", "003".

我这边的一个问题是,有一些以 0 开头的无效数字,例如:“001”、“002”、“003”。

     "expectedToBeReturned":1,
     "inventoryNumber":001,
     "remindNote":"",

Replace 001 with 1 and it works.

用 1 替换 001 就可以了。