Как работает сериализация объектов?php-39

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

Основные принципы

  1. Сохранение состояния: Сериализация захватывает текущее состояние объекта (значения свойств), но не методы класса.
  2. Иерархия классов: Сохраняется информация о классе объекта и его родительских классах.
  3. Ресурсы и замыкания: Некоторые типы данных (как ресурсы или замыкания) не могут быть сериализованы.

Как работает процесс

Сериализация )

class User {
    public $name = 'John';
    protected $age = 30;
    private $password = 'secret';
}

$user = new User();
$serialized = serialize($user);

Результат будет выглядеть примерно так:

O:4:"User":3:{s:4:"name";s:4:"John";s:6:"*age";i:30;s:15:"Userpassword";s:6:"secret";}

Разберем структуру:

  • O:4:"User" - объект (O) класса User длиной 4 символа
  • 3 - количество свойств
  • Далее пары "ключ-значение" для каждого свойства

Десериализация )

$restoredUser = unserialize($serialized);

При десериализации:

  1. PHP ищет объявление класса с таким же именем
  2. Создает новый объект этого класса
  3. Восстанавливает все свойства

Важные особенности

  1. Магические методы:

    • __sleep() - вызывается перед сериализацией, позволяет указать какие свойства сериализовать
    • __wakeup() - вызывается после десериализации, для восстановления ресурсов
  2. Безопасность:

    • Десериализация непроверенных данных опасна (возможны RCE-атаки)
    • Рекомендуется использовать JSON для сериализации ненадежных данных
  3. Автозагрузка классов:

    • Класс должен быть доступен при десериализации
    • Иначе получим объект класса __PHP_Incomplete_Class

Пример с __sleep и __wakeup

class Session {
    public $data;
    private $dbConnection;

    public function __sleep() {
        return ['data']; // Сериализуем только data
    }

    public function __wakeup() {
        $this->dbConnection = new PDO(...); // Восстанавливаем соединение
    }
}

Альтернативы

  • JSON (json_encode()/json_decode()) - но не поддерживает объекты полностью
  • XML
  • Специализированные форматы (MessagePack, Protocol Buffers)

Резюмируем:

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