Объектные файлы в PHP: как хранить и восстанавливать объекты

Раздел: Основы PHP -> Основы PHP

Сохранение объектов в файлы: основные подходы

В PHP существует несколько способов сохранить объект в файл для последующего восстановления. Такой файл часто называют объектным файлом. Выбор метода зависит от целей: совместимость с другими языками, удобство отладки, скорость работы.

Как сохранить объект в файл и восстановить его с помощью serialize?

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


// Создание объекта
$obj = new stdClass();
$obj->name = 'Пример';
$obj->value = 42;

// Сериализация
$ser = serialize($obj);

// Запись в файл
file_put_contents('object.txt', $ser);

// Чтение и восстановление
$data = file_get_contents('object.txt');
$restored = unserialize($data);

Htm php (html и php)

Пояснение: file_put_contents записывает строку в файл, file_get_contents читает её. После unserialize получается исходный объект.

Типичные проблемы:

  • Класс объекта должен быть определён до вызова unserialize, иначе произойдёт ошибка. Если класс изменился, восстановление может привести к некорректным данным.
  • Не следует доверять непроверенным данным: unserialize может привести к выполнению кода (уязвимость). Для безопасной десериализации используется unserialize с фильтрацией или альтернативы.
  • Ресурсы (например, соединения с БД) не сериализуются, их нужно восстанавливать отдельно через магические методы __sleep и __wakeup.

Как сделать объект читаемым для других языков с помощью JSON?

JSON – текстовый формат, поддерживаемый многими языками. Функции json_encode и json_decode преобразуют объект в JSON-строку и обратно. Однако кодируются только публичные свойства, а private и protected теряются. Для сохранения всех свойств можно использовать интерфейс JsonSerializable.


class User {
    public $name;
    private $password;
    public function __construct($name, $password) {
        $this->name = $name;
        $this->password = $password;
    }
    public function jsonSerialize() {
        return ['name' => $this->name, 'password' => '***'];
    }
}
$user = new User('admin', 'secret');
$json = json_encode($user);
file_put_contents('user.json', $json);
$restored = json_decode(file_get_contents('user.json'));
// $restored будет stdClass, а не User

язык разработки php (php (язык разработки))

Пояснение: jsonSerialize управляет тем, что попадает в JSON. При декодировании тип объекта теряется.

Проблемы: JSON не восстанавливает исходный класс, только stdClass. Для восстановления типа нужно дополнительно хранить имя класса или использовать гидратацию. Также json_decode возвращает stdClass по умолчанию, если второй параметр false.

Как сохранить объект в виде самодостаточного PHP кода с var_export?

Функция var_export выводит представление переменной в виде валидного PHP кода. Его можно записать в файл и затем включить через include. Такой файл будет содержать описание объекта, но без методов.


$obj = new stdClass();
$obj->data = [1, 2, 3];

$code = '<?php return ' . var_export($obj, true) . ';';
file_put_contents('object.php', $code);

// Восстановление
$restored = include 'object.php';

Пояснение: var_export($obj, true) возвращает строку, а не выводит её. Файл содержит return, поэтому include возвращает значение. Подходит для кэширования конфигураций.

Проблемы: var_export не обрабатывает ссылки и циклические ссылки (вызовет рекурсию). Для сложных объектов с циклами лучше использовать serialize.

- простой php (простые примеры php)
- Return php (оператор return в php)
- Php return file (возврат файла из функции в php)

Расширенные примеры работы с объектными файлами

Пример 1. Использование магических методов __sleep и __wakeup для управления сериализацией

Пример

class Connection {
    private $pdo;
    private $dsn;
    public function __construct($dsn) {
        $this->dsn = $dsn;
        $this->connect();
    }
    private function connect() {
        $this->pdo = new PDO($this->dsn);
    }
    public function __sleep() {
        // сериализуем только dsn, не сам pdo
        return ['dsn'];
    }
    public function __wakeup() {
        // восстанавливаем соединение
        $this->connect();
    }
}
$conn = new Connection('sqlite::memory:');
$ser = serialize($conn);
// После unserialize соединение будет восстановлено автоматически

Результат: unserialize корректно восстанавливает объект с новым PDO.

Пример 2. Безопасная десериализация с указанием разрешённых классов

Пример

class SafeClass {}
class DangerousClass {}
$obj = new SafeClass();
$ser = serialize($obj);
// Разрешаем только SafeClass
$restored = unserialize($ser, ['allowed_classes' => ['SafeClass']]);
// Если в данных окажется DangerousClass, будет получен __PHP_Incomplete_Class или false в зависимости от версии PHP

Результат: безопасно восстанавливается только указанный класс.

Пример 3. Сериализация в JSON с полным сохранением структуры через JsonSerializable и гидратацию

Пример

class User {
    private $name;
    private $age;
    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }
    public function jsonSerialize() {
        return get_object_vars($this);
    }
    public static function fromJson($json) {
        $data = json_decode($json, true);
        return new self($data['name'], $data['age']);
    }
}
$user = new User('Alice', 30);
$json = json_encode($user);
$restored = User::fromJson($json);
var_dump($restored);

Результат (вывод var_dump):

object(User)#2 (2) {
  ["name":"User":private] =>
  string(5) "Alice"
  ["age":"User":private] =>
  int(30)
}

Пример 4. Сериализация объекта с циклическими ссылками

Пример

class Node {
    public $name;
    public $parent;
    public $children = [];
    public function __construct($name) {
        $this->name = $name;
    }
}
$root = new Node('root');
$child = new Node('child');
$root->children[] = $child;
$child->parent = $root;
// serialize справится с циклическими ссылками (использует рекурсию и пометки)
$ser = serialize($root);
$restored = unserialize($ser);
echo $restored->children[0]->parent->name;

Результат:

root

Объектный файл в PHP - comments

En
Object file php (php)