【问题标题】:No error is thrown but PHP unserialization doesn't succeed没有抛出错误,但 PHP 反序列化不成功
【发布时间】:2011-08-01 23:09:01
【问题描述】:

下面是我目前正在编写的一个类的一部分,它应该负责序列化。 serialize 函数工作正常,并生成了正确的字符串。 问题出在反序列化($data)函数中。 将正确的序列化字符串传递给反序列化函数中的反序列化。 不幸的是,$scl 对象不包含预期的数据。没有通知或错误抛出。结果是 $scl->printData() 打印信息但不打印类变量的内容。将来我想将反序列化的结果分配给 $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>
    ...
    ";
}

【问题讨论】:

    标签: php class serialization


    【解决方案1】:

    __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 将所有属性作为数组返回,要么根本不实现它。 it 和__wakeup 都是可选的。

    如果您使用的是 PHP 5.3,请考虑使用 implementing Serializable,因为它具有不同的副作用,如果您尝试运行代码来处理序列化和反序列化效果,您可能会发现这些副作用很有用


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

    【讨论】:

    • 效果很好 :) 我现在无法将反序列化的结果分配给 $this,这不可能吗?
    • @jallmer,正确,您永远不能将 anything 直接分配给 $this,只能分配给属性。此外,我在关于一个重要安全问题的问题中添加了最后一部分。
    • 谢谢,我创建了一个类似“复制构造函数”的东西来解决这个问题。现在它可以工作了,我将处理安全问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    相关资源
    最近更新 更多