Вопрос об объекте объекта JSON
Я перехожу от 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>");
Выходной сигнал здесь:
Array ( [0] => a ) a0:
Array ( [0] => b ) b0:b
Я ожидал бы 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>");
Вывод расширенного примера:
array ( '0' => 'a', )a0:
a
array ( 'x' => 'b', )bx:b
array ( 1 => 'c', )c1:c
array ( 0 => 'd', )d0:d
Ответы
Ответ 1
Более подробная информация в этом старом вопросе. Краткая версия состоит в том, что properties на объектах/классах PHP следуют тем же соглашение об именах в качестве переменных. Числовое свойство недопустимо для объекта PHP, поэтому нет четкого правила относительно того, что должно произойти при сериализации объекта с другого языка (json/javascript), который имеет числовой ключ. Хотя вам кажется очевидным, что должно произойти с вышесказанным, кто-то с другим уклоном видит, что поведение PHP в этом случае является совершенно правильным и предпочтительным.
Итак, это своего рода ошибка, но больше области undefined спецификации без четкого ответа, поэтому не ожидайте, что поведение изменится в соответствии с вашими предпочтениями, и если это произойдет, не ожидайте которые изменяются как постоянные.
Чтобы устранить некоторые из проблем в комментариях, рассмотрите этот
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'));
который выведет что-то вроде этого
array(1) {
["0"]=>
string(1) "a"
}
array(1) {
[0]=>
string(1) "a"
}
array(1) {
[0]=>
string(1) "a"
}
Массив с нулевым нулевым ключом не является корректной конструкцией PHP. Если вы попытаетесь создать один PHP, он превратит нуль в int для вас. Когда вы попросите PHP сделать бросок, для которого нет определения, он заканчивает создание массива с помощью строкового ключа (из-за плохо определенных правил вокруг того, что должно произойти здесь).
Хотя наглядно очевидно, что это "неправильное" поведение со стороны PHP, определение правильного поведения на языке, который слабо набрал, непросто.
Ответ 2
Вы можете просто получить доступ к нему как к объекту (stdClass), а не к массиву:
$json = '{"0" : "a"}';
$obj = json_decode($json);
print_r($obj);
echo("a0:".$obj->{"0"}."<br>");
Это наиболее прямолинейно, поскольку ваш JavaScript был объектом ({}
), а не массивом []
для начала.
В качестве альтернативы вы можете сделать это
$arr = json_decode($json, true);
Второй необязательный параметр выводит ассоциативный массив.
http://us.php.net/json_decode
Ответ 3
Зачем ты это делаешь? Вы знаете, что вы можете иметь JSON-декодированные значения в виде массива напрямую?
$arr = json_decode($json, true);
echo '<pre>';
print_r($arr);
echo '</pre>';
Ответ 4
Array ( [0] => a ) a0:
Array ( [0] => b ) b0:b
PHP бесполезные атаки print_r
снова!
Первый массив имеет целочисленный ключ 0
, потому что приведение (array)
пытается превратить его в плоский список-подобный массив.
Во втором массиве сохраняется строковый ключ '0'
с ассоциативным массивом. Вы построили его с помощью.
Используйте var_export
вместо print_r
, и вы можете легко увидеть разницу.
Ответ 5
Ну, проблема существует только тогда, когда исходный объект имеет свойства, которые не разрешены [акамерные числа]. Это не связано с json_encode/decode, но с любой операцией, включающей преобразование из объектов в массив. Все целые ключи будут недоступны.
http://www.php.net/manual/en/language.types.array.php - где указано, что: если объект преобразуется в массив, результатом является массив, элементами которого являются свойства объекта. Ключи - это имена переменных-членов, с несколькими заметными исключениями: целочисленные свойства недоступны; частные переменные имеют имя класса, добавленное к имени переменной; защищенные переменные имеют "*", добавленные к имени переменной. Эти предварительные значения имеют нулевые байты с обеих сторон.