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 "
- SYNTAX ERROR
";
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)
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.
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);
?>
I solved this issue adding stripslashes to the string, before json_decode.
$data = stripslashes($data);
$obj = json_decode($data);
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!!
use BOM Cleaner if you have lot's of files to fix.
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..
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;
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 [...]
After trying all the solution without the result this is the one worked for me.
Hope it will help someone
$data = str_replace('"', '"', $data);
I had the same issues. I took the following steps:
changed the JSON text encoding
$json = utf8_encode($json);
I then viewed the plain text before decoding. I found crazy symbols like
ï
then I just stripped it off
$json = str_replace(array('ï',''), '',$json);
and I successfully decoded my JSON
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);
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.