Я хотел сериализовать полный PHP-объект-граф для строкового представления JSON и неэтериализовать его на идентичный PHP-объект-граф.
Вот резюме вариантов, которые я рассмотрел, и причины, по которым они не работают для меня:
-
serialize()
не выполняет то, что я хочу, потому что он использует формат, специфичный для PHP. Я хочу формат, который широко поддерживается большинством языков и доступен для чтения/редактирования. -
json_encode()
не делает то, что я хочу, потому что он просто делает простые значения и массивы, а не объекты. (Я фактически использую это в своей реализации, см. Ниже.) -
var_export()
не обрабатывает циклические ссылки и не выполняет то, что я хочу (см. выше.) (обратите внимание, что моя текущая реализация также не обрабатывает круговые ссылки - см. комментарии и ответ ниже для пояснения этот вопрос.) -
Себастьян Бергманн Объект 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-объекта-графика.
В моем начальном подходе Я использовал сериализованную форму, которая была по существу базовым списком объектов. Первым объектом в списке (число 0) является корень сериализованного объектного графа, любые другие объекты хранятся в том порядке, в котором они найдены.
В текущей реализации представление JSON похоже на исходную древовидную структуру до такой степени, что это возможно, что позволяет фактически работать с представлением JSON объектного графа в JavaScript. Единственное отклонение - это свойство magic #type
(с префиксом # для предотвращения столкновения с именами свойств) и #hash
"type", используемое для выделения хешей array
-типов (хранимых как объекты JSON) из регулярного array
-типы (хранятся как массивы JSON).
Я оставляю эти заметки о предыдущей версии здесь для исторических целей.
Циклические ссылки обрабатываются просто, никогда не сохраняя вложенные объекты внутри сериализованного представления каждого объекта - вместо этого любая объектная ссылка сохраняется как объект JSON с индексом объекта - например. {"__oref":2}
является ссылкой на объект с индексом 2
в списке объектов.
У меня проблема с ссылками на массивы в моей реализации - когда я var_dump() внутри кода, который восстанавливает ссылки на объекты в массиве, они заполняются, но в какой-то момент массив копируется, и вы закончите с пустой копией. Я попытался помещать символы &
всюду в коде, но независимо от того, где я передаю по ссылке, конечным результатом является пустой массив.