Оновлено для 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'};
Факт No3: Але ні, якщо назва власності - це всі цифри!
$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'};
Живий приклад .
Досить інтуїтивно, ви не згодні?
Що ти можеш зробити
Варіант No1: зробіть це вручну
Найпрактичніший підхід - просто повернути об’єкт, який вас цікавить, назад у масив, що дозволить отримати доступ до властивостей:
$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'];
Однак я не впевнений, що це кращий варіант, оскільки він без необхідності передасть у масиви всі властивості, які вас не цікавлять, а також ті, що вас цікавлять.
Варіант No3: грати розумно
Альтернативою попереднього варіанту є використання вбудованих функцій JSON:
$arr = json_decode(json_encode($myVar), true);
$value = $arr['highlighting']['448364']['Data']['0'];
Функції JSON корисно виконують рекурсивне перетворення в масив без необхідності визначати будь-які зовнішні функції. Наскільки б це не виглядало бажаним, він має недолік "нуклеотиду" варіанту №2 і додатково недолік: якщо у вашому об'єкті є будь-які рядки, ці рядки повинні бути закодовані в UTF-8 (це є вимогою json_encode
).