3

I try to load and parse JSON file from this link

But I have JSON_ERROR_SYNTAX problem and Invalid argument supplied for foreach(). Why it's happen?

[{ "Manufacturer": "Toyota", "Sold": 1200, "Month": "2012-11" }, { "Manufacturer": "Ford", "Sold": 1100, "Month": "2012-11" }, { "Manufacturer": "BMW", "Sold": 900, "Month": "2012-11" }, { "Manufacturer": "Benz", "Sold": 600, "Month": "2012-11" }, { "Manufacturer": "GMC", "Sold": 500, "Month": "2012-11" }, { "Manufacturer": "HUMMER", "Sold": 120, "Month": "2012-11" }]

<?php
$url = "http://www.pureexample.com/backend/data/car-sale.json";
$url = file_get_contents($url);
print_r($url);
$url = stripslashes($url);
print_r($url);
$url = str_replace("\n", "", $url);
print_r($url);
$url = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($url));
print_r($url);
$url = json_decode($url, true);
// Add this switch to your code
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;
}


foreach($koyim as $data){
echo $data['Manufacturer'];
echo $data['Sold'];
echo $data['Month'];
echo "<br/>";
}
?>
voloshin
  • 536
  • 7
  • 17
NormalArs
  • 101
  • 2
  • 11
  • 2
    Why do you use `stripslashes()`, `str_replace()`, `iconv()` and `utf8_encode()` before `json_decode()` ? – Eduardo Escobar Sep 21 '17 at 18:58
  • the url (before your transformations) is valid json. You know where to look now :) – YvesLeBorg Sep 21 '17 at 19:01
  • Using json_last_error() can be userfull if your apache server serve only one website, but it can be disgracefully if you got errors from other errors generated by other web site, this function trigger the last errors from the last call to the function json_encode or json_decode. –  Sep 21 '17 at 19:09
  • json not valid everywhere! – NormalArs Sep 21 '17 at 19:12

1 Answers1

7

The link you provided serves the JSON in UTF-8 with a Byte Order Mark. Apparently json_decode() does not deal well with these three extraneous characters. The solution would be to strip the BOM:

<?php

//see https://stackoverflow.com/a/32185872/500890
function removeBomUtf8($s){
   if(substr($s,0,3)==chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF'))){
        return substr($s,3);
    }else{
        return $s;
    }
}

$url = "http://www.pureexample.com/backend/data/car-sale.json";
$content = file_get_contents($url);
$clean_content = removeBomUtf8($content);
$decoded = json_decode($clean_content);

//Recovered data
echo "<pre>" . print_r($decoded, TRUE);

I took this solution to strip the BOM: https://stackoverflow.com/a/32185872/500890, although there are a ton of them floating on the Internet. The main idea is to strip the first three specific characters if they are indeed a BOM.

lampyridae
  • 949
  • 1
  • 8
  • 21
  • 1
    Nice catch, I was debugging this with a test script as you posted it, I was seeing the same behavior as OP. This does indeed fix the problem. Nice find! – rickdenhaan Sep 21 '17 at 19:23