4

When you do array type-casting of json_decoded value (with $assoc = false), PHP creates an array with string indices:

$a = (array)json_decode('{"7":"value1","8":"value2","9":"value3","13":"value4"}');

var_export($a);

//array (
//  '7' => 'value1',
//  '8' => 'value2',
//  '9' => 'value3',
//  '13' => 'value4',
//)

And for some reason these indices are not accessible:

var_dump(isset($a[7]), isset($a['7']));

//false
//false

When you try to create the same array by PHP itself, it is being created with numeric indices (string are automatically converted), and values are accessible using both strings and numbers:

$c = array('7' => 'value1', '8' => 'value2', '9' => 'value3','10' => 'value4');

var_export($c);

var_dump(isset($c[7]), isset($c['7']));

//array (
//  7 => 'value1',
//  8 => 'value2',
//  9 => 'value3',
//  13 => 'value4',
//)
//
//true
//true

Does anybody know what is going on here? Is it some bug of older PHP versions (the issue seems to be fixed on PHP version >= 7.2, but I can't find anything related in changelog)?

Here's the demo of what is going on: https://3v4l.org/da9CJ.

2
  • @LawrenceCherone please read the question carefully, it fails for older PHP versions (the second output tab on 3v4l.org) Commented Jan 22, 2018 at 10:59
  • Yeah I saw that, sorry. I guess you should be using the second param then and its fine. Commented Jan 22, 2018 at 11:01

3 Answers 3

3

This seems to be related to bug #61655 fixed in 7.2.0:

in a object property lookup by name always in string, but in array numeric string(like "22200" ) key will transform to numeric but not a string anymore. when conversion internal HashTable did't changed so after conversion, key lookup will fail.

Clarified: $a["2000"] is always interpreted as $a[2000], but (array) failed to cast object string keys to numbers. So the array contained string numeric indices, but the array syntax' automatic casting prevented those from being accessible.

Sign up to request clarification or add additional context in comments.

3 Comments

Indeed! Thanks, I looked for something related to "json_decode", not for generic type-casting.
@GinoPane i will recomend you to always use true when you need type casting. Check once my answer as two different version are working perfectly fine.
@AlivetoDie, thanks! Actually, I do use it (you can check my demo link and see the test-case with true passed). The reason for the question was, that I faced json_decode usage without second parameter and couldn't explain the magic with array indices.
0

add TRUE to json_decode()

<?php
$a = json_decode('{"7":"value1","8":"value2","9":"value3","13":"value4"}',TRUE);

var_export($a);

var_dump(isset($a[7]), isset($a['7']));

https://3v4l.org/YuF9B

Comments

0

add TRUE to json_decode() is possible, but it will couse to recode everything.

Becouse you have to change the access to the variables.

if your json look like this:

$return = '{"status":"ok","message":"","code":"200","data":{"1234":{"sid":1,"name":"foo"},"4321":{"sid":2,"name":"bar"}}}';

on:

$json_data = json_decode($return, true);
$data = $json_data['data'];

you can loop the $data and have to access the values as array: $data[0]['name'] ...

on:

$json_data = json_decode($return);
$data = (array) $json_data->data;

you can loop the $data and have to access the values as objects: $data[0]->name ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.