сериализация в php

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

У нас есть какой-то класс, мы создали от него объект. Если мы хотим все это сериализовать, то нужно описать два магических метода: __sleep и __wakeup. Метод __sleep возвращает массив, т.е. мы должны вернуть массив тех свойств, которые хотим засериализовать (а то что не пропишем, удалится).

После создания объекта (см. код ниже) вызываем функцию serialize. Получим, что два свойства (varA и varB) сериализуются (т.е. сохранятся). В результате отработки кода выскочит ошибка уровня NOTICE (предупреждение), что нет доступа к приватной переменной varA. На помощь приходят методы сериализации.

class A {
   private $varA;
   function __construct(){
      $this->varA = 'A';}
}
class B extends A{
   private $varB;
   function __construct(){
      parent::__construct();
      $this->varB = 'B';}
   function __sleep(){
      return array ('varB','varA');}
}
$obj = new B();
$serialized = serialize($obj);

Механизм сериализации

inrerface Serializable {
   public function serialize();
   public function unserialize ($serialized);}

С помощью двух методов можем перегрузить serialize, unserialize глобальные, чтобы избежать ошибки в первом примере.

Перепишем наш код таким способом:

class A implement Serializable{
   private $varA;
   function __construct(){
      $this->varA = 'A';}
   function serialize(){ //сериализация внутри
      return serialize ($this->varA);}
   function unserialize ($serialized){ //возвращаем все назад
      $this->varA = unserialize($serialize);}
}
class B extends A{
   private $varB;
   function __construct(){
      parent::__construct();
      $this->varB = 'B';}
   function serialize(){ //перегружаем serialize
      $sSerialized = parent::serialize(); //вызов родительского serialize, вернет varA
      return serialize(array($this->varB, $sSerialized));}
   function unserialize($serialize){ //перегружаем unserialize
      $tmp = unserialize($serialized);
      $this->varB = $tmp[0]; //передаем первый элемент массива varB
      parent::unserialize($tmp[1]);} //второй элемент массива varA
}
$obj = new B();
$serialized = serialize($obj); //сериализация

Теперь у нас сохранились varA и varB. Т.е. мы дотянулись до приватного свойства внутри класса-родителя.




Добавить комментарий

Ваш e-mail не будет опубликован.