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
).