Вопрос преобразования объекта JSON - PullRequest
10 голосов
/ 18 мая 2010

Я конвертирую из 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 

Ответы [ 5 ]

4 голосов
/ 18 мая 2010

Больше информации в этом старом вопросе . Короткая версия состоит в том, что свойства для объектов / классов 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, определить правильное поведение в языке, который слабо типизирован, непросто.

1 голос
/ 17 января 2011

Ну, проблема существует только тогда, когда исходный объект имеет свойства, которые не разрешены [также известные как числовые свойства].Это связано не с json_encode / decode, а с любой операцией, включающей преобразование объектов в массив.Все целочисленные ключи будут сделаны недоступными.

http://www.php.net/manual/en/language.types.array.php - где указано, что: Если объект преобразуется в массив, результатом является массив, элементы которого являются свойствами объекта.Ключи являются именами переменных-членов, с несколькими заметными исключениями: целочисленные свойства недоступны;закрытые переменные имеют имя класса, добавленное к имени переменной;Защищенные переменные имеют «*» перед именем переменной.Эти предварительно добавленные значения имеют нулевые байты с каждой стороны.

1 голос
/ 18 мая 2010
Array ( [0] => a ) a0:
Array ( [0] => b ) b0:b

PHP бесполезные print_r атаки снова!

Первый массив имеет целочисленный ключ 0, потому что приведение (array) пытается превратить его в плоский массив, подобный списку.

Второй массив сохраняет строковый ключ в стиле ассоциативного массива '0', с которым вы его построили.

Используйте var_export вместо print_r, и вы сможете легче увидеть разницу.

1 голос
/ 18 мая 2010

Почему ты это делаешь? Знаете ли вы, что вы можете иметь JSON-декодированные значения в виде массива напрямую?

<code>$arr = json_decode($json, true);

echo '<pre>';
print_r($arr);
echo '
';
1 голос
/ 18 мая 2010

Вы можете просто получить к нему доступ как к объекту (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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...