arnorhs arnorhs - 1 year ago 44
PHP Question

Weird behavior of matching array keys after json_decode()

I've got some very weird behavior in my PHP code. I don't know if this is actually a good SO question, since it almost looks like a bug in PHP. I had this problem in a project of mine and isolated the problem:

// json object that will be converted into an array
$json = '{"5":"88"}';
$jsonvar = (array) json_decode($json); // notice: Casting to an array
// Displaying the array:
var_dump($jsonvar);
// Testing if the key is there
var_dump(isset($jsonvar["5"]));
var_dump(isset($jsonvar[5]));


That code outputs the following:

array(1) {
["5"]=>
string(2) "88"
}
bool(false)
bool(false)


The big problem: Both of those tests should produce bool(true) - if you create the same array using regular php arrays, this is what you'll see:

// Let's create a similar PHP array in a regular manner:
$phparr = array("5" => "88");
// Displaying the array:
var_dump($phparr);
// Testing if the key is there
var_dump(isset($phparr["5"]));
var_dump(isset($phparr[5]));


The output of that:

array(1) {
[5]=>
string(2) "88"
}
bool(true)
bool(true)


So this doesn't really make sense. I've tested this on two different installations of PHP/apache.

You can copy-paste the code to a php file yourself to test it.

It must have something to do with the casting from an object to an array.

Answer Source

It can be further simplified to this problem

$o = new stdClass;
$o->{5} = 1; //or even $o->{'5'} = 1;
$a = (array) $o;
print_r($a); // Array([5] => 1)
var_dump(isset($a[5])); // false
var_dump(isset($a['5'])); // false

It seems that this only happens when the property name is one that php would normally consider a numeric key in an array.

Definitely unexpected behavior to me.


edit Same issue here Casting an Array with Numeric Keys as an Object


edit#2 documented behavior http://www.php.net/manual/en/language.types.array.php#language.types.array.casting