Я преобразовываю из 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
Больше информации есть в этом более старом вопросе. Краткая версия такова: свойства объектов/классов 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'));
что выведет что-то вроде этого
array(1) {
["0"]=>
string(1) "a"
}
array(1) {
[0]=>
string(1) "a"
}
array(1) {
[0]=>
string(1) "a"
}
Массив с единственным строковым ключом ноль не является допустимой конструкцией PHP. Если вы попытаетесь создать такой массив, PHP превратит ноль в int. Когда вы просите PHP сделать приведение, для которого у него нет определения, он в итоге создает массив со строковым ключом (из-за плохо сформулированных правил о том, что здесь должно произойти).
Хотя очевидно, что это "неправильное" поведение со стороны PHP, определить правильное поведение в языке со слабой типизацией не так просто.
Почему вы это делаете? Знаете ли вы, что можно напрямую получить декодированные значения JSON в виде массива?
$arr = json_decode($json, true);
echo '<pre>';
print_r($arr);
echo '</pre>';
Array ( [0] => a ) a0:
Array ( [0] => b ) b0:b
Опять бесполезная атака PHP print_r
!
Первый массив имеет целочисленный ключ 0
, потому что приведение (array)
пытается превратить его в плоский массив, подобный списку.
Второй массив сохраняет строковый ключ в стиле ассоциативного массива '0'
, с помощью которого вы его создали.
Используйте var_export
вместо print_r
, и вы сможете легче увидеть разницу.
Вы можете просто получить доступ к нему как к объекту (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