跨子域共享session需在session_start()前设session.cookie_domain为’.example.com’,高并发须用redis存储,完全无关域名只能用Token透传或jwt方案。

session_start() 前必须设好 cookie_domain,否则白配
跨子域(如 shop.example.com 和 api.example.com)共享 Session,核心不是“怎么读”,而是“浏览器愿不愿意发”。如果 session.cookie_domain 没在 session_start() 之前生效,php 生成的 Cookie 就只会绑定到当前完整域名(比如 shop.example.com),另一个子域根本收不到它。
- 必须在
session_start()调用前设置:ini_set('session.cookie_domain', '.example.com');(注意开头的点) - 若用
session_set_cookie_params(),也得在session_start()前调用,且要带'samesite' => 'None'+'secure' => true(httpS 环境下强制要求) - 常见错误:在 thinkphp 的中间件或控制器里才设,此时 Cookie 已发出,设置无效
- 验证方式:打开浏览器 DevTools → Application → Cookies,看 Domain 列是否显示为
.example.com
高并发下别用文件存 Session,Redis 是事实标准
本地文件存储 Session 在单机开发时没问题,但一上负载均衡或多节点,就立刻失效;更关键的是,文件 I/O 在高并发下会成为瓶颈,还容易因锁竞争导致请求阻塞。
- 改用 Redis 最直接:在入口文件顶部加两行:
ini_set('session.save_handler', 'redis');和ini_set('session.save_path', 'tcp://127.0.0.1:6379'); - 生产环境务必加密码和数据库编号:
tcp://:password@127.0.0.1:6379?database=2 - 不要依赖 php.ini 全局配置——不同项目可能连不同 Redis 实例,代码内动态设置更可控
- 注意 PHP-Redis 扩展版本兼容性:7.4+ 推荐用 redis 扩展(非 predis 或 phpredis 旧版),否则
session_start()可能静默失败
完全无关域名(如 a.com ↔ b.net)只能靠 token 或 sid 透传
浏览器同源策略对 Cookie 的限制是硬性的,.a.com 和 b.net 之间无法共享 Cookie,也就没法靠 cookie_domain 解决。这时候必须跳出 Session 思维,改用无状态方案。
- 最轻量做法:登录后返回
session_id(),前端跳转时拼到 URL 上(如https://b.net/login?sid=abc123),目标站用session_id($_GET['sid'])+session_start()加载 - 更规范的做法是换 JWT:用
firebase/php-jwt生成带user_id、exp的 Token,前端存在 localStorage,每次请求带Authorization: Bearer xxx - 警惕陷阱:透传
sid不能裸奔,必须配合 Referer 校验或一次性使用机制,否则易被劫持复用 - JWT 不是银弹:payload 别塞太多数据,签名密钥必须服务端严格保管,
exp建议设 15–30 分钟,搭配 refresh token 机制
并发写 Session 时 unset() 比 = NULL 更安全
多个请求同时修改同一个 Session(比如购物车增删、订单状态轮询),PHP 默认会对 Session 文件/Redis key 加写锁,导致后续请求排队。如果只是清理字段,没必要触发完整写入流程。
立即学习“PHP免费学习笔记(深入)”;
- 想删某个值,用
unset($_SESSION['cart_items']),而不是$_SESSION['cart_items'] = null - 写完敏感操作后,尽早调用
session_write_close()释放锁,尤其在需发起下游 HTTP 请求(如调支付网关)前 - 避免在 Session 中存大对象或 json 字符串——序列化/反序列化本身就有 CPU 开销,高并发下放大明显
- Redis 存储虽快,但网络往返仍存在,
$_SESSION只该放 ID、角色、登录时间等极简状态,详情查数据库
跨域 Session 表面是配置问题,实际是“客户端能不能送”“服务端能不能认”“多节点能不能共用”三层叠加。最容易忽略的是:Cookie 的 samesite 和 secure 属性在现代浏览器中已成强制门槛,不满足就直接丢弃,连调试都看不到痕迹。