2012-10-30 71 views
8

你好我想存儲或保存一個會話內的對象,使用像SessionHandler或數組$ _SESSION類,我已經看到,如果我序列化對象是可能的,我不想失去的方法該對象實例.. 我見過seralizing這是可能的,但我希望存儲的對象是通過PDOStatement對象:: fetchObject()althought的實例類是「用戶」我得到這個錯誤產生:如何將對象存儲在PHP中的會話中?

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

對不起,我是西班牙語,我不會說英語很好.. 謝謝

+1

展示你是如何試圖序列化,從異常似乎您試圖序列化語句,不是結果。 –

+0

@ dev-null-dweller說了些什麼。我可以序列化「PDOStatement :: fetchObject」的結果。 –

+0

如果對象來自數據庫,那麼爲什麼要在會話中序列化它?只需從DB再次抓取它。應儘可能避免會議。 –

回答

14

PHP的原生$_SESSION會話透明地序列化和uns對支持PHP的serialization protocolSerializable interface的對象進行字符串化。你不需要明確地序列化它們。

PHP無法序列化resources,因爲它們是PHP控制之外的某些有狀態資源的句柄。這就是爲什麼你不能序列化PDOPDOStatement對象。

默認情況下,通過保存所有屬性名稱和值,並通過創建具有相同類的對象(不調用構造函數)並直接設置序列化屬性來反序列化對象。您可以使用__sleep__wakeup魔術方法或通過實現Serializable接口來自定義對象的序列化行爲。但不是兩個!如果使用implements Serializable,則會忽略__sleep__wakeup

一個重要的提示:使用對象序列化時,你必須有你反序列化(或者有可以加載它自動加載磁帶機)之前類定義加載它必須匹配的對象的類定義被序列化。類定義不存儲在序列化數據中。

例如,假設你有以下幾種:

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

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

現在想象你改變Test一天是這樣,而不是:

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

現在假設你加載到您的新代碼序列化的對象當Test處於版本1時:

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

var_dump($t) 

你會得到這樣的:

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

而且,你不能用老辦法:

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

感謝它解決了我的問題,但我有一個新的問題,在該類我傳遞__constructor(即連接到MySQL)的PDO對象,我設置一個成員變量PDO對象,但是當我反序列化「容器對象」它不會執行__constructor函數,所以作爲PDO對象的成員變量將不會被設置。 我該如何解決它?謝謝 – Carlos

+3

這是在答案中解釋。構造函數不會執行,因爲對象被*恢復*不*初始化*。根據需要創建'__wakeup()'或'Serializer'接口'unserialize()'方法,或者添加一個'setPDO()'方法並手動設置PDO對象。底線,但是,**你不應該序列化包含資源**的對象!使用不同的課程設計。 –

+0

非常感謝你,我喜歡你的想法添加一個setPDO方法,你是對的:) – Carlos