Короткий ответ
Array
типа литья из Object
doesn't work with integer properties (as strings
i.e. "139").
Длинный ответ
Пучок тестирования кода:
<pre>
<?php
$arr = array("139" => "some_data", "test" => "other_data");
$good = (object) $arr;
$good_arr = (array) $good;
$bad = json_decode(json_encode($arr));
$bad_arr = (array)($bad);
var_dump ($arr);
foreach ($arr as $k => $v)
var_dump (gettype ($k)); // 139 is integer
var_dump ($good);
foreach ($good as $k => $v)
var_dump (gettype ($k)); // 139 is integer
var_dump ($good_arr);
foreach ($good_arr as $k => $v)
var_dump (gettype ($k)); // 139 is integer
var_dump ($bad);
foreach ($bad as $k => $v)
var_dump (gettype ($k)); // 139 is string
var_dump ($bad_arr);
foreach ($bad_arr as $k => $v)
var_dump (gettype ($k)); // 139 is string
var_dump ($arr[139]); // string(9) "some_data"
var_dump ($arr["139"]); // string(9) "some_data"
var_dump ($arr["test"]); // string(10) "other_data"
var_dump ($good->{139}); // NULL
var_dump ($good->{"139"}); // NULL
var_dump ($good->{"test"}); // string(10) "other_data"
var_dump ($good_arr[139]); // string(9) "some_data"
var_dump ($good_arr["139"]); // string(9) "some_data"
var_dump ($good_arr["test"]); // string(10) "other_data"
var_dump ($bad->{139}); // string(9) "some_data"
var_dump ($bad->{"139"}); // string(9) "some_data"
var_dump ($bad->{"test"}); // string(10) "other_data"
var_dump ($bad_arr[139]); // NULL
var_dump ($bad_arr["139"]); // NULL
var_dump ($bad_arr["test"]); // string(10) "other_data"
?>
</pre>
bin2hex
фактически показывает точно такое же значение, и foreach
работает нормально.
Так как же возможно, что он не работает, когда мы пытаемся получить к нему доступ напрямую?
И как странно, что последнее показывает хорошо?
Ну, на самом деле, я получил ответ на второй вопрос от этого part from the doc talking about array type casting Как вы можете видеть, при преобразовании объекта в массив с отливкой типа, это не работает для числовых свойств, которые позволяют недоступны.
Для первого вопроса я предполагаю, что тип cast не изменяет способ представления данных в памяти, так что он все равно может перебирать его, как если бы это был объект.
Следующая лишь мои предположения о различиях между двумя сценариями:
В хорошем сценарии
PHP
обрабатывает материал, все сам.Ключ массива типа string
, представляющий integer
, автоматически преобразуется в integer
.
Тогда нет проблем, когда мы его конвертируем, оно становится собственностью (с integer
) объекта $good
, хотя оно недоступно (потому что оно пытается достичь свойства "139"
, а не 139
). (NULL
)
Когда мы произведем преобразование в массив $good_arr
, структура данных не изменилась, и мы все еще можем получить к нему доступ, поскольку он достигает 139
, а не "139"
.
В плохом сценарии
Здесь объект регенерируют json_decode
. Эта функция не генерирует плохие объекты (и это хорошо!), Поэтому все свойства будут иметь тип string
.
Вот почему мы можем получить доступ к собственности непосредственно от объекта здесь. Это действительное свойство (тип string
), поэтому мы можем получить к нему доступ.
Но, как сказано в документах, когда мы возвращаем его обратно в array
, структура данных не изменилась, поэтому мы не можем получить к ней доступ. Либо мы напишем $bad_arr[139]
, либо $bad_arr["139"]
попытается получить доступ к значению с помощью ключа 139
(NULL
), когда он действительно должен получить доступ к "139"
.
Заключение
Это типичный пример магии PHP
«s. Преобразование string
s в int
автоматически в массивах является причиной вашей проблемы.
Так что ваше решение с использованием assoc
параметров из json_decode
, кажется, только один, который будет работать здесь:
json_decode($json_arr, true);
Это странно, что вы получите 'строку (5)' для '«my_data»' – Ryan
Try 'var_dump (bin2hex ($ my_key), bin2hex (ключ ($ bad_array)))' и посмотреть, что вы получаете. – deceze
Пожалуйста, разместите свой код, который строит массив. – Dai