PHP session不生效,cookie配置检查
前言
PHP用session存用户登录状态,结果刷新页面就掉了?session不生效太常见了,一般就是cookie配置不对、路径不对、或者目录没权限。本文讲怎么排查和解决。
一、session工作原理
简单说:
- 浏览器访问网站
- PHP创建session,生成session_id
- session_id通过cookie发给浏览器
- 浏览器每次请求带上这个cookie
- PHP根据cookie里的session_id找到对应数据
核心: session靠cookie传session_id,cookie不行session就没了。
二、常见原因
原因1:cookie没设置对
session.cookie_path、session.cookie_domain配置不对。
原因2:session保存目录没权限
session文件存不进去。
原因3:session.auto_start没开
或者开了但和代码冲突。
原因4:跨域问题
主域和子域之间cookie不共享。
原因5:HTTPS下cookie的secure问题
cookie设了secure,但用http访问。
三、排查步骤
第一步:检查session有没有启动
<?php
session_start();
// 存个值
$_SESSION['test'] = 'hello';
// 看有没有
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
刷新页面,看test还在不在。
第二步:看cookie里有没有PHPSESSID
按F12打开浏览器开发者工具 → Application → Cookies。
看有没有 PHPSESSID 这个cookie。
没有的话: 就是cookie没设对。
有的话: 那就是session保存目录的问题。
四、php.ini配置检查
找到php.ini位置
php --ini
关键配置
;session保存目录
session.save_path = "/var/lib/php/session"
;是否自动启动
session.auto_start = 0
;cookie路径
session.cookie_path = /
;cookie域名
session.cookie_domain =
;cookie有效期(秒)
session.cookie_lifetime = 0
;是否仅https
session.cookie_secure = 0
;是否仅http(防XSS)
session.cookie_httponly = 1
五、常见坑和解决
坑1:session目录没权限
session文件写不进去。
检查:
ls -ld /var/lib/php/session
解决:
chmod 777 /var/lib/php/session
chown apache:apache /var/lib/php/session
或者看php-fpm用的哪个用户。
坑2:cookie_path不对
比如网站装在子目录,但cookie_path设成了别的。
解决:
ini_set('session.cookie_path', '/');
session_start();
坑3:cookie_domain不对
多域名访问时,cookie只在一个域名下有效。
解决:
ini_set('session.cookie_domain', '.example.com');
注意前面有个点,表示所有子域名都生效。
坑4:HTTPS下设了secure
cookie_secure=1表示只在https下传cookie,用http访问就没了。
解决:
session.cookie_secure = 0
或者全站用https。
坑5:session.auto_start冲突
代码里已经session_start()了,但php.ini里也开了auto_start,冲突。
解决:
session.auto_start = 0
六、代码里动态设置
不想改php.ini,可以在代码里设:
<?php
// 必须在session_start()之前
ini_set('session.cookie_path', '/');
ini_set('session.cookie_domain', '.example.com');
ini_set('session.cookie_lifetime', 0);
session_start();
$_SESSION['user_id'] = 1;
七、检查session是否生效
写个测试页:
<?php
session_start();
// 第一次访问,设置
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 1;
} else {
$_SESSION['count']++;
}
echo "访问次数: " . $_SESSION['count'];
echo "<br>";
echo "Session ID: " . session_id();
echo "<br>";
echo "Session 文件: " . session_save_path() . "/sess_" . session_id();
刷新页面,数字应该一直涨。
如果不涨: 就是session没存住。
八、常见场景
场景1:登录后刷新就掉
原因: cookie_path或domain不对。
解决: 检查cookie配置。
场景2:换了个子域名就掉
比如 www.example.com 登录了,跳到 bbs.example.com 就没登录。
原因: cookie_domain没设成 .example.com。
解决:
ini_set('session.cookie_domain', '.example.com');
场景3:从http跳到https就掉
原因: cookie_secure=1,但http不带cookie。
解决: 全站用https,或者关掉secure。
场景4:session目录满了
原因: session文件太多。
解决: 清理旧session,或者设gc_maxlifetime。
session.gc_maxlifetime = 1440
九、快速排查清单
- F12看cookie里有没有PHPSESSID
- 没有 → 查cookie_path、cookie_domain、cookie_secure
- 有 → 查session目录权限
- 都没问题 → 看session.auto_start有没有冲突
- 跨域问题 → cookie_domain设成 .主域名
总结
记住:
- session靠cookie传session_id
- 先看cookie里有没有PHPSESSID
- 没有就查cookie配置
- 有就查session目录权限
- 跨域名记得设cookie_domain=.主域名
最常用:
ini_set('session.cookie_path', '/');
session_start();
遇到问题加QQ23979811 协助处理
PHP 会话管理详解
PHP 会话管理详解
Session 和 Cookie 是 PHP 做用户登录、状态保持的基础,搞懂原理才不会出问题。
1. Cookie 和 Session 的区别
Cookie:存在客户端浏览器里,每次请求自动带在请求头里。
- 大小限制 4KB
- 不安全,用户可以改
- 适合存不敏感的数据
Session:存在服务器端,客户端只存一个 session_id。
- 大小没有限制
- 更安全
- 适合存用户登录信息
2. Cookie 基本用法
// 设置 Cookie(7天过期)
setcookie('user_id', '123', time() + 3600 * 24 * 7);
// 读取 Cookie
echo $_COOKIE['user_id'];
// 删除 Cookie(过期时间设为过去)
setcookie('user_id', '', time() - 3600);
3. Session 基本用法
// 开启 Session(必须在最前面)
session_start();
// 设置 Session
$_SESSION['user_id'] = 123;
$_SESSION['user_name'] = '张三';
// 读取 Session
echo $_SESSION['user_name'];
// 删除单个 Session
unset($_SESSION['user_id']);
// 销毁所有 Session
session_destroy();
4. Session 工作原理
- 用户第一次访问,PHP 生成唯一 session_id
- 把 session_id 通过 Cookie 发给浏览器
- 浏览器下次访问自动带上这个 Cookie
- 服务器根据 session_id 找到对应 Session 数据
5. Session 配置
php.ini 里常用配置:
; Session 保存路径
session.save_path = "/tmp"
; Session 过期时间(分钟)
session.gc_maxlifetime = 1440
; Cookie 有效期(0 表示浏览器关闭就过期)
session.cookie_lifetime = 0
6. 常见问题
1)Session 丢失:
- 没有 session_start()
- Cookie 被禁用
- session 文件目录权限不对
2)多台服务器 Session 共享:
- 默认 Session 存在本地文件,多台服务器不共享
- 解决方案:存在 Redis 里
// Session 存 Redis
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');
7. 安全建议
- 登录成功后重新生成 session_id,防止会话固定攻击
- 敏感数据不要存在 Cookie 里
- Session 过期时间不要太长
- HTTPS 下设置 Cookie 的 secure 属性
// 登录成功后重新生成 ID
session_regenerate_id(true);
总结
PHP 会话管理核心:
- Cookie 存客户端,Session 存服务器
- Session 靠 Cookie 里的 session_id 识别用户
- 多服务器部署 Session 存 Redis
- 登录后重新生成 session_id 防攻击
搞懂这些,用户登录功能就不会出问题了。
PHP Session 与 Cookie:会话管理实战指南
前言
HTTP 是无状态的,你每次请求服务器都不认识你。Session 和 Cookie 就是用来解决这个问题的。本文讲清楚 PHP 中 Session 和 Cookie 的用法。
一、Cookie 是什么
Cookie 是存在浏览器里的小数据,每次请求自动带给服务器。
设置 Cookie
setcookie("username", "张三", time() + 3600, "/");
参数说明:
- 第一个参数:名称
- 第二个参数:值
- 第三个参数:过期时间(时间戳)
- 第四个参数:路径
读取 Cookie
echo $_COOKIE['username'];
删除 Cookie
setcookie("username", "", time() - 3600, "/");
把过期时间设成过去就行。
二、Session 是什么
Session 是存在服务器上的数据,通过 Session ID 识别用户。
启动 Session
session_start();
注意:必须在输出之前调用,不然会报错。
存数据
$_SESSION['user_id'] = 1;
$_SESSION['username'] = '张三';
读数据
echo $_SESSION['username'];
删除单个数据
unset($_SESSION['user_id']);
销毁 Session
session_destroy();
三、Session 和 Cookie 的区别
| 对比 | Cookie | Session |
|---|---|---|
| 存储位置 | 浏览器 | 服务器 |
| 大小限制 | 4KB | 无限制 |
| 安全性 | 低(用户能改) | 高 |
| 生命周期 | 可设置 | 默认浏览器关闭就没 |
四、登录功能示例
登录页
<?php
session_start();
if ($_POST) {
$username = $_POST['username'];
$password = $_POST['password'];
// 验证用户名密码
if ($username == 'admin' && $password == '123456') {
$_SESSION['user_id'] = 1;
$_SESSION['username'] = $username;
header('Location: dashboard.php');
exit;
} else {
echo "用户名或密码错误";
}
}
?>
判断是否登录
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
?>
退出登录
<?php
session_start();
session_destroy();
header('Location: login.php');
exit;
?>
五、Session 配置
修改 Session 有效期
ini_set('session.gc_maxlifetime', 3600); // 1小时
session_start();
修改 Session 存储路径
session_save_path('/tmp/sessions');
session_start();
用 Redis 存储 Session
生产环境推荐用 Redis 存 Session,默认文件存储性能差。
php.ini 配置:
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
六、安全问题
1. Session 劫持
别人拿到你的 Session ID,就能冒充你。
防护:
- 用 HTTPS
- Session ID 定期更换
- 绑定 IP(不太推荐,IP 会变)
2. Cookie 劫持
别人拿到你的 Cookie,就能冒充你。
防护:
- 设置 HttpOnly,JS 读不到
- 设置 Secure,只在 HTTPS 下传
- 设置 SameSite,防止 CSRF
setcookie("token", $token, [
'expires' => time() + 3600,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
3. CSRF 攻击
别人伪造你的请求。
防护:
- 表单加 CSRF Token
- 验证 Referer
七、常见坑
- session_start() 在输出之后:报错 headers already sent
- Session 没销毁:退出登录后还能访问
- Cookie 大小限制:别存太多东西,超过 4KB 就丢
- Session 文件太多:默认文件存储,大了要清理
八、最佳实践
- 敏感数据用 Session,别存 Cookie
- Cookie 加 HttpOnly 和 Secure
- 生产环境用 Redis 存 Session
- 登录成功后重新生成 Session ID,防止固定攻击
// 登录成功后
session_regenerate_id(true);
总结
Session 和 Cookie 的核心要点:
- Cookie 存在浏览器,Session 存在服务器
- session_start() 必须在输出之前调用
- Session 更安全,Cookie 更轻量
- 生产环境用 Redis 存 Session
- Cookie 加 HttpOnly 和 Secure,防劫持
登录、权限、购物车,都离不开 Session 和 Cookie。搞懂这俩,PHP 后端才算入门。