sessioni native di PHP $_SESSION
in modo trasparente serializza e uns erializzare oggetti che supportano il serialization protocol di PHP o lo Serializable
interface. Non è necessario serializzarli esplicitamente.
PHP non può serializzare resources
perché si tratta di handle per alcune risorse stateful al di fuori del controllo di PHP. Questo è il motivo per cui non è possibile serializzare gli oggetti PDO
o PDOStatement
.
Per impostazione predefinita, un oggetto viene serializzato salvando tutti i nomi di proprietà e valori e non serializzati creando un oggetto con la stessa classe (senza richiamare il costruttore) e impostando direttamente le proprietà serializzate. È possibile personalizzare il comportamento di serializzazione per gli oggetti utilizzando i metodi magici __sleep
e __wakeup
o implementando l'interfaccia Serializable
. Ma non entrambi! Se si utilizza implements Serializable
, __sleep
e __wakeup
vengono ignorati.
Una nota importante: quando si utilizzano serializzazione degli oggetti, si necessario avere la definizione di classe caricato prima di unserialize (o avere un caricatore automatico che può caricarlo) e necessario corrispondere alla definizione della classe dell'oggetto che è stato serializzato. Le definizioni di classe non sono memorizzate nei dati serializzati.
Per esempio si supponga di avere il seguente:
class Test {
public $version = 1;
protected $abc;
public function setAbc($abc) {
$this->abc = $abc;
}
}
$t = new Test();
$t->setAbc(123);
$_SESSION['mytest'] = $t;
Ora immaginate si cambia Test
un giorno per essere come questo, invece:
class Test {
public $version = 2;
private $def;
public function setDef ($def) {
$this->def = $def;
}
}
Ora supponiamo che si carica nel nuovo codice di un oggetto serializzato quando Test
era alla versione 1:
$t = $_SESSION['mytest']; // this was stored yesterday, when Test was version 1
var_dump($t)
Otterrete questo:
object(Test)#1 (3) {
["version"]=>
int(1)
["def":"Test":private]=>
NULL
["abc":protected]=>
int(123)
}
Inoltre, non è possibile utilizzare i vecchi metodi:
if ($t->version == 1) { // Check for class version
$t->setAbc(345); // "Fatal error: Call to undefined method Test::setAbc()"
}
Mostrare come stai cercando di serializzare esso, dal l'eccezione sembra che si sta cercando di serializzare dichiarazione , non è il risultato. –
Cosa dice @ dev-null-dweller. Posso serializzare il risultato di 'PDOStatement :: fetchObject' bene. –
Se l'oggetto proviene dal database, perché dovresti serializzarlo in una sessione? Prendilo di nuovo dal DB. Le sessioni dovrebbero essere evitate il più possibile. –