Итак, почему мы получаем ошибку?
blockquote>Поскольку
super
допустимо только внутри методов .greet: function() {}
является «нормальным» свойством / функцией, а не методом, потому что он не следует синтаксису метода.Различия между методом и определением нормальной функции:
- Методы имеют «HomeObject», что позволяет им использовать
super
.- Методы не являются конструктивными, т. е. их нельзя вызвать с помощью
new
.- ] Имя метода не становится привязкой в области метода (в отличие от названных функциональных выражений).
PHP 7.2 представил поведенческое изменение в преобразование числовых клавиш в объекты и массивы cast , которое исправляет эту конкретную несогласованность и приводит к тому, что все следующие примеры ведут себя как ожидаемый.
Нечего путать!
У 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'];
Тем не менее, я не уверен, что это лучший вариант по всем направлениям, потому что он будет бесполезно применять к массивам все свойства, которые вы не
Вариант № 3: умение играть
Альтернативой предыдущей опции является использование встроенных функций JSON:
$arr = json_decode(json_encode($myVar), true);
$value = $arr['highlighting']['448364']['Data']['0'];
Функции JSON помогают выполнять рекурсивное преобразование в массив без необходимости определять какие-либо внешние функции. Как бы это ни было желательно, у него есть недостаток «nuke» варианта №2 и дополнительно недостаток, заключающийся в том, что если в вашем объекте есть какие-либо строки, эти строки должны быть закодированы в UTF-8 (это требование json_encode
).
Последняя альтернатива полному ответу Джона:
Просто используйте json_decode (), а второй параметр установлен в true.
$array = json_decode($url, true);
Затем он возвращает ассоциативный массив, а не объект, поэтому нет необходимости преобразовывать его после этого.
Это может быть непригоден для каждого приложения, но это действительно помогло мне легко ссылаться на свойство объекта oroginal.
Решение было найдено в этом учебнике - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/
С уважением
Боюсь, вам не разрешено называть объекты, начинающиеся с численных значений. Переименуйте первый «448364», начинающийся с буквы.
Второй - это массив, к которому должны быть доступны скобки вроде этого:
print myVar->highlighting->test_448364->Data[0]
вместо
Если объект начинается с @
, например:
SimpleXMLElement Object (
[@attributes] => Array (
[href] => qwertyuiop.html
[id] => html21
[media-type] => application/xhtml+xml
)
)
Вы должны использовать:
print_r($parent_object->attributes());
, потому что $parent_object->{'@attributes'}
или $parent_object['@attributes']
не будут работать .
Просто хотел добавить к красноречивому объяснению Джона причину, почему это не удается. Это все потому, что при создании массива php преобразует ключи в целые числа & mdash; если он может & mdash; что вызывает проблемы поиска на массивах, которые были переданы объектам, просто потому, что цифровой ключ сохранен. Это проблематично, потому что все параметры доступа к ресурсам ожидают или конвертируют в строки. Вы можете подтвердить это, выполнив следующие действия:
$arr = array('123' => 'abc');
$obj = (object) $arr;
$obj->{'123'} = 'abc';
print_r( $obj );
, которые будут выводиться:
stdClass Object (
[123] => 'abc',
[123] => 'abc'
)
Таким образом, у объекта есть две клавиши свойств, одна цифра (к которой невозможно получить доступ ) и одна строка. Вот почему Jon #Fact 4
работает, потому что, устанавливая свойство с помощью фигурных скобок, вы всегда определяете строковый ключ, а не числовой.
Принимая решение Джона, но поворачивая его на голову , вы можете сгенерировать объект из вашего массива, который всегда имеет строковые ключи, выполнив следующее:
$obj = json_decode(json_encode($arr));
Теперь вы можете использовать любое из следующих действий, потому что доступ таким образом всегда преобразует значение внутри фигурной скобки до строки:
$obj->{123};
$obj->{'123'};
Хороший старый нелогичный PHP ...
->date
или->timezone
, возвращается толькоnull
. Я заметил, что если я var_dumped объект перед использованием этих свойств, вернутся правильные значения. Клонирование не исправляет это, поэтому я думаю, что это действительно имеет отношение к доступу, который делаетvar_dump
... Затем я увидел ваш вариант # 1 и voilá, получив его как массив ($objCastAsArray['date']
), работал как очарование. – Armfoot 18 July 2013 в 09:31