У меня есть массив PHP, который имеет числовые ключи в виде строкового типа.
Но когда я пытаюсь получить к ним доступ, PHP дает мне неопределенную ошибку индекса.
$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 ОШИБКА: E_NOTICE: Неопределенное смещение: 1 ноль ОШИБКА: E_NOTICE: Неопределенное смещение: 1 ноль
Как получить доступ к этим значениям?
Демо: http://codepad.viper-7.com/8O03IM
Таким образом, я не видел, чтобы другие ответы касались этого, но @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
Если вам нужен массив, установите для второго параметра json_decode значение true
.
$a = json_decode('{"1":1,"2":2}', true);
Изменить: когда вы бросаете объект std в массив, числовой строковый ключ не присваивается числу. Вот пример.
$obj = new stdClass; $obj->{'1'} = 1; $arr = (array) $obj; var_dump($arr); var_dump(isset($arr[1]));
По-видимому, это известная проблема, и ее не планируется исправлять; см. Doc Bug # 45959 Преобразование объекта в массив приводит к странному поведению :
Фиксация подразумевает уменьшение производительности, следовательно, лучше, по-видимому, держать его как известную проблему, но документировано.
Эта победа (тогда) отмечена в документации для типа массива (акцент мой):
Если объект преобразуется в массив, результатом является массив, элементами которого являются свойства объекта. Ключи – это имена переменных-членов, с несколькими заметными исключениями: целочисленные свойства недоступны …. Это может привести к неожиданному поведению ….
Да. Я согласен, 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; }
Я недавно встретил ту же проблему.
$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" }
Установлено, что при отладке метода для преобразования рекурсивных объектов в массив я был сумасшедшим.
У меня была та же проблема (но с array_intersect_key).
Вот мое решение:
$array = array_combine(array_keys($array), $array);