JSON对象转换问题

use*_*021 10 php json type-conversion

我正在从JSON转换为对象,从对象转换为数组.它不符合我的预期,你能解释一下吗?

$json = '{"0" : "a"}';
$obj = json_decode($json);
$a = (array) $obj;
print_r($a);
echo("a0:".$a["0"]."<br>");

$b = array("0" => "b");
print_r($b);
echo("b0:".$b["0"]."<br>");
Run Code Online (Sandbox Code Playgroud)

这里的输出是:

Array ( [0] => a ) a0:
Array ( [0] => b ) b0:b
Run Code Online (Sandbox Code Playgroud)

我原以为a0:a在第一行的末尾.

编辑:在阅读答案后,我扩展了代码,这使得行为更加清晰:

//extended example
$json = '{"0" : "a"}';
$obj = json_decode($json);
$a = (array) $obj;
var_export($a);
echo("a0:".$a["0"]."<br>"); //this line does not work, see the answers
echo $obj->{"0"}."<br>";  //works!

$json = '{"x" : "b"}';
$obj = json_decode($json);
$b = (array) $obj;
var_export($b);
echo("bx:".$b["x"]."<br>");

$c = array("1" => "c");
var_export($c);
echo("c1:".$c["1"]."<br>");

$d = array("0" => "d");
var_export($d);
echo("d0:".$d["0"]."<br>");
Run Code Online (Sandbox Code Playgroud)

扩展示例的输出:

array ( '0' => 'a', )a0:
a
array ( 'x' => 'b', )bx:b
array ( 1 => 'c', )c1:c
array ( 0 => 'd', )d0:d 
Run Code Online (Sandbox Code Playgroud)

Ala*_*orm 4

这个较旧的问题中有更多信息。简而言之,PHP 对象/类的属性遵循与变量相同的命名约定。数字属性在 PHP 对象上无效,因此对于从具有数字键的另一种语言 (json/javascript) 序列化对象时应该发生什么,没有明确的规则。虽然上面的情况对您来说似乎很明显应该发生什么,但具有不同偏见的人认为 PHP 在这种情况下的行为是完全有效和首选的。

所以,这是一个错误,但更多的是规范中未定义的区域,没有明确的答案,所以不要指望行为会改变以满足您的喜好,如果它确实改变,也不要指望这种改变是永久性的。

为了解决评论中的一些问题,请考虑这个

header('Content-Type: text/plain');
$json = '{"0" : "a"}';
$obj = json_decode($json);
$a = (array) $obj;
var_dump($a);
var_dump(array(0=>'a'));
var_dump(array('0'=>'a'));
Run Code Online (Sandbox Code Playgroud)

会输出类似这样的内容

array(1) {
  ["0"]=>
  string(1) "a"
}
array(1) {
  [0]=>
  string(1) "a"
}
array(1) {
  [0]=>
  string(1) "a"
}
Run Code Online (Sandbox Code Playgroud)

具有单个字符串键零的数组不是有效的 PHP 构造。如果您尝试创建一个 PHP 会为您将零转换为 int。当您要求 PHP 进行强制转换时,它没有定义,最终会创建一个带有字符串键的数组(因为这里应该发生的情况定义不正确)。

虽然很明显这是 PHP 的“错误”行为,但在弱类型语言中定义正确的行为并不容易。