Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Serializable w klasie ArrayObject
Forum PHP.pl > Forum > PHP > Object-oriented programming
bongdigibonbon
Witam
W jaki sposób zaimplementować metody interfejsu Serializable lub metody __sleep, __wakeup w klasie dziedziczącej po ArrayObject, aby zachować zarówno dane przechowywane w obiekcie danej klasy jak i klasy bazowej.
Przykład:
  1. <?php
  2. class A extends ArrayObject {
  3.        private $_skladowa;
  4.        public function __construct() {
  5.            $this->_skladowa=true;
  6.        }
  7.        public function getSkladowa() { return $this->_skladowa; }
  8.    }
  9.  
  10.    $a=new A();
  11.    $a->append('Jeden');
  12.    $a->append('Dwa');
  13.  
  14.    $b=unserialize(serialize($a));
  15. ?>

W tym przypadku obiekt "b" posiada wartości 'Jeden', 'Dwa', ale składowa "_skladowa" ma wartość null.
LBO
  1. <?php
  2.  
  3. class A extends ArrayObject implements Serializable {
  4.  
  5.    // twoje metody i atrybuty
  6.    
  7.    public function serialize()
  8.    {
  9.        // zserializuj co chcesz
  10.    }
  11.  
  12.    public function unserialize($serialized)
  13.    {
  14.        // odtwórz
  15.    }
  16. }
  17.  
  18. ?>
Sergiusz
Ciekawy problem,
Wiadomo, ze w interfejsie Serializable istnieja metody serialize i unserialize.
Pytanie tylko jak je zaimplementowac tak aby zachowac dane w obiekcie klasy.

  1. <?php
  2. public function serialize() {
  3.       return serialize($this);
  4. }
  5. ?>

Przeciez wywolanie funkcji serialize() w metodzie serialize interfejsu Serializable powoduje zapetlenie.
LBO
Nic się nie zapętla, spokojnie smile.gif

Serializable::serialize() zwraca zserializowane zmienne, który są wtłaczane w zserializowany - ogólny - string obiektu.
Serializable::unserialize($data) dostaje ten string (wyciągnięty z tego ogólnego) jako parametr i musisz sam go sobie rozserializować, wyciagnąć interesujące Ciebie dane i wszystko w obiekcie ustawić.

Odrobinę się to różni od __sleep() i __wakeup()

edit:

Zapomniałem zaznaczyć, że dzięki temu nie musisz wcale używać domyślnego formatu serializowania PHP. Możesz własny np. atrybuty po przecinkach.
Sergiusz
Chyba nie chcesz mi powiedziec, ze trzeba serializowac i deserializowac oddzielnie kazde pole/zmeinna w obiekcie? smile.gif
LBO
Nie no, zbierasz je sobie do kupy i zwracasz w metodzie. To jak je sobie zbierzesz to zależy od Ciebie.
bongdigibonbon
Czyli tak?

  1. <?php
  2. public function serialize() {
  3.            // Pobranie danych z ArrayObject.
  4.            $arrayObject=$this->getArrayCopy();
  5.            // Pobranie wszystkich składowych obiektu.
  6.            $zmienna1=$this->zmienna1;
  7.            $zmienna2=$this->zmienna2;
  8.            // ...
  9.            // Zwrócenie własnej struktury.
  10.            return serialize(compact('arrayObject', 'zmienna1', 'zmienna2' /* , ... */));
  11.        }
  12.        public function unserialize($string) {
  13.            extract(unserialize($string));
  14.            // Wycztanie danych do arrayObject
  15.            parent::__construct($arrayObject);
  16.            // Wczytanie wszytkich zmiennych.
  17.            $this->zmienna1=$zmienna1;
  18.            $this->zmienna2=$zmienna2;
  19.            // ...
  20.        }
  21. ?>


Wszystkie właściwości obiektu należy ustawiać ręcznie? Nie ma na to innego sposobu?
LBO
A zwykłe __sleep i __wakeup być nie może?
bongdigibonbon
Nie może. Metoda __sleep() zwraca tablicę nazw składowych, które mają być serializowane. Nie ma jawnej składowej w klasie ArrayObject, w której przechowywane są dane. Dostęp jest jedynie przez metodę.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.