Обновлено для PHP 7.2
PHP 7.2 представил изменение поведения при преобразовании числовых ключей в приведения объектов и массивов , которое исправляет это конкретное несоответствие и заставляет все следующие примеры вести себя так, как ожидалось.
Одной проблемой меньше!
Исходный ответ (относится к версиям до 7.2.0)
У PHP есть своя доля темных переулков, внутри которых вы действительно не хотите оказаться. Свойства объекта с именами, которые являются числами, являются одним из них ...
Что они никогда не говорили тебе
Факт №1: вы не можете легко получить доступ к свойствам с именами, которые не являются допустимыми именами переменных.
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->123foo;
Факт №2: Вы можете получить доступ к таким свойствам с помощью синтаксиса фигурных скобок.
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'};
Факт №3: Но только не, если имя свойства состоит только из цифр!
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'};
echo $o->{'123'};
Живой пример .
Факт №4: Ну, если только объект изначально не был получен из массива.
$a = array('123' => '123');
$o1 = (object)$a;
$o2 = new stdClass;
$o2->{'123'} = '123';
echo $o1->{'123'};
echo $o2->{'123'};
Живой пример .
Довольно интуитивно понятно, согласны?
Что ты можешь сделать
Вариант 1: сделать вручную
Наиболее практичный подход - просто вернуть интересующий вас объект в массив, что позволит вам получить доступ к свойствам:
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
$a = (array)$o;
echo $o->{'123'};
echo $a['123'];
К сожалению, это не работает рекурсивно. Итак, в вашем случае вам нужно будет сделать что-то вроде:
$highlighting = (array)$myVar->highlighting;
$data = (array)$highlighting['448364']->Data;
$value = $data['0'];
Вариант 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
).