PHP json_encode as object after PHP array unset()
I’m experiencing odd behavior with json_encode
after removing a numeric array key with unset
. The following code should make the problem clear. I’ve run it from both the CLI and as an Apache mod:
PHP version info:
C:\Users\usr\Desktop>php -v
PHP 5.3.1 (cli) (built: Nov 20 2009 17:26:32)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies
PHP Code
<?php
$a = array(
new stdclass,
new stdclass,
new stdclass
);
$a[0]->abc="123";
$a[1]->jkl="234";
$a[2]->nmo = '567';
printf("%s\n", json_encode($a));
unset($a[1]);
printf("%s\n", json_encode($a));
Program Output
C:\Users\usr\Desktop>php test.php
[{"abc":"123"},{"jkl":"234"},{"nmo":"567"}]
{"0":{"abc":"123"},"2":{"nmo":"567"}}
As you can see, the first time $a
is converted to JSON it’s encoded as a javascript array. The second time around (after the unset
call) $a
is encoded as a javascript object. Why is this and how can I prevent it?
The reason for that is that your array has a hole in it: it has the indices 0 and 2, but misses 1. JSON can’t encode arrays with holes because the array syntax has no support for indices.
You can encode array_values($a)
instead, which will return a reindexed array.
In addition to the array_values
technique it is possible to use array_splice
and remove an element and re-index in one step:
unset($a[1]);
Instead:
array_splice($a, 1, 1);
Try to use JSON_FORCE_OBJECT option for json_encode, like: json_encode($a, JSON_FORCE_OBJECT)
so you will always have the same result.