PHP:对象类型转换为数组后出现奇怪的数组行为
PHP: Strange Array Behaviour After Object Type Casting to Array
当您对 json_decode
d 值(使用 $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']));
向 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]->名称...
当您对 json_decode
d 值(使用 $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']));
向 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]->名称...