PHP-массив с числовыми ключами как строка не может использоваться
У меня есть массив PHP, который имеет числовые ключи как строковый тип.
Но когда я пытаюсь получить к ним доступ, PHP дает мне ошибку индекса undefined.
$a = (array)json_decode('{"1":1,"2":2}');
var_dump($a);
var_dump(isset($a[1]));
var_dump(isset($a["1"]));
var_dump($a[1]);
var_dump($a["1"]);
Вывод:
array (size=2)
'1' => int 1
'2' => int 2
boolean false
boolean false
ERROR: E_NOTICE: Undefined offset: 1
null
ERROR: E_NOTICE: Undefined offset: 1
null
Как получить доступ к этим значениям?
Демо: http://codepad.viper-7.com/8O03IM
Ответы
Ответ 1
Итак, я не видел, чтобы другие ответы касались этого, но @xdazz приблизился.
Пусть начало нашей среды, $obj
равно объектной нотации декодированной строки:
php > $obj = json_decode('{"1":1,"2":2}');
php > print_r($obj);
stdClass Object
(
[1] => 1
[2] => 2
)
php > var_dump( $obj );
object(stdClass)#1 (2) {
["1"]=>
int(1)
["2"]=>
int(2)
}
Если вы хотите получить доступ к строкам, мы знаем следующее:
php > echo $obj->1;
Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `'{'' or `'$'' in php shell code on line 1
Доступ к объектным переменным
Вы можете получить к нему доступ так:
php > echo $obj->{1};
1
Это то же самое, что сказать:
php > echo $obj->{'1'};
1
Доступ к переменным массива
Проблема с массивами заключается в следующем: пустой пробел, что является проблемой при типизации.
php > echo $obj[1];
php >
Если вы возвращаете его обратно, объект снова доступен:
php > $obj = (object) $obj;
php > echo $obj->{1};
1
Вот функция, которая будет автоматизировать вышесказанное для вас:
function array_key($array, $key){
$obj = (object) $array;
return $obj->{$key};
}
Пример использования:
php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1
php > echo array_key($obj, 2);
2
Ответ 2
Если вам нужен массив, установите второй параметр json_decode в true
.
$a = json_decode('{"1":1,"2":2}', true);
Edit:
когда вы бросаете объект std в массив, числовой строковый ключ не присваивается числу.
Вот пример.
$obj = new stdClass;
$obj->{'1'} = 1;
$arr = (array) $obj;
var_dump($arr);
var_dump(isset($arr[1]));
Ответ 3
По-видимому, это известная проблема, и не планируется ее исправление; см. Doc Bug # 45959 Преобразование объекта в массив приводит к странному поведению:
Фиксация, которая подразумевает уменьшение производительности, следовательно, лучше кажется, что она остается известной проблемой, но документирована.
Эта победа (тогда) отмечена в документации для типа массива (выделение мое):
Если объект преобразуется в массив, результатом является массив, элементами которого являются свойства объекта. Ключи - это имена переменных-членов с несколькими заметными исключениями: целочисленные свойства недоступны.... Это может привести к неожиданному поведению....
Ответ 4
Да. Я согласен, PHP имеет проблемы с typecasting от объекта к массиву, но foreach обрабатывает разумно объект или ассоциативный массив.
$a = json_decode('{"1":1,"2":2}'); //need not typecast but doesnt break even if u typecast
foreach ($a as $k=>$v){
echo $v;
}
Ответ 5
Я недавно встретил ту же проблему.
$obj = new stdClass();
$obj->{'0'} = "test";
$array = (array)$obj;
foreach ($array as $key => $value) {
$array[$key] = strtoupper($value);
}
var_dump($array);
Этот код выводит:
array(2) {
["0"]=>
string(4) "test"
[0]=>
string(4) "TEST"
}
Обнаружено, что при отладке метода для преобразования рекурсивных объектов в массив я был сумасшедшим.
Ответ 6
У меня была та же проблема (но с array_intersect_key).
Вот мое решение:
$array = array_combine(array_keys($array), $array);