ID: 45989 Updated by: [EMAIL PROTECTED] Reported By: steven at acko dot net Status: Assigned Bug Type: JSON related Operating System: Mac OS X PHP Version: 5.2.6 Assigned To: magicaltux New Comment:
Just a note for documentation: http://docs.php.net/json_decode Right now the documentation says the function returns an object, OR an array. This is not strictly true as it may return a string, a boolean, an integer, a double... depending on the input. Also, the fact json_decode() may return NULL on error isn't explicitly documented either, instead some examples which happens to return NULL with the current implementation are provided. I think it would be a good idea to explicitly document this behavior, if the change I'm proposing here is accepted. Previous Comments: ------------------------------------------------------------------------ [2008-12-03 21:10:50] [EMAIL PROTECTED] Ok guys, I've had a look at the CVS history for json, and checked why it was following this weird behaviour (returning what was passed in some cases, and NULL in other cases). The CVS commit log message for this relates to bug #38680, however it seems that the behaviour in parsing strings not handled by json is doing too much to try to "fix" things and find a way to provide parsed value. Anyway here's a patch that changes this behaviour to make json_decode() return NULL when we get invalid JSON data, while still keeping null, true, false and integers parsing. Some tests were fixed (the result depended on broken behaviour), and the other tests still run fine. The patch itself, against PHP_5_2: http://ookoo.org/svn/snip/php_5_2-json-returntype-final-fix.patch If nobody can find anything against this (being a bit more strict with obviously wrong values) I'll add patchs against HEAD and PHP_5_3. ------------------------------------------------------------------------ [2008-12-02 18:52:36] steven at acko dot net till said: "but it's supposed to return the string as is -- in case it's a literal type, but why does it in some cases return "null" then?" What argument is there for having (some) unparseable sequences returned as is? If json_decode() returns a string, then that should mean that the input was a valid JSON encoding of that string, no? The only literal types JSON allows are numbers and the pre-defined constants 'true' 'false' and 'null'. Strings must be quote-delimited. The fact that you can switch between 'return NULL' and 'return the argument as-is' just by adding/removing a leading space is a pretty big sign that something is wrong here. To be honest, it seems a bit silly that this is even an argument. ------------------------------------------------------------------------ [2008-12-01 17:16:06] [EMAIL PROTECTED] Just to add to this: I know that the function is not supposed to be a JSON validator, but it's supposed to return the string as is -- in case it's a literal type, but why does it in some cases return "null" then? For example: $bad_json = "{ 'bar': 'baz' }"; json_decode($bad_json); // null I know this is "probably" an edge-case but $bad_json could be my own /valid/ string -- not valid JSON. Because a string could look like anything. Point well taken, I'm passing in a pretty /funky/ looking string. But instead of "NULL", json_decode should return the string as-is. That is, according to the documentation, a bug. ;-) Lots of people also seemed to rely on json_decode as a json validator. Which is -- once you understand the subtle differences -- not the case. The case should be made for either one though. ------------------------------------------------------------------------ [2008-11-17 15:23:35] [EMAIL PROTECTED] @Iliaa: Could this bug be re-evaluated or a more detailed explaination as of why the docs sometimes note that "NULL" is returned on invalid json, and why sometimes json_decode() returns the string instead? If the function returns "whatever" then the docs should be updated to tell the user to not rely on what is returned by json_decode at all. ;-) I double-checked some of Steve's examples on jsonlint.com (which is in most docs cited as the reference validator for json data) and they all show up as "invalid". I also build the most recent 5.2.7 snapshot: ./configure --disable-all --enable-json [EMAIL PROTECTED]:~/php5.2-200811171330$ ./sapi/cli/php test-45989.php string(14) "'invalid json'" string(12) "invalid json" string(2) " {" string(2) " [" [EMAIL PROTECTED]:~/php5.2-200811171330$ ./sapi/cli/php --ini Configuration File (php.ini) Path: /usr/local/lib Loaded Configuration File: (none) Scan for additional .ini files in: (none) Additional .ini files parsed: (none) [EMAIL PROTECTED]:~/php5.2-200811171330$ ./sapi/cli/php -m [PHP Modules] date json Reflection standard [Zend Modules] I'm gonna write a test and send it to QA too. ------------------------------------------------------------------------ [2008-09-10 01:14:23] steven at acko dot net Please clarify the bogus classification. The following each returns NULL, as expected: var_dump(json_decode('[')); // unmatched bracket var_dump(json_decode('{')); // unmatched brace var_dump(json_decode('{}}')); // unmatched brace var_dump(json_decode('{error error}')); // invalid object key/value notation var_dump(json_decode('["\"]')); // unclosed string var_dump(json_decode('[" \x "]')); // invalid escape code Yet the following each returns the literal argument as a string: var_dump(json_decode(' [')); var_dump(json_decode(' {')); var_dump(json_decode(' {}}')); var_dump(json_decode(' {error error}')); var_dump(json_decode('"\"')); var_dump(json_decode('" \x "')); Please examine the examples closely: they are all meaningless, invalid JSON. Even under the most widely stretched definition of JSON, the above is not JSON encoded data. Yet json_decode() arbitarily returns /some of it/ as a string... and in a way that looks suspiciously like a bad parser implementation. If this was merely a case of json_decode() returning /all/ invalid json as is, then it could be classified as an implementation quirk. But because of how inconsistent it is now, you can't say that it is by design or following any kind of spec. E.g. how would you currently see if json_decode() succeeded or not? ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/45989 -- Edit this bug report at http://bugs.php.net/?id=45989&edit=1