Я использую json_decode()
что-то вроде:
$myVar = json_decode($data)
Что дает мне такой вывод:
[highlighting] => stdClass Object
(
[448364] => stdClass Object
(
[Data] => Array
(
[0] => Tax amount liability is .......
Я хочу получить доступ к строковому значению в ключе [0]. Когда я пытаюсь сделать что-то вроде:
print $myVar->highlighting->448364->Data->0;
Я получаю такую ошибку:
Ошибка синтаксического анализа: синтаксическая ошибка, неожиданный T_DNUMBER
Две цифры / целые числа там кажутся проблемой.
php
object
properties
Авинаш шах
источник
источник
Ответы:
Обновлено для PHP 7.2
PHP 7.2 представил изменение поведения при преобразовании числовых ключей в приведения объектов и массивов , которое исправляет это конкретное несоответствие и заставляет все следующие примеры вести себя так, как ожидалось.
Одной проблемой меньше!
Исходный ответ (относится к версиям до 7.2.0)
У PHP есть своя доля темных переулков, внутри которых вы действительно не хотите оказаться. Свойства объекта с именами, которые являются числами, являются одним из них ...
Что они никогда не говорили тебе
Факт №1: вы не можете легко получить доступ к свойствам с именами, которые не являются допустимыми именами переменных.
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->123foo; // error
Факт №2: Вы можете получить доступ к таким свойствам с помощью синтаксиса фигурных скобок.
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->{'123foo'}; // OK!
Факт №3: Но только не, если имя свойства состоит только из цифр!
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->{'123foo'}; // OK! echo $o->{'123'}; // error!
Живой пример .
Факт №4: Ну, если только объект изначально не был получен из массива.
$a = array('123' => '123'); $o1 = (object)$a; $o2 = new stdClass; $o2->{'123'} = '123'; // setting property is OK echo $o1->{'123'}; // error! echo $o2->{'123'}; // works... WTF?
Живой пример .
Довольно интуитивно понятно, согласны?
Что ты можешь сделать
Вариант 1: сделать вручную
Наиболее практичный подход - просто вернуть интересующий вас объект в массив, что позволит вам получить доступ к свойствам:
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; $a = (array)$o; echo $o->{'123'}; // error! echo $a['123']; // OK!
К сожалению, это не работает рекурсивно. Итак, в вашем случае вам нужно будет сделать что-то вроде:
$highlighting = (array)$myVar->highlighting; $data = (array)$highlighting['448364']->Data; $value = $data['0']; // at last!
Вариант 2: ядерный вариант
Альтернативным подходом было бы написать функцию, рекурсивно преобразующую объекты в массивы:
function recursive_cast_to_array($o) { $a = (array)$o; foreach ($a as &$value) { if (is_object($value)) { $value = recursive_cast_to_array($value); } } return $a; } $arr = recursive_cast_to_array($myVar); $value = $arr['highlighting']['448364']['Data']['0'];
Однако я не уверен, что это лучший вариант во всех отношениях, потому что он без нужды приведет к преобразованию в массивы всех свойств, которые вам не интересны, а также те, которые вам интересны.
Вариант no 3: сыграть с умом
Альтернативой предыдущему варианту является использование встроенных функций JSON:
$arr = json_decode(json_encode($myVar), true); $value = $arr['highlighting']['448364']['Data']['0'];
Функции JSON помогают выполнять рекурсивное преобразование в массив без необходимости определять какие-либо внешние функции. Как бы желательно это ни выглядело, у него есть недостаток «ядерной бомбы» варианта №2 и, кроме того, недостаток, заключающийся в том, что если внутри вашего объекта есть какие-либо строки, эти строки должны быть закодированы в UTF-8 (это требование
json_encode
).источник
->date
или->timezone
,null
возвращается только . Я заметил, что если я var_dumped объект перед использованием этих свойств, возвращаются правильные значения. Клонирование этого не исправляет, поэтому я предполагаю, что это действительно имеет какое-то отношение к доступу, которыйvar_dump
делает ... Затем я увидел ваш вариант №1 и вуаля, доступ к нему как к массиву ($objCastAsArray['date']
) работал как шарм.$o = unserialize('O:8:"StdClass"' . substr(serialize($a),1));
Просто хотел добавить к красноречивому объяснению Джона причину, по которой это не удается. Это все потому, что при создании массива php преобразует ключи в целые числа - если это возможно - что вызывает проблемы поиска в массивах, которые были преобразованы в объекты, просто потому, что числовой ключ сохраняется. Это проблематично, потому что все параметры доступа к свойствам ожидают или преобразуются в строки. Вы можете подтвердить это, выполнив следующие действия:
$arr = array('123' => 'abc'); $obj = (object) $arr; $obj->{'123'} = 'abc'; print_r( $obj );
Что выведет:
stdClass Object ( [123] => 'abc', [123] => 'abc' )
Таким образом, у объекта есть два ключа свойств, один числовой (к которому нельзя получить доступ) и один на основе строки. Это причина того, почему Джон
#Fact 4
работает, потому что установка свойства с помощью фигурных скобок означает, что вы всегда определяете строковый ключ, а не числовой.Взяв решение Джона, но перевернув его с ног на голову, вы можете сгенерировать объект из вашего массива, который всегда имеет строковые ключи, выполнив следующие действия:
С этого момента вы можете использовать любое из следующих действий, поскольку при таком доступе значение внутри фигурной скобки всегда преобразуется в строку:
$obj->{123}; $obj->{'123'};
Старый добрый нелогичный PHP ...
источник
Если объект начинается с
@
подобного:SimpleXMLElement Object ( [@attributes] => Array ( [href] => qwertyuiop.html [id] => html21 [media-type] => application/xhtml+xml ) )
Вы должны использовать:
потому что
$parent_object->{'@attributes'}
или$parent_object['@attributes']
не будет работать.источник
Я скопировал эту функцию из сети. Если все работает так, как написано («Функция преобразования объектов stdClass в многомерные массивы»), попробуйте следующее:
<?php function objectToArray($d) { if (is_object($d)) { // Gets the properties of the given object // with get_object_vars function $d = get_object_vars($d); } if (is_array($d)) { /* * Return array converted to object * Using __FUNCTION__ (Magic constant) * for recursive call */ return array_map(__FUNCTION__, $d); } else { // Return array return $d; } } ?>
objectToArray
функции[highlighting][448364][Data][0]
Источник: PHP stdClass в массив и массив в stdClass
источник
Последняя альтернатива исчерпывающему ответу Джона:
Просто используйте json_decode () со вторым параметром, установленным в значение true .
$array = json_decode($url, true);
Затем это возвращает ассоциативный массив, а не объект, поэтому нет необходимости преобразовывать постфактум.
Это может не подходить для каждого приложения, но действительно помогло мне легко ссылаться на свойство оригинального объекта.
Решение было найдено в этом руководстве - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/
С уважением
источник
Доступ к свойствам объекта, имеющим номера в качестве имени свойства. В основном требуется после преобразования массива в объект.
$arr = [2,3,7]; $o = (object) $arr; $t = "1"; $t2 = 1; $t3 = (1); echo $o->{1}; // 3 echo $o->{'1'}; // 3 echo $o->$t; // 3 echo $o->$t2; // 3 echo $o->$t3; // 3 echo $o->1; // error echo $o->(1); // error
источник
Боюсь, вам не разрешено называть объекты, начинающиеся с цифр. Переименуйте первый в «448364», начиная с буквы.
Второй - массив, к ним нужно обращаться с помощью скобок:
print myVar->highlighting->test_448364->Data[0]
вместо
источник