不会抛出任何错误,但PHP反序列化不会成功

时间:2011-04-09 05:25:33

标签: php class serialization

下面是我正在编写的类的一部分,它应该处理序列化。 serialize函数工作正常,并生成一个正确的字符串。 问题出在反序列化($ data)函数中。 在deserialize函数中传递正确的序列化字符串以反序列化。 不幸的是,$ 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>
    ...
    ";
}

1 个答案:

答案 0 :(得分:3)

__sleep是应该序列化的supposed to return an array个键。你正在归还这个物体。

收到以下通知:

  

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,请考虑使用implementing Serializable,因为它有不同的副作用,如果您尝试运行代码来处理序列化和反序列化效果,则可能会发现这些副作用很有用


值得注意的是,您可能会发现自己遇到了巨大的安全问题。从URL编码看,您最终可能会通过表单或URL传递序列化对象。这是一个糟糕的坏主意,特别是如果你正在构建自定义睡眠/唤醒处理。它可以是malicious users to inject arbritary code的向量(PDF链接,从第28页开始)。如果您绝对必须在野外传递序列化对象,请考虑using real encryptionsigning the data with an HMAC