Home » Php » php – json_decode returns JSON_ERROR_SYNTAX but online formatter says the JSON is OK

php – json_decode returns JSON_ERROR_SYNTAX but online formatter says the JSON is OK

Posted by: admin April 23, 2020 Leave a comment

Questions:

I got a very strange problem.

I have a JSON webservice.

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

Everything is OK.

But when i load my JSON with this code :

  $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

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

How to&Answers:

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

Answer:

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

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!!

see W3C on BOM’s in HTML

use BOM Cleaner if you have lot’s of files to fix.

Answer:

I solved this issue adding stripslashes to the string, before json_decode.

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

Answer:

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.

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;

Answer:

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

Answer:

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

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

Answer:

please first clean json data and then load.

Answer:

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.

Answer:

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

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:

\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 this site for more documentation.

Answer:

I had the same issues. I took the following steps:

  1. changed the JSON text encoding

    $json = utf8_encode($json);
    
  2. I then viewed the plain text before decoding. I found crazy symbols like

    ï

  3. then I just stripped it off

    $json = str_replace(array('ï',''), '',$json);
    

    and I successfully decoded my JSON

Answer:

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

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

Replace 001 with 1 and it works.

Answer:

This code worked for me.
Basically it removes hidden characters.

    function cleanString($val)
    {
        $non_displayables = array(
        '/%0[0-8bcef]/',            # url encoded 00-08, 11, 12, 14, 15
        '/%1[0-9a-f]/',             # url encoded 16-31
        '/[\x00-\x08]/',            # 00-08
        '/\x0b/',                   # 11
        '/\x0c/',                   # 12
        '/[\x0e-\x1f]/',            # 14-31
        '/x7F/'                     # 127
        );
        foreach ($non_displayables as $regex)
        {
            $val = preg_replace($regex,'',$val);
        }
        $search  = array("
 function cleanString($val) { $non_displayables = array( '/%0[0-8bcef]/', # url encoded 00-08, 11, 12, 14, 15 '/%1[0-9a-f]/', # url encoded 16-31 '/[\x00-\x08]/', # 00-08 '/\x0b/', # 11 '/\x0c/', # 12 '/[\x0e-\x1f]/', # 14-31 '/x7F/' # 127 ); foreach ($non_displayables as $regex) { $val = preg_replace($regex,'',$val); } $search = array("\0","\r","\x1a","\t"); return trim(str_replace($search,'',$val)); } 
","\r","\x1a","\t"); return trim(str_replace($search,'',$val)); }

Answer:

I had same issue. For me it was causing by echo "<br/><pre>". I was trying to pass json string to another php file using exit(json_encode(utf8ize($resp_array))); At the beginning of file i had decleared break line tag… So this was error for me. Removing this break line tag , i was able to decoding my json string an other php file..

Answer:

I had same issue. For me it was causing by echo "<br/><pre>".

I was trying to pass json string to another php file using :

exit(json_encode(utf8ize($resp_array)));

At the beginning of file I had decleared break line tag… So this was error for me. Removing this break line tag , I was able to […]