Как отобразить массив & amp; объект с использованием одной строки кода в PHP? [Дубликат]

Итак, почему мы получаем ошибку?

blockquote>

Поскольку super допустимо только внутри методов . greet: function() {} является «нормальным» свойством / функцией, а не методом, потому что он не следует синтаксису метода.

Различия между методом и определением нормальной функции:

  • Методы имеют «HomeObject», что позволяет им использовать super.
  • Методы не являются конструктивными, т. е. их нельзя вызвать с помощью new.
  • ] Имя метода не становится привязкой в ​​области метода (в отличие от названных функциональных выражений).
78
задан Rizier123 12 May 2016 в 21:27
поделиться

6 ответов

Обновлен для PHP 7.2

PHP 7.2 представил поведенческое изменение в преобразование числовых клавиш в объекты и массивы cast , которое исправляет эту конкретную несогласованность и приводит к тому, что все следующие примеры ведут себя как ожидаемый.

Нечего путать!


Оригинальный ответ (относится к версиям до 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'];

Тем не менее, я не уверен, что это лучший вариант по всем направлениям, потому что он будет бесполезно применять к массивам все свойства, которые вы не

Вариант № 3: умение играть

Альтернативой предыдущей опции является использование встроенных функций JSON:

$arr = json_decode(json_encode($myVar), true);
$value = $arr['highlighting']['448364']['Data']['0'];

Функции JSON помогают выполнять рекурсивное преобразование в массив без необходимости определять какие-либо внешние функции. Как бы это ни было желательно, у него есть недостаток «nuke» варианта №2 и дополнительно недостаток, заключающийся в том, что если в вашем объекте есть какие-либо строки, эти строки должны быть закодированы в UTF-8 (это требование json_encode ).

256
ответ дан Jon 19 August 2018 в 16:20
поделиться
  • 1
    Это также помогло решить мою проблему! [Д0] stackoverflow.com/questions/4643894/… – Bossliaw 10 December 2012 в 13:40
  • 2
    Джон, спасибо, что спас меня. Моя проблема была другой, хотя (я думаю, это действительно «то, что они никогда не говорили вам»). Объект DateTime, полученный из БД, кажется ОК, но если я обращаюсь к любому из его свойств, например ->date или ->timezone, возвращается только null. Я заметил, что если я var_dumped объект перед использованием этих свойств, вернутся правильные значения. Клонирование не исправляет это, поэтому я думаю, что это действительно имеет отношение к доступу, который делает var_dump ... Затем я увидел ваш вариант # 1 и voilá, получив его как массив ($objCastAsArray['date']), работал как очарование. – Armfoot 18 July 2013 в 09:31
  • 3
    Факт № 0 : Литейные массивы в объекты не должны в первую очередь не иметь вонючего смысла. Факт №1 к факту № 3: ненужный. – Pacerier 13 March 2015 в 11:34
  • 4
    @Pacerier: Я согласен, что это несколько сомнительно, но в некоторых ситуациях это может иметь смысл. Во всяком случае, поскольку это документировано в руководстве, чтобы работать так, наши личные мнения не имеют большого значения. – Jon 14 April 2015 в 19:12
  • 5
    Я написал билет на php bugtracker: bugs.php.net/bug.php?id=70127 – nfo 24 July 2015 в 14:33

Последняя альтернатива полному ответу Джона:

Просто используйте json_decode (), а второй параметр установлен в true.

$array = json_decode($url, true);

Затем он возвращает ассоциативный массив, а не объект, поэтому нет необходимости преобразовывать его после этого.

Это может быть непригоден для каждого приложения, но это действительно помогло мне легко ссылаться на свойство объекта oroginal.

Решение было найдено в этом учебнике - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/

С уважением

1
ответ дан Bluekable 19 August 2018 в 16:20
поделиться

Боюсь, вам не разрешено называть объекты, начинающиеся с численных значений. Переименуйте первый «448364», начинающийся с буквы.

Второй - это массив, к которому должны быть доступны скобки вроде этого:

print myVar->highlighting->test_448364->Data[0]

вместо

0
ответ дан Gustav 19 August 2018 в 16:20
поделиться
  • 1
    Я не могу его изменить. Результат возвращается из приложения, управление которым я не контролирую. – avinash shah 26 April 2012 в 13:12

Если объект начинается с @, например:

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'] не будут работать .

1
ответ дан Nisse Engström 19 August 2018 в 16:20
поделиться

Просто хотел добавить к красноречивому объяснению Джона причину, почему это не удается. Это все потому, что при создании массива 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 ...

9
ответ дан Pebbl 19 August 2018 в 16:20
поделиться
1
ответ дан Nisse Engström 31 October 2018 в 03:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: