當前位置: 首頁> 最新文章列表> PHP 中如何用unserialize 函數還原session 數據?實例講解

PHP 中如何用unserialize 函數還原session 數據?實例講解

gitbox 2025-09-30

1. session的工作原理

PHP 的session通過使用唯一的會話ID 將用戶的數據保存在服務器端。每次用戶發出請求時,PHP 會查找該會話ID,並加載對應的會話數據。數據通常是通過$_SESSION超全局變量進行存取的。

PHP 在內部自動使用serialize函數將對像或數組等數據轉化為字符串存儲,並且用unserialize函數將其還原為原始數據類型。

不過,有時我們希望直接訪問這些序列化後的數據,或者手動處理它們,這時unserialize函數就顯得尤為重要。


2. unserialize函數概述

unserialize函數用於將序列化的字符串轉化為PHP 變量。

 <span><span><span class="hljs-keyword">mixed</span></span><span> </span><span><span class="hljs-title function_ invoke__">unserialize</span></span><span> ( </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$data</span></span><span> [, </span><span><span class="hljs-keyword">array</span></span><span> </span><span><span class="hljs-variable">$options</span></span><span> = [] ] )
</span></span>

參數說明:

  • $data :要反序列化的字符串。

  • $options :可選的參數,提供額外的反序列化控制(PHP 7+ 支持)。例如,可以指定允許反序列化的類。

返回值:

  • 成功時返回反序列化後的變量,失敗時返回false


3. 示例:手動序列化並反序列化session 數據

步驟一:模擬session 數據存儲

假設我們有一個用戶對象,裡麵包含了一些用戶的基本信息。我們將會手動將該對象序列化,並存儲在session 中。

 <span><span><span class="hljs-title function_ invoke__">session_start</span></span><span>();

</span><span><span class="hljs-comment">// 創建一個用戶對象</span></span><span>
</span><span><span class="hljs-class"><span class="hljs-keyword">class</span></span></span><span> </span><span><span class="hljs-title">User</span></span><span> {
    </span><span><span class="hljs-keyword">public</span></span><span> </span><span><span class="hljs-variable">$name</span></span><span>;
    </span><span><span class="hljs-keyword">public</span></span><span> </span><span><span class="hljs-variable">$email</span></span><span>;

    </span><span><span class="hljs-keyword">public</span></span><span> </span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">__construct</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$name</span></span></span><span>, </span><span><span class="hljs-variable">$email</span></span><span>) {
        </span><span><span class="hljs-variable language_">$this</span></span><span>-&gt;name = </span><span><span class="hljs-variable">$name</span></span><span>;
        </span><span><span class="hljs-variable language_">$this</span></span><span>-&gt;email = </span><span><span class="hljs-variable">$email</span></span><span>;
    }
}

</span><span><span class="hljs-comment">// 實例化用戶對象</span></span><span>
</span><span><span class="hljs-variable">$user</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title class_">User</span></span><span>(</span><span><span class="hljs-string">'John Doe'</span></span><span>, </span><span><span class="hljs-string">'[email protected]'</span></span><span>);

</span><span><span class="hljs-comment">// 將用戶對象序列化後存入 session</span></span><span>
</span><span><span class="hljs-variable">$_SESSION</span></span><span>[</span><span><span class="hljs-string">'user_data'</span></span><span>] = </span><span><span class="hljs-title function_ invoke__">serialize</span></span><span>(</span><span><span class="hljs-variable">$user</span></span><span>);
</span></span>

在上面的代碼中,我們創建了一個User類,並將一個用戶對象John Doe序列化後存儲到$_SESSION['user_data']中。

步驟二:還原(反序列化) session 數據

一旦數據存入session,我們可以在隨後的請求中恢復它。通過unserialize函數,我們能夠將存儲在session 中的序列化數據還原為原始的對象形式。

 <span><span><span class="hljs-title function_ invoke__">session_start</span></span><span>();

</span><span><span class="hljs-comment">// 檢查 session 中是否有 'user_data' 數據</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-keyword">isset</span></span><span>(</span><span><span class="hljs-variable">$_SESSION</span></span><span>[</span><span><span class="hljs-string">'user_data'</span></span><span>])) {
    </span><span><span class="hljs-comment">// 反序列化 session 數據</span></span><span>
    </span><span><span class="hljs-variable">$user</span></span><span> = </span><span><span class="hljs-title function_ invoke__">unserialize</span></span><span>(</span><span><span class="hljs-variable">$_SESSION</span></span><span>[</span><span><span class="hljs-string">'user_data'</span></span><span>]);

    </span><span><span class="hljs-comment">// 輸出用戶信息</span></span><span>
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">'Name: '</span></span><span> . </span><span><span class="hljs-variable">$user</span></span><span>-&gt;name . </span><span><span class="hljs-string">'&lt;br&gt;'</span></span><span>;
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">'Email: '</span></span><span> . </span><span><span class="hljs-variable">$user</span></span><span>-&gt;email . </span><span><span class="hljs-string">'&lt;br&gt;'</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">'No user data found in session.'</span></span><span>;
}
</span></span>

在這段代碼中,我們首先檢查$_SESSION['user_data']是否存在。如果存在,我們使用unserialize函數將其還原為User對象,然後輸出該對象的屬性。


4. 使用unserialize函數的注意事項

安全性問題

使用unserialize函數時,必須特別注意安全性問題。尤其是反序列化來自不可信源的數據時,可能導致對象注入攻擊。這可能會讓攻擊者通過構造惡意的序列化數據來執行危險的操作。因此,推薦在使用unserialize時,添加安全措施來避免此類問題。

在PHP 7+ 中,可以通過設置allowed_classes選項來限制反序列化的類。例如,限制只能反序列化User類:

 <span><span><span class="hljs-variable">$options</span></span><span> = [</span><span><span class="hljs-string">'allowed_classes'</span></span><span> =&gt; [</span><span><span class="hljs-string">'User'</span></span><span>]];
</span><span><span class="hljs-variable">$user</span></span><span> = </span><span><span class="hljs-title function_ invoke__">unserialize</span></span><span>(</span><span><span class="hljs-variable">$_SESSION</span></span><span>[</span><span><span class="hljs-string">'user_data'</span></span><span>], </span><span><span class="hljs-variable">$options</span></span><span>);
</span></span>

這樣,只有User類的對象才能被反序列化,其他類則會被阻止。

反序列化時的兼容性問題

在跨版本或跨服務器的PHP 環境中, unserialize可能會遇到兼容性問題。例如,如果某個類在不同版本中發生了變化,反序列化時可能會失敗。為避免這種問題,開發者可以使用json_encodejson_decode作為替代方法,尤其是在涉及簡單數據結構時。