2016-11-27 79 views
7

我有一個複雜的結構,它使用sericalize()函數保存在MySQL數據庫中,然後使用unserialize()轉換回來。將系統從PHP 5.3遷移到PHP 5.6並在5.6中反序列化5.3中序列化的數據後,結構已損壞。對象的某些引用現在顯示爲數組。將PHP序列化從PHP 5.3遷移到PHP 5.6

我的問題是:

  1. 是否有關於不同的PHP版本使用的序列化/反序列化不同的編碼規範? (在我的Google搜索或PHP.net文檔中找不到任何具體的東西)

  2. 如何將序列化數據從PHP 5.3編碼轉換爲PHP 5.6編碼?

+0

你好, 你能提供更多關於beeing序列化的信息嗎?它是一個類還是一組數據? –

+1

反序列化對象時,必須在代碼中包含類定義。因此,如果您在存儲對象的位置以外的常規代碼庫之外進行測試,或者如果您更改了對象結構,那麼它們將不會正確反序列化。如果您需要更改對象結構,請保留舊對象,然後使用新結構重新創建新對象並重新進行串行化。 (不作爲答案張貼,因爲我無法測試它 - 但它們是需要查找的東西!) – Robbie

回答

1

你可以轉換成串行數據,以JSON(使用PHP 5.3的安裝),保存到數據庫中,然後執行opposit(使用PHP 5.6的安裝)。

從5.3到JSON:

$data = unserialize($strSerializedData); 
$jsonData = json_encode($data); 

從JSON到5.6:

$data = json_decode($jsonData); 
$strSerializedData= serialize($data); 

您可能需要調整您發送到json_decode以匹配原始數據的選項。

此選項將取決於正在序列化的數據。如果你的數據是類,這是行不通的。沒有調用構造函數來強制對象實例化將:

此外,您的問題可能與本說明文檔中(here):

5.6.0通過更換ç操縱序列數據:帶O現在失敗了。

+0

由於問題是關於對象的serliazation /反序列化,並且您正確地指出「如果您的數據是類,這是行不通的。「那麼是的 - 這是行不通的。你可以在這個類中創建一個「toJSON()」方法和「fromJSON()」,並使用它來訪問內部,但是如果你走得太遠,那麼你也可以寫你自己的serliaze /反序列化函數!爲此,請使用'serializable'接口(http://php.net/manual/en/class.serializable.php) – Robbie

+0

同意這不適用於一個類。這個問題需要澄清。 –

+0

它確實是我正在序列化的一個類的一個對象。該對象具有對同一類的對象以及其他類的引用。其中一些類依次引用它們引用的對象。使用serialize(),這些交叉引用用r表示:後跟一個數字。其中一些引用在php 5.6中反序列化時會被破壞,而數組中的類對象應該是什麼。 –

2

是的,在PHP5.6中更改了對象的序列化。具體的一些相關對象的序列化領域PHP5.6中渡過了

有一個模糊的音符在PHP unserialize manual提的是:

5.6.0通過更換ç操縱序列化的數據:與O:強制對象實例化而不調用構造函數,現在將失敗 。

但是看看bug列表可以發現,在report 68099的引擎蓋下還有一點點。報告還指出,原來的格式沒有正式的文件:

「原來的行爲(我們允許使用舊的序列化格式 使用新的格式類)從未被記錄在案,也不 正式支持,」

請注意,該討論的最終結果是「不會修復」

所以基本上,你的選擇是:

  • 嘗試其他串行如出口PHP版本之間數據的方式之一。如session_encode其中還可以處理對象。

  • 轉換腳本。有一個 的 的廣泛文檔版本PHP internals的當前格式,您可以與舊格式的 迭代器一起使用以更新語法。