Сериализация объектов в PHP: от основ до продвинутых техник
Сериализация — это процесс преобразования сложных структур данных (объектов, массивов) в линейный формат, пригодный для хранения или передачи. В PHP этот механизм особенно важен для сохранения состояния объектов между запросами, передачи данных через API или записи в базы данных. В этой статье мы подробно разберём все аспекты сериализации в PHP.
Что такое сериализация и зачем она нужна?
Сериализация позволяет "заморозить" объект в строку, а затем восстановить его обратно. Это полезно в следующих сценариях:
- Сохранение сессий пользователя (PHP автоматически сериализует данные сессии)
- Кэширование сложных объектов в Redis или Memcached
- Передача объектов между микросервисами
- Хранение конфигураций в файлах
- Отладка и логирование состояния объектов
Базовая сериализация: serialize() и unserialize()
PHP предоставляет две основные функции для работы с сериализацией:
<?php
class User {
public $name;
public $email;
private $password;
public function __construct($name, $email, $password) {
$this->name = $name;
$this->email = $email;
$this->password = $password;
}
}
$user = new User('Иван Петров', 'ivan@example.com', 'secret123');
$serialized = serialize($user);
echo $serialized;
// Вывод: O:4:"User":3:{s:4:"name";s:11:"Иван Петров";s:5:"email";s:16:"ivan@example.com";s:14:"\0User\0password";s:9:"secret123";}
// Восстановление объекта
$unserialized = unserialize($serialized);
echo $unserialized->name; // Иван Петров
?>
Важно: Функция serialize() обрабатывает все свойства объекта, включая приватные и защищённые. Приватные свойства кодируются с префиксом \0ClassName\0, защищённые — \0*\0.
Магические методы __sleep() и __wakeup()
Для контроля над процессом сериализации PHP предоставляет два магических метода:
- __sleep() — вызывается перед сериализацией. Должен вернуть массив имён свойств, которые нужно сериализовать.
- __wakeup() — вызывается после десериализации. Используется для повторной инициализации ресурсов (например, соединений с БД).
<?php
class DatabaseConnection {
private $connection;
private $dsn;
private $username;
private $password;
private $cache = [];
public function __construct($dsn, $username, $password) {
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}
private function connect() {
// Имитация подключения к БД
$this->connection = new stdClass();
$this->connection->connected = true;
}
public function __sleep() {
// Не сериализуем ресурс соединения и пароль
return ['dsn', 'username', 'cache'];
}
public function __wakeup() {
// Восстанавливаем соединение после десериализации
$this->connect();
}
}
$db = new DatabaseConnection('mysql:host=localhost;dbname=test', 'root', 'pass');
$serialized = serialize($db);
$restored = unserialize($serialized);
?>
Сериализация в JSON: json_encode() и json_decode()
JSON — более универсальный формат, поддерживаемый многими языками программирования. В PHP для сериализации в JSON используются функции json_encode() и json_decode().
<?php
class Product {
public $id;
public $name;
public $price;
public function __construct($id, $name, $price) {
$this->id = $id;
$this->name = $name;
$this->price = $price;
}
}
$product = new Product(1, 'Ноутбук', 45000.50);
$json = json_encode($product);
echo $json;
// {"id":1,"name":"Ноутбук","price":45000.5}
// Для восстановления объекта нужно использовать JSON-десериализацию
$data = json_decode($json, true);
$restoredProduct = new Product($data['id'], $data['name'], $data['price']);
?>
Особенности JSON-сериализации:
- Сериализуются только публичные свойства
- Не сохраняется информация о классе (только данные)
- Для