PHP, json_encode, json_decode объекта SimpleXML

Функция в моем приложении делает следующее:

  • Захват веб-страницы с помощью Snoopy
  • Загрузить результат в DOMDocument
  • Загрузите DOMDocument в простой XML-объект
  • Запустите XPath, чтобы изолировать требуемый раздел документа
  • json_encode результат и сохранить в базу данных для дальнейшего использования.

Моя проблема возникает при восстановлении этого блока из базы данных и его декодировании. Я вижу атрибуты @attributes, когда выполняю var_dump объекта, но не могу найти комбинацию команд, позволяющую получить к ним доступ.

Сообщение об ошибке: Неустранимая ошибка: невозможно использовать объект типа stdClass в качестве массива.

Ниже приведен пример моего объекта. Я пробовал, среди прочего, то, что раньше работало.

echo $obj['class'];

stdClass Object
(
    [@attributes] => stdClass Object
        (
            [class] => race_idx_hdr
        )

    [img] => stdClass Object
        (
            [@attributes] => stdClass Object
                (
                    [src] => /Images/Icons/i_blue_bullet.gif
                    [alt] => image
                    [title] => United Kingdom
                )

        )

    [a] => Fast Cards
)

person Community    schedule 01.10.2009    source источник


Ответы (3)


Когда вы декодируете json из базы данных, вы получаете объект типа «stdClass» вместо исходного типа «SimpleXMLElement», возвращаемого функцией SimpleXMLElement::xpath.

Объект stdClass не «знает» о синтаксисе псевдомассива, используемом объектами SimpleXMLElement для доступа к атрибутам.

Обычно вы должны использовать функции serialize() и unserialize() вместо json_encode/decode для хранения объектов в базе данных, но, к сожалению, SimpleXMLElements с ними не работает.

В качестве альтернативы, почему бы просто не сохранить фактический xml и не прочитать его обратно в SimpleXML после извлечения из базы данных:

// convert SimpleXMLElement back to plain xml string
$xml = $simpleXML->asXML();

// ... code to store $xml in the database
// ... code to retrieve $xml from database

// recreate SimpleXMLELement
$simpleXML = simplexml_load_string($xml);
person Henrik Opel    schedule 01.10.2009
comment
на самом деле это единственное решение, так как json_encode теряет кучу данных. - person ; 02.10.2009

Я на самом деле не очень понимаю, что вы пытаетесь сделать и где возникает ошибка, но для доступа к свойствам вашего объекта вы можете использовать

echo $obj->{'@attributes'}->class; // prints "race_idx_hdr"
echo $obj->img->{'@attributes'}->src; // prints "/Images/Icons/i_blue_bullet.gif"
echo $obj->img->{'@attributes'}->alt; // prints "image"
echo $obj->img->{'@attributes'}->title; // prints "United Kingdom"
echo $obj->a; // prints "Fast Cards"

Этот странный синтаксис ($obj->{'@attributes'}) необходим, потому что символ @ зарезервирован в PHP и не может использоваться для идентификаторов.

person Stefan Gehrig    schedule 01.10.2009
comment
{@stefan} - ты легенда ;). хорошо, что мой новый факт дня, @ является зарезервированным символом. - person ; 01.10.2009
comment
обновление: json_encoding simplexml, кажется, сбрасывает массу информации. поэтому я меняю принятый ответ на сохранение необработанного xml в БД. - person ; 02.10.2009

Если объект преобразуется в массив, результатом является массив, элементами которого являются свойства объекта.

$asArray = (array)$myObj;
echo $asArray['@attribute'];
person Lawrence Barsanti    schedule 01.10.2009
comment
это все еще не работает, вероятно, из-за того, что Стефан сказал о том, что @ является зарезервированным символом. - person ; 01.10.2009
comment
Это связано с тем, что только exterior stdClass преобразуется в массив, все значения массива по-прежнему будут объектами stdClass. Однако, если вы использовали decode_json($json_string, TRUE) обратите внимание на истинное логическое значение. Затем вы можете получить доступ к $array['@attribute']. --the '@' на данный момент является строкой и не зарезервировано. - person null; 01.10.2009