2011-04-09 49 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