当前位置: 首页> 最新文章列表> 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 作为替代方法,尤其是在涉及简单数据结构时。