2012-10-30 15 views
8

Witam Chciałbym zapisać lub zapisać obiekt wewnątrz sesji, używając klas takich jak SessionHandler lub tablice $ _SESSION, Widziałem, że jest to możliwe, jeśli serializuje obiekt i nie chcę stracić metod że instancja obiektu .. widziałem seralizing to jest możliwe, ale przedmioty, co chcę zapisać tworzony jest przez PDOStatement :: fetchObject() althought klasa instancji jest „Użytkownicy” otrzymuję ten błąd:Jak mogę przechowywać obiekty w sesji w PHP?

PDOException: You cannot serialize or unserialize PDO instances Why? It is not a PDO instance..

Przepraszam, jestem hiszpański i nie mówię po angielsku bardzo dobrze .. Dzięki

+1

Pokaż, jak starasz się je szeregować, z wyjątkiem wydaje się, że starasz się szeregować oświadczenie , nie jest to wynik. –

+0

Co powiedział @ dev-null-mieszkaniec. Mogę serializować wynik 'PDOStatement :: fetchObject' po prostu dobrze. –

+0

Jeśli obiekt pochodzi z bazy danych, dlaczego miałbyś go serializować w sesji? Po prostu złap go ponownie z DB. Sesji należy unikać w jak największym stopniu. –

Odpowiedz

14

Natywne sesje PHP $_SESSION w sposób przezroczysty serializują i nie erycjonuj obiekty obsługujące PHP serialization protocol lub Serializable interface. Nie musisz ich jawnie serializować.

PHP nie może serializować resources, ponieważ są one obsługiwane przez pewien stanowy zasób poza kontrolą PHP. Dlatego nie można serializować obiektów PDO ani PDOStatement.

Domyślnie obiekt jest serializowany poprzez zapisanie wszystkich nazw i wartości właściwości i niezsrywalizowany przez utworzenie obiektu z tą samą klasą (bez wywoływania konstruktora) i bezpośrednie ustawienie zserializowanych właściwości. Możesz dostosowywać zachowanie serializacji obiektów za pomocą magicznych metod __sleep i __wakeup lub implementując interfejs Serializable. Ale nie obaj! Jeśli używasz implements Serializable, __sleep i __wakeup są ignorowane.

Jedna ważna uwaga: podczas korzystania z obiektu serializacji, ty musi mieć definicja klasy ładowane zanim unserialize (lub mieć autoloadery że można go obciążenia) i musi dopasować definicję klasy obiektu, który był serializowany. Definicje klas nie są przechowywane w zserializowanych danych.

Na przykład załóżmy, że masz następujące elementy:

class Test { 
    public $version = 1; 
    protected $abc; 
    public function setAbc($abc) { 
     $this->abc = $abc; 
    } 
} 

$t = new Test(); 
$t->setAbc(123); 
$_SESSION['mytest'] = $t; 

Teraz wyobraź sobie zmienić Test jeden dzień, aby być tak zamiast:

class Test { 
    public $version = 2; 
    private $def; 
    public function setDef ($def) { 
     $this->def = $def; 
    } 
} 

Załóżmy teraz załadować do nowego kodu źródłowego obiektu odcinkach gdy Test był w wersji 1:

$t = $_SESSION['mytest']; // this was stored yesterday, when Test was version 1 

var_dump($t) 

Dostaniesz to:

object(Test)#1 (3) { 
    ["version"]=> 
    int(1) 
    ["def":"Test":private]=> 
    NULL 
    ["abc":protected]=> 
    int(123) 
} 

Ponadto, nie można używać starych metod:

if ($t->version == 1) { // Check for class version 
    $t->setAbc(345); // "Fatal error: Call to undefined method Test::setAbc()" 
} 
+0

Dzięki temu rozwiązałem mój problem, ale mam nowy problem, na tej klasie przekazuję obiekt PDO w __constructor (który jest połączony z MySQL) i ustawiam zmienną składową na obiekt PDO, ale kiedy odserializuję "obiekt kontenera" nie wykonuje funkcji __constructor, więc zmienna składowa, która jest obiektem PDO, nie zostanie ustawiona. Jak mogę to rozwiązać? Dzięki – Carlos

+3

Zostało to wyjaśnione w odpowiedzi. Konstruktory nie są wykonywane, ponieważ obiekt jest * przywrócony * nie * zainicjowany *. Utwórz metodę '__wakeup()' lub 'Serializer'' unserialize() ', która robi to, co chcesz, lub dodaj metodę' setPDO() 'i ręcznie ustaw obiekt PDO. Ostatecznie, ** nie powinieneś serializować obiektów, które zawierają zasoby **! Użyj innego projektu klasy. –

+0

Dziękuję bardzo, podoba mi się twój pomysł dodając metodę setPDO, masz rację :) – Carlos

Powiązane problemy