I have a PHP array that has numeric keys as a string type.
But when I try and access them PHP is giving me an undefined index error.
$a = (array)json_decode('{"1":1,"2":2}');
var_dump($a);
var_dump(isset($a[1]));
var_dump(isset($a["1"]));
var_dump($a[1]);
var_dump($a["1"]);
Output:
array (size=2) '1' => int 1 '2' => int 2 boolean false boolean false ERROR: E_NOTICE: Undefined offset: 1 null ERROR: E_NOTICE: Undefined offset: 1 null
How do I access these values?
Demo: http://codepad.viper-7.com/8O03IM
So, I haven’t seen any other answers touch upon this, but @xdazz came close.
Let’s start our environment, $obj
equals the object notation of a decoded string:
php > $obj = json_decode('{"1":1,"2":2}');
php > print_r($obj);
stdClass Object
(
[1] => 1
[2] => 2
)
php > var_dump( $obj );
object(stdClass)#1 (2) {
["1"]=>
int(1)
["2"]=>
int(2)
}
If you want to access the strings, we know the following will fail:
php > echo $obj->1;
Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `'{'' or `'$'' in php shell code on line 1
Accessing the object variables
You can access it like so:
php > echo $obj->{1};
1
Which is the same as saying:
php > echo $obj->{'1'};
1
Accessing the array variables
The issue with arrays is that the following return blank, which is the issue with typecasting.
php > echo $obj[1];
php >
If you typecast it back, the object is once again accessible:
php > $obj = (object) $obj;
php > echo $obj->{1};
1
Here is a function which will automate the above for you:
function array_key($array, $key){
$obj = (object) $array;
return $obj->{$key};
}
Example usage:
php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1
php > echo array_key($obj, 2);
2
Answer:
If you want array, set the second parameter of json_decode to true
.
$a = json_decode('{"1":1,"2":2}', true);
Edit:
when you cast a std object to array, numeric string key doesn’t cast to number.
Here is an example.
$obj = new stdClass;
$obj->{'1'} = 1;
$arr = (array) $obj;
var_dump($arr);
var_dump(isset($arr[1]));
Answer:
Apparently, this is a known issue, and there are no plans to fix it; see Doc Bug #45959 Object to array conversion leads to weird behaviour:
Fixing that implies a perfomance decrease, hence the better seems be keep it as an known issue, but documented.
This wonkiness is (then) noted in the documentation for the array type (emphasis mine):
If an object is converted to an array, the result is an array whose elements are the object’s properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible…. This can result in some unexpected behaviour….
Answer:
Yes. I do agree, PHP has issue with typecasting from object to array but foreach is handling intelligently the object or associative array.
$a = json_decode('{"1":1,"2":2}'); //need not typecast but doesnt break even if u typecast
foreach ($a as $k=>$v){
echo $v;
}
Answer:
I met the same problem recently.
$obj = new stdClass();
$obj->{'0'} = "test";
$array = (array)$obj;
foreach ($array as $key => $value) {
$array[$key] = strtoupper($value);
}
var_dump($array);
This code outputs :
array(2) {
["0"]=>
string(4) "test"
[0]=>
string(4) "TEST"
}
Found that when debugging a method to convert recursivly objects to array, I’ve been mad.
Answer:
I had the same problem (but with array_intersect_key).
Here is my solution:
$array = array_combine(array_keys($array), $array);