Decode sparse json object to php array
Asked Answered
G

3

22

I can create a sparse php array (or map) using the command:

$myarray = array(10=>'hi','test20'=>'howdy');

I want to serialize/deserialize this as JSON. I can serialize it using the command:

$json = json_encode($myarray);

which results in the string {"10":"hi","test20":"howdy"}. However, when I deserialize this and cast it to an array using the command:

$mynewarray = (array)json_decode($json);

I seem to lose any mappings with keys which were not valid php identifiers. That is, mynewarray has mapping 'test20'=>'howdy', but not 10=>'hi' nor '10'=>'hi'.

Is there a way to preserve the numerical keys in a php map when converting to and back from json using the standard json_encode / json_decode functions?

(I am using PHP Version 5.2.10-2ubuntu6.4.)

Gilly answered 20/3, 2010 at 20:48 Comment(0)
L
47

json_decode returns an object of type stdClass by default. You access members as properties (i.e., $result->test20). 10 isn't a valid name for a property, which is why you're losing it.

Instead of casting to an array, you can pass true as a second argument to json_decode to make it return an associative array itself:

$mynewarray = json_decode($json, true);

If you do that, $mynewarray[10] will work fine.

Lanell answered 20/3, 2010 at 20:58 Comment(2)
true is important, to make in PHP Array type, else stdClass ObjectLucrece
omg, thank man, it just blowed my brain. I dumped array, saw the key, but could not access to val by it.Brod
E
2

What version of PHP? On 5.2 the following program/script

$myarray = array(10=>'hi','test20'=>'howdy');
$json = json_encode($myarray);
$mynewarray = (array) json_decode($json);
var_dump($mynewarray);

Outputs

array(2) {
  ["10"]=>
  string(2) "hi"
  ["test20"]=>
  string(5) "howdy"
}

Which doesn't display the behavior you're describing.

That said, if your version of PHP is miscasting the JSON, try using get_object_vars on the stdClass object that json_decode returns

get_object_vars(json_decode($json))

That might return better results.

Edaedacious answered 20/3, 2010 at 20:59 Comment(2)
it has "10" index which can't be accessed through [] operator in PHPInflation
Ah, got it, it serialize the key as a string that happens to be a number, which you can't get at. The get_object_vars solution should solves that, as well as the second parameter of json_decode, mentioned above.Edaedacious
I
2

The problem is in the conversion from object to array.

$a = (array)json_decode('{"10":"hi","test20":"howdy"}');
var_dump($a);

//outputs
array(2) {
  ["10"]=>
     string(2) "hi"
  ["test20"]=>
     string(5) "howdy"
}

See how this array have index "10"? But in PHP, everything that looks like a number gets converted into a number, especially in array indexes. You can't just get a["10"] because it converts "10" into a number and this array does not have such an index.

However, foreach works.

foreach ($a as $key => $value) {
   var_dump($key);
   var_dump($value);
}

//outputs
string(2) "10"
string(2) "hi"
string(6) "test20"
string(5) "howdy"

You can also treat result of json_decode as an object. While you won't be able to do $a->10 or $a->"10",

$a = json_decode('{"10":"hi","test20":"howdy"}');
$b = 10;
var_dump($a->$b);

//outputs
string(2) "hi"

works.

But most likely, as Chris said, you just want to pass true as a second argument.

$a = json_decode('{"10":"hi","test20":"howdy"}', true);
var_dump($a[10]);

//outputs
string(2) "hi"
Inflation answered 20/3, 2010 at 21:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.