php变量每次请求消失是因为http无状态特性导致每个请求启动全新进程,局部变量、$_post等随脚本结束销毁;需用$_session、cookie、数据库或redis等方案按需持久化状态。

PHP里变量为什么每次请求就消失
PHP默认是无状态的:每个HTTP请求都启动一个全新脚本进程,$_GET、$_POST、局部变量、甚至$user_id这种自定义变量,请求一结束就彻底销毁。这不是bug,是设计使然——你不能指望$count++在用户第二次刷新时还带着上次的值。
常见错误现象:
– 登录后跳转页面,$_SESSION['user']为空
– 表单提交后用$_POST存了临时数据,下个页面读不到
– 用static $cache = []想跨请求缓存,结果每次都是空数组
- 别依赖全局变量或文件作用域变量来“保持”状态
- 函数内
static只对单次请求有效,不是会话级缓存 - CLI模式下变量能活久一点,但Web请求永远重启进程
session_start()必须在输出前调用
这是最常踩的坑:只要有任何HTML、空格、echo、BOM头出现在session_start()之前,就会报headers already sent错误,导致$_SESSION写入失败,后续请求读不到数据。
使用场景:登录态、购物车、表单步骤流转
立即学习“PHP免费学习笔记(深入)”;
- 确保
session_start()是脚本最开头几行之一(可放在include配置文件里统一处理) - 检查所有被
include或require的文件,有没有意外输出(比如UTF-8 BOM、结尾空行) - 开发时打开
error_reporting(E_ALL),这类错误不会静默失败,但容易被忽略 -
session_start()之后才能读写$_SESSION,且修改会自动在脚本结束时保存
$_SESSION不是万能的,注意生命周期和大小限制
$_SESSION靠服务端文件或Redis等存储,默认有效期由session.gc_maxlifetime控制(通常1440秒=24分钟),不等于浏览器关闭或用户登出。它适合存用户身份、少量上下文,不适合大对象或长期缓存。
性能与兼容性影响:
– 文件型session在高并发下可能锁文件,导致请求阻塞
– $_SESSION序列化时遇到资源类型(如mysqli连接)会直接失败
– 跨子域名需手动设session_set_cookie_params(['domain' => '.example.com'])
- 敏感数据(如密码、token)不要直接塞进
$_SESSION,至少做一次hash_hmac()校验 - 大数组建议只存ID,用ID查数据库或缓存,避免session文件膨胀
- 登出时务必调用
$_SESSION = []+session_destroy()+setcookie()删客户端cookie
替代方案:什么时候该用cookie、数据库或缓存
$_COOKIE适合存轻量、非敏感、客户端可读的标识(如语言偏好、主题色);数据库适合需要持久、关联查询的数据(如订单步骤);Redis/Memcached适合高频读写、需主动失效的临时状态(如短信验证码、防刷计数)。
参数差异举例:
– setcookie('theme', 'dark', ['expires' => time()+86400, 'secure' => true, 'httponly' => true])比$_SESSION更可控但不加密
– redis->setex('verify:138xxxxxx', 300, 'a1b2c3')比文件session快一个数量级,且支持原子操作
-
$_COOKIE有4KB限制,且每次请求都随HTTP头发送,别塞大JSON - 用数据库存请求间状态,记得加索引和过期时间字段,否则表越滚越大
- Redis的
EXPIRE是精确到秒的,而PHP session gc是概率清理,精度不同
真正难的不是选哪个方案,而是想清楚这个变量“谁需要读”“要活多久”“改不改得频繁”——没想清就硬套$_SESSION,后面八成要重写。











