PHP:对象类型转换为数组后出现奇怪的数组行为

PHP: Strange Array Behaviour After Object Type Casting to Array

当您对 json_decoded 值(使用 $assoc = false)进行 array 类型转换时,PHP 创建一个包含字符串索引的数组:

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

var_export($a);

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

并且由于某些原因无法访问这些索引:

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

//false
//false

当您尝试通过 PHP 本身创建相同的数组时,它是使用数字索引创建的(字符串会自动转换),并且可以使用字符串和数字访问值:

$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

有人知道这里发生了什么吗?是否是旧 PHP 版本的一些错误(问题似乎已在 PHP 版本 >= 7.2 上修复,但我在 changelog 中找不到任何相关内容)?

这是正在发生的事情的演示:https://3v4l.org/da9CJ

这似乎与 7.2.0 中修复的 bug #61655 有关:

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.

澄清:$a["2000"] 始终被解释为 $a[2000],但 (array) 无法将对象字符串键转换为数字。因此数组包含字符串数字索引,但数组语法的自动转换阻止了这些索引的访问。

TRUE 添加到 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

向 json_decode() 添加 TRUE 是可能的,但它会导致重新编码所有内容。

因为您必须更改对变量的访问权限。

如果您的 json 看起来像这样:

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

于:

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

您可以循环 $data 并且必须访问数组形式的值: $数据[0]['name'] ...

在:

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

您可以循环 $data 并且必须将值作为对象访问: $数据[0]->名称...