Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when does php json_decode return false?

Tags:

json

php

In the PHP documentation for json_decode it says it can return TRUE,FALSE,NULL.

Could some help me understand when it would return FALSE? I understand invalid JSON will return NULL, but when would the other two be returned if not the actual JSON value?

Thanks

like image 314
d-_-b Avatar asked Oct 27 '13 23:10

d-_-b


1 Answers

JSON format definition clearly shows all possible values and their representations:

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array.

Both objects and arrays have special syntax in JSON representation (wrapped in {} and [] respectively), so they can't be mixed up with false in any case. The same goes with string - it's wrapped in "" (double quotation marks). As for Numbers, they have to contain at least one digit - so cannot be confused with false (and true and null) too.

So that leaves us with the only case: when json_encode processes an object having redefined its JSON representation. For example (PHP 5.4+):

class FalsyFoo implements JsonSerializable {
  public $foo;

  public function __construct($f) {
    $this->foo = $f;
  }

  public function jsonSerialize() {  
    return false; 
  }
}

$f = new FalsyFoo(true);
$fj = json_encode($f);
var_dump( $fj ); // string(5) 'false'
var_dump( json_decode($fj) ); // bool(false)

Technically, we still work with false value here, but the source is obviously different.


If you're still not convinced, check the source code of json_decode, which calls php_json_decode_ex after checking the arguments. This, in turn, calls parse_JSON_ex first, which operates over the predefined state transition table; the latter has only one set of states leading to false value as result. If this call fails somehow, value is checked directly:

if (str_len == 4) {
  if (!strcasecmp(str, "null")) {
    /* We need to explicitly clear the error 
         because its an actual NULL and not an error */
    jp->error_code = PHP_JSON_ERROR_NONE;
    RETVAL_NULL();
  } else if (!strcasecmp(str, "true")) {
    RETVAL_BOOL(1);
  }
} else if (str_len == 5 && !strcasecmp(str, "false")) {
  RETVAL_BOOL(0);
}

... and that's the only case when return_value is set to boolean.

like image 164
raina77ow Avatar answered Oct 04 '22 13:10

raina77ow