PHP的原生$_SESSION
會話透明地序列化和uns對支持PHP的serialization protocol或Serializable
interface的對象進行字符串化。你不需要明確地序列化它們。
PHP無法序列化resources
,因爲它們是PHP控制之外的某些有狀態資源的句柄。這就是爲什麼你不能序列化PDO
或PDOStatement
對象。
默認情況下,通過保存所有屬性名稱和值,並通過創建具有相同類的對象(不調用構造函數)並直接設置序列化屬性來反序列化對象。您可以使用__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()"
}
展示你是如何試圖序列化,從異常似乎您試圖序列化語句,不是結果。 –
@ dev-null-dweller說了些什麼。我可以序列化「PDOStatement :: fetchObject」的結果。 –
如果對象來自數據庫,那麼爲什麼要在會話中序列化它?只需從DB再次抓取它。應儘可能避免會議。 –