2012-05-07 4 views
6

Я хотел сериализовать полный PHP-объект-граф в строковое представление JSON и неэтериализовать его обратно на идентичный PHP-объект-граф.Сериализовать/unserialize PHP-объект-график для JSON

Вот краткое изложение вариантов я рассматривал, и причины, почему они не работают для меня:

  • serialize() не делать то, что я хочу, потому что он использует формат, специфичный для PHP. Я хочу формат, который широко поддерживается большинством языков и доступен для чтения/редактирования.

  • json_encode() не делает то, что я хочу, потому что это только простые значения и массивы, а не объекты. (Я фактически использую это в своей реализации, см. Ниже.)

  • не обрабатывает круговые ссылки и не делает то, что я хочу (см. Выше). (обратите внимание, что моя текущая реализация не обрабатывать циклические ссылки либо - см комментарии и отвечать ниже для выяснения этого вопроса)

  • Sebastian Бергмана Object Freezer хорошая реализация, но это не то, что я хочу, либо -. он использует очень длинную форму, и опирается на заполнение сериализованных объектов GUID.

  • Serialized не делает то, что я хочу - он фактически не выполняет сериализацию, он анализирует вывод serialize() и производит другое представление, например. XML, но не может проанализировать это представление. (Она также не поддерживает JSON - XML ​​очень длинная форма, а не то, что я хочу.)

теперь у меня есть рабочая реализация поделиться:

https://github.com/mindplay-dk/jsonfreeze

JSON- представление объекта-граф выглядит следующим образом:

{ 
    "#type": "Order", 
    "orderNo": 123, 
    "lines": [{ 
     "#type": "OrderLine", 
     "item": "milk \"fuzz\"", 
     "amount": 3, 
     "options": null 
    }, { 
     "#type": "OrderLine", 
     "item": "cookies", 
     "amount": 7, 
     "options": { 
      "#type": "#hash", 
      "flavor": "chocolate", 
      "weight": "1\/2 lb" 
     } 
    }], 
    "paid": true 
} 

Этот подход предназначен для работы для чистой дерева структуры совокупности - циклические ссылки не допускается, ни множественный г ссылки на те же объекты. Другими словами, это не универсальное назначение, например, serialize() и unserialize(), которые функционируют для любого объекта-графа PHP.

В моем initial approach Я использовал сериализованную форму, которая была по существу базовым-0 списком объектов. Первым объектом в списке (число 0) является корень сериализованного объектного графа, любые другие объекты хранятся в том порядке, в котором они найдены.

В текущей реализации представление JSON похоже на исходную древовидную структуру до такой степени, что это возможно, что позволяет фактически работать с представлением JSON объектного графа в JavaScript. Единственное отклонение - это свойство magic #type (с префиксом # для предотвращения столкновения с именами свойств) и #hash «type», используемое для выделения хешей array (хранимых как объекты JSON) из регулярных array -типов массивов (хранимых как JSON массивы).


Я оставляю эти записи о предыдущей версии здесь в исторических целях.

Циркулярные ссылки обрабатываются просто, никогда не сохраняя вложенные объекты внутри сериализованного представления каждого объекта - вместо этого любая ссылка на объект хранится как объект JSON с индексом объекта - например. {"__oref":2} - ссылка на объект с индексом 2 в списке объектов.

У меня возникла проблема с ссылками на массивы в моей реализации - когда я var_dump() внутри кода, который восстанавливает ссылки на объекты в массиве, они заполняются, но в какой-то момент массив копируется и вы получаете пустую копию. Я пробовал поместить в код & символов, но независимо от того, где я передаю по ссылке, конечным результатом является пустой массив.

+0

Я бы не назвал формат сериализации PHP запатентованным, поскольку он задокументирован - [по крайней мере внутри исходного кода] (http://lxr.php.net/opengrok /xref/PHP_TRUNK/ext/standard/var.c#php_var_serialize_intern), но также и третьими лицами. Поэтому вы можете использовать его. – hakre

+0

он может быть задокументирован, но PHP является единственной платформой/языком, которая имеет реализацию unserialize() - я бы предпочел JSON, который уже поддерживается каждым основным языком. А также читается человеком. –

+0

Вы можете преобразовывать сериализованные данные в XML, который поддерживается везде. [Сериализованная библиотека] (https://github.com/ktomk/Serialized) делает это. Не должно быть так сложно продлить его с помощью json dumper. - так что, может быть, вы сочтете это полезным. – hakre

ответ

2

Готовый сценарий (отправил выше) отвечает моим требованиям: точные

  • Serialize и десериализируются весь агрегат.

  • Имейте представление JSON, которое близко напоминает исходную структуру данных.

  • Не загрязняйте структуру данных динамически сгенерированными ключами или другими данными.

Он не обрабатывает круглые ссылки. Как указано в comment above, нет правильного способа хранения круговых ссылок или нескольких ссылок на один и тот же объект, так как все они равны. Понимая это, я решил, что мой объектный граф должен быть обычным деревом и принял это ограничение как «хорошую вещь».

обновление: вывод теперь может быть отформатирован с отступом, строкой и пробелами - это было для меня важно иметь удобочитаемое (и источник управление дружественным) представление для моих целей. (Форматирование может быть включено или отключено по мере необходимости.)

0

Я не знаю, если это то, что вам нужно, но если вы заинтересованы только в получении публичных свойств объекта, get_object_vars ($ obj) выполнит трюк.

<?php 

class foo { 
    public $fname = "John"; 
    public $sname = "Doe"; 
    private $status = null; 
    static $type = "person"; 


} 

$obj = new foo; 

print_r((get_object_vars($obj))); 

print json_encode(get_object_vars($obj)); 

?> 

Выведет:

Array ([имя_файла] => John [SNAME] => Doe)

{ "имя_файла": "Джон", "SNAME": "Doe"}

Вышеупомянутый метод бесполезен для доступа к ссылкам функций и частным переменным, но вы можете использовать его в сочетании с некоторым другим кодом, чтобы сбить то, что вам нужно.

Dinesh.

+0

Если вы посмотрели на реализацию, которую я опубликовал, я получил немного больше этого ... –

Смежные вопросы