3

I wrote an API for a friend's wordpress site that relies on the JSON API plugin to get a JSON feed of her recent posts. It worked flawlessly for months, but a few days ago, stopped working entirely just when her shared host made the switch over to PHP 5.3 (of course, they did not alert their users-- why should they?)

I dug around and found a strange error in the part of the code that takes a JSON string, and returns the decoded JSON object to another function. Previously, the code (which worked, I SWEAR!) worked like this:

    $json_string = file_get_contents($url_to_json_string);
    return json_decode($json_string);

This began to return NULL, and json_last_error was 4 (syntax error.) I checked the utf8_encoding: fine. I checked for BOM-strangeness (according to this post): fine. I validated the JSON string in jsonlint.com and in json.parser.online.fr and it was perfectly valid. No stray htmlentities, no wandering slashes. The JSON string itself was fine and should have validated.

Then, I changed the code to this:

    $json_string = file_get_contents($url_to_json_string);
    $json_object = json_decode($json_string);
    return $json_object;

and it worked.

Does anyone know why this happened?

Community
  • 1
  • 1
Harlo Holmes
  • 5,145
  • 1
  • 23
  • 20
  • Can you provide the JSON which can not be parsed? – Sergey Eremin Jun 29 '12 at 19:26
  • sure... it's kind of too long to post here, but this is an example that you can copy/paste yourself: http://tomtommag.com/?json=get_category_posts&count=1&category_id=105 – Harlo Holmes Jun 29 '12 at 19:31
  • It may be something as simple as a change in the config to not allow urls to open from fopen. Check phpinfo. – MetalFrog Jun 29 '12 at 19:34
  • @MetalFrog i thought that was the error, too, at first. but config did allow allow_url_open. – Harlo Holmes Jun 29 '12 at 19:38
  • @HarloHolmes Oh well, it'd have been nice if that was the case! I hate when things (seemingly) randomly break. – MetalFrog Jun 29 '12 at 19:40
  • Check the return value of that function. It can return NULL in two cases: On error or when the json was just NULL. For the error case, you need to call a function then to find out a) if it was an error and b) which one. do the error checking and logging(!) so next time this happens you have *more* information. PHP tells you if there was a syntax problem with json. – hakre Jun 30 '12 at 22:50
  • @hakre unfortunately, my error logs only point to the cascade of failure stemming from using an object that does not exist (ie "Trying to get property of non-object" and "Cannot use object of type stdClass as array") which are only thrown when the JSON string fails to resolve (thus resulting JSON object is null.) My log shows no other errors. As stated in the original post, json_last_error was 4. Are there any other places I should look for errors that might shed more light on this? – Harlo Holmes Jul 03 '12 at 13:18
  • `json_decode` with `json_last_error()` being 4 (most likely that is `JSON_ERROR_SYNTAX`) tells you that this is not valid json. So this is merely about proper error handling I'd say. Are you familiar with the concept of defensive programming? – hakre Jul 03 '12 at 14:35
  • @hakre not explicitly, but it seems like you're saying I shouldn't count on the JSON string being 100% valid in the first place, and that I can hedge against that by applying some preemptive regex or something similar? – Harlo Holmes Jul 03 '12 at 15:41

3 Answers3

4

The non printable characters must be in JSON string. Use below:

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string);, true );
dloewen
  • 975
  • 1
  • 10
  • 26
user764806
  • 41
  • 2
  • you have needless semicolon, correct syntax "json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );" – Ivan Hanák Sep 03 '15 at 08:36
3

These links might be applicable:

PS:

I just ran your snippet through a couple of validators: I did not see anything wrong ... but you might:

Community
  • 1
  • 1
paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • thanks, @paulsm4 for the link to functions-online-- i didn't know that one before! but you and i are right, and so are the validators: the problem doesn't appear to be with the JSON string itself. and, once i got it working again, there was no need to reformat the string with regex or anything. so i'm still stumped! – Harlo Holmes Jun 29 '12 at 19:40
0

There is general bug in jsonDecode where "id":"google:1111111111111111111111111111111111111" is translated to "id:"google:"11111111111111111111111111"" which leads to syntax error.

To fix it the line must be: $json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);

(it must be : in regular expression in the front).