下面是我目前正在编写的类的一部分,它应该负责序列化。serialize函数工作正常,并生成一个合适的字符串。问题出在反序列化($data)函数中。在反序列化函数中传递正确的序列化字符串以进行反序列化。不幸的是,$scl对象不包含预期的数据。没有提示或错误被抛出。结果是$scl->printData()打印信息,但不打印类变量的内容。将来我想把unserialize的结果赋值给$this。我错过了什么?
public function serialize() {
$serial = serialize($this);
$df = gzdeflate($serial);
$b64 = base64_encode($df);
$ue = urlencode($b64);
return($ue);
}
public function deserialize($data) {
$u64 = base64_decode($data);
$gf = gzinflate($u64);
$scl = unserialize($gf);
if(!$scl)
echo"Cannot unserialize<br>";
$scl->printData();
}
function __sleep() {
return($this);
}
function __wakeup() {
echo"Waking up";
}
public function printData() {
echo"Data: <br>
ID: {$this->ID} <br>
sID: {$this->sID}<br>
...
";
}
__sleep
应该返回一个应该被序列化的键数组。你正在返回对象。
你应该收到以下通知:
serialize(): __sleep should return an array only containing the names of instance-variables to serialize.
如果你没有看到这个,确保你把错误报告打开了。
因为返回的是一个对象而不是要序列化的键数组,所以序列化后的对象最终看起来像:
O:3:"Foo":1:{N;}
Foo是我的测试类名,N
未序列化为null
。这就是你丢失数据的原因。
如果你想序列化整个对象,要么从__sleep
返回所有属性作为数组,要么根本不实现它。它和__wakeup
都是可选的。
如果您正在使用PHP 5.3,考虑实现Serializable
,因为它有不同的副作用,如果您试图运行代码来处理序列化和反序列化效果,您可能会发现它很有用
值得注意的是,您可能会在这里发现一个巨大的安全问题。从url编码来看,您最终可能会通过表单或url传递序列化的对象。这是一个非常非常糟糕的主意,特别是如果你正在构建自定义睡眠/唤醒处理。它可以成为恶意用户注入任意代码的载体(PDF链接,从第28页开始)。如果您绝对必须在野外传递序列化对象,请考虑对它们使用真实的加密,并使用HMAC对数据签名。