Reputation: 43
I'm receiving a json array from php as the return of curl_exec in PHP (first json PHP -> python, that returns another json), and decode fails due to bad syntax.
The piece of API code:
if($_GET['url'] == 'tomorrowdate'){
$tomorrow = date('Y-m-d', strtotime(' + 1 days'));
$risposta = [
"tomorrow" => $tomorrow
];
echo json_encode($risposta);
http_response_code(200);
}
the curl code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, array('Content-type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
//var_dump($output);
$data = stripslashes($data);
$json_array = json_decode($output, true);
//var_dump(curl_error($ch));
curl_close($ch);
var_dump($json_array);
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;
}
I tried to adapt your code with mine but the problem remains ...
function remove_utf8_bom($text){
$bom = pack('H*','EFBBBF');
$text = preg_replace("/^$bom/", '', $text);
return $text;
}
$tomorrow = date('Y-m-d', strtotime(' + 1 days'));
$risposta = [
"tomorrow" => $tomorrow
];
$json = remove_utf8_bom($risposta);
echo json_encode($json);
var_dump(json_decode($json_encode, TRUE));
The output is:
{"tomorrow":"2018-09-15"}NULL - Syntax error, malformed JSON
Upvotes: 3
Views: 16439
Reputation: 34416
Using the following code I can see there is a non-printable character at the beginning of the JSON:
$json = '{"tomorrow":"2018-09-15"}';
var_dump(json_encode($json));
Returns:
string(37) ""\ufeff{\"tomorrow\":\"2018-09-15\"}""
The string ufeff
is a BOM. To remove it use the following function:
function remove_utf8_bom($text){
$bom = pack('H*','EFBBBF');
$text = preg_replace("/^$bom/", '', $text);
return $text;
}
which returns:
string(31) ""{\"tomorrow\":\"2018-09-15\"}""
Now using all of the code:
function remove_utf8_bom($text)
{
$bom = pack('H*','EFBBBF');
$text = preg_replace("/^$bom/", '', $text);
return $text;
}
$json = remove_utf8_bom('{"tomorrow":"2018-09-15"}');
var_dump(json_encode($json));
print_r(json_decode($json, TRUE));
Which returns:
string(31) ""{\"tomorrow\":\"2018-09-15\"}""
Array
(
[tomorrow] => 2018-09-15
)
##EDIT based on comments:
Change the last the lines of your code:
$json = remove_utf8_bom(json_encode($risposta)); // encode here
//echo json_encode($json); // don't really need this, just a test
var_dump(json_decode($json, TRUE)); // you had $json_encode here
This returns EXAMPLE:
array(1) {
["tomorrow"]=>
string(10) "2018-09-15"
}
Upvotes: 15
Reputation: 883
In my case I was getting this error because of PHP version if your php version is less than or equal to 5.4.0 then you have to send all json key values in quotes
I was sending payload like
$payload = array(
"id" => 36
);
which was failing while decoding json in JWTs decode function I changed to this
$payload = array(
"id" => "36"
);
and it worked!!!
it is because of json_decode in previous PHP version requires values to be given in quotes. This is block of code from JWT.php JWT library
public static function jsonDecode($input)
{
if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
/** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
* to specify that large ints (like Steam Transaction IDs) should be treated as
* strings, rather than the PHP default behaviour of converting them to floats.
*/
$obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
} else {
/** Not all servers will support that, however, so for older versions we must
* manually detect large ints in the JSON string and quote them (thus converting
*them to strings) before decoding, hence the preg_replace() call.
*/
$max_int_length = strlen((string) PHP_INT_MAX) - 1;
$json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
$obj = json_decode($json_without_bigints);
}
if (function_exists('json_last_error') && $errno = json_last_error()) {
static::handleJsonError($errno);
} elseif ($obj === null && $input !== 'null') {
throw new DomainException('Null result with non-null input');
}
return $obj;
}
enter code here
Upvotes: 1