2011-04-09 65 views
1

下面是我正在编写的一个类的一部分,它应该关注序列化。 序列化函数工作正常,并生成一个正确的字符串。 问题出在反序列化($ data)函数中。 将正确的序列化字符串传递给反序列化函数中的反序列化。 不幸的是,$ scl对象不包含预期的数据。没有通知或错误抛出。结果是$ scl-> printData()打印信息,但不打印类变量的内容。将来我想将反序列化的结果赋值给$ this。我错过了什么?没有错误抛出,但PHP非序列化不成功

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> 
    ... 
    "; 
} 

回答

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;} 

富是我的测试类的名字,并N被解序列化到null。这就是你失去你的数据的原因。

如果要序列化整个对象,请将所有属性作为数组从__sleep返回,或者根本不要实现它。它和__wakeup都是可选的。

如果你使用PHP 5.3,考虑implementing Serializable相反,因为它有不同的副作用,如果你想运行的代码来处理序列化和反序列化效应


值得一提的,你可能会发现有用你可能会发现自己在这里有一个巨大的安全问题。从URL编码看,您最终可能会通过表单或URL传递序列化对象。这是一个糟糕的主意,特别是如果你正在构建定制的睡眠/唤醒处理。它可以是malicious users to inject arbritary code的载体(PDF链接,从第28页开始)。如果你绝对是必须绕过序列化对象,请考虑它们上的using real encryption,以及signing the data with an HMAC

+0

这工作得很好:) 我不能将反序列化的结果分配给$这现在是不可能的? – jallmer 2011-04-09 05:47:37

+0

@jallmer,正确的,你永远不能将任何*任何*直接指定给'$ this',仅限于属性。另外,我在关于重要安全问题的问题中添加了最后一节。 – Charles 2011-04-09 05:53:27

+0

谢谢,我创建了一个类似于“复制构造函数”的东西来解决问题。 现在,它的工作,我会处理安全问题。 – jallmer 2011-04-09 06:02:31