Сохранить объект в файл с возможностью дальнейшего подключения

350
12 февраля 2020, 13:00

Есть объекты, которые строятся в одной системе. Они могут быть как большими, так и маленькими, очень вложенными и не очень.

Мне необходимо каким-то образом сохранить их в файлы, чтобы затем в другом проекте кто-то взял и написал что-то типа.

$model = require 'path/to/model';

И работал с ним, как с тем самым объектом.

Пока я придумал сохранять их в json файлы, и в другом проекте делать

$json = file_get_contents('path/to/json');
$model = json_decode($json);

Но минус подхода в том, что на выходе все будет объектами. Даже то, что было до этого массивами. А мне важно получить такую же модель как была изначально.

P.S. Вообще эти объекты есть модели представления, которые уходят во вьюхи. Мы хотим отдавать их верстальщику, чтобы он на их основе верстал страницы без необходимости поднимать у себя весь проект.

Answer 1

В данном случае при использовании нативной php шаблонизации важно сохранить массив массивом, а объект объектом, т.к. обращения к ним по разному происходит, поэтому подошел вариант с serialize/unserialize.

php.net/manual/ru/function.serialize.php

UPD.1 Если делать unserialize в системе, где не объявлены сериализованные объекты, они после unserialize станут объектами класса __PHP_Incomplete_Class. Получить доступ к свойствам такого объекта не представляется возможным, хотя var_dump выводит их все.

Для решения этой ситуации был написан небольшой хелпер.

Смысле его в приведении таких проблемных объектов к классу stdClass.

class DataHelper
{
    public static $basePath;
    public static function getViewData($name)
    {
        $serializedData = file_get_contents(self::$basePath.'/'.$name.'.php');
        $data = unserialize($serializedData, ['allowed_classes' => false]);
        return self::fixObjects($data);
    }
    public static function fixObjects($data)
    {
        if (is_array($data)) {
            foreach($data as $key=>$value) {
                $data[$key] = self::fixObjects($value);
            }
        }
        if (gettype($data) == 'object' && get_class($data) == '__PHP_Incomplete_Class') {
            $data = self::castToClass('stdClass', $data);
            $vars = get_object_vars($data);
            foreach($vars as $varName => $varValue) {
                $data->{$varName} = self::fixObjects($varValue);
            }
        }
        return $data;
    }
    public static function castToClass($class, $object)
    {
        return unserialize(preg_replace('/^O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', serialize($object)));
    }
}
READ ALSO
Рандомные ошибки ImageMagick

Рандомные ошибки ImageMagick

Использую в проекте imagineНе часто, но появляются странные исключения, самое массовое:

333
Как менять количество точек картинки (resolution)?

Как менять количество точек картинки (resolution)?

Имеется папка с 3000 картинками в PNGУ них Pixels/Inch: 72 и размеры 354px на 130px На выходе нужно получить эти же картинки с Pixels/Inch = 300, размеры сохранить

314
Доктрина не обновляет свойства объекта cmf SeoBundle после установки

Доктрина не обновляет свойства объекта cmf SeoBundle после установки

Я использую Symfony CMF SeoBundleМой класс сущности использует SeoAwareTrait

306