在PHP开发中,我们经常会遇到这样的场景:通过表单提交数据后想要更新一个数组,但是下次刷新页面或者再次提交表单时,数组又回到了初始状态,没有保留之前的修改。这种现象的核心原因是HTTP协议的无状态特性,以及PHP脚本的生命周期限制。

为什么数组无法持续更新
PHP脚本的运行模式是每次请求触发一次独立的执行过程,脚本执行开始时初始化所有变量,执行结束后所有变量都会被释放,内存中的数据不会自动保留到下一次请求。我们定义的数组属于脚本运行时的临时变量,表单提交只是触发了一次新的脚本执行,之前的数组数据早就不存在了。
比如下面这段常见的错误代码:
<?php
// 错误示例:直接定义临时数组尝试持久化
$user_list = ['张三', '李四'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$new_name = $_POST['name'] ?? '';
if (!empty($new_name)) {
$user_list[] = $new_name; // 只在当前请求生效
}
}
?>
<form method="post">
<input type="text" name="name" placeholder="输入姓名">
<button type="submit">添加</button>
</form>
<p>当前用户列表:</p>
<ul>
<?php foreach ($user_list as $user): ?>
<li><?php echo $user; ?></li>
<?php endforeach; ?>
</ul>
每次提交表单后,页面显示的列表只会包含张三、李四和新提交的姓名,再次刷新页面又会回到只有张三、李四的状态,因为$user_list每次都是重新初始化的临时变量。
状态持久化的常见方案
要让数组数据在多次请求之间保留,就需要把数据存储到脚本执行周期之外的地方,常见的方案有以下几种:
- Cookie存储:数据保存在客户端浏览器,每次请求会自动携带,但是存储容量小,且不适合存储敏感或复杂数据。
- 文件存储:把数组序列化后保存到服务器文件,每次请求读取文件恢复数据,适合少量数据的持久化。
- 数据库存储:把数据保存到数据库,适合需要长期存储、数据量大的场景,但是操作成本较高。
- Session存储:数据保存在服务器端,和单个用户会话绑定,使用简单,适合存储用户相关的临时状态数据。
使用Session实现数组持续更新
Session是PHP中最常用的状态持久化方案,它会为每一个访问用户分配一个唯一的会话ID,对应的数据保存在服务器上,通过会话ID来关联用户和数据。使用Session只需要开启会话,然后把数组存储到$_SESSION超全局数组中即可。
Session的基本使用步骤
- 调用
session_start()函数开启会话,必须在输出任何内容之前调用。 - 通过
$_SESSION数组读写需要持久化的数据。 - 脚本执行结束后,Session数据会自动保存,下次同一用户访问时可以直接读取。
正确的数组更新示例
下面是使用Session解决数组无法持续更新问题的完整代码:
<?php
// 开启会话,必须在最顶部,之前不能有任何输出
session_start();
// 初始化Session中的用户列表,判断是否存在,不存在则初始化
if (!isset($_SESSION['user_list'])) {
$_SESSION['user_list'] = ['张三', '李四'];
}
// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$new_name = $_POST['name'] ?? '';
if (!empty($new_name)) {
// 直接操作Session中的数组,修改会持久化
$_SESSION['user_list'][] = $new_name;
}
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户列表管理</title>
</head>
<body>
<form method="post">
<input type="text" name="name" placeholder="输入姓名">
<button type="submit">添加</button>
</form>
<p>当前用户列表:</p>
<ul>
<?php foreach ($_SESSION['user_list'] as $user): ?>
<li><?php echo htmlspecialchars($user); ?></li>
<?php endforeach; ?>
</ul>
</body>
</html>
这段代码中,用户列表数组存储在$_SESSION['user_list']里,每次表单提交添加的新姓名都会保存到Session中,即使刷新页面或者多次提交,数组都会持续更新,不会丢失之前的数据。
Session使用的注意事项
session_start()必须在使用$_SESSION之前调用,且不能在它之前输出任何HTML内容或者空格,否则会报错。- Session数据保存在服务器端,会占用服务器资源,不需要的数据要及时清理,比如调用
unset($_SESSION['user_list'])删除对应数据。 - 用户关闭浏览器后,Session默认不会立即删除,需要等待会话过期时间(默认一般是1440秒)才会自动清理。
- 如果需要存储复杂的数据结构,Session会自动处理序列化,不需要手动调用
serialize和unserialize函数。
不同场景的方案选择
如果数组数据只需要临时保存,和用户会话绑定,优先选择Session;如果数据需要所有用户共享,或者需要长期保存,可以选择文件存储或者数据库存储;如果数据量很小,且不需要考虑安全性,也可以使用Cookie存储。理解不同方案的适用场景,才能更合理地解决状态持久化的问题。