升级CodeIgniter后PHP无法读取Cookie中Session ID致登录失败
嘿,我帮你捋捋CodeIgniter从2.2.1升级到3.1.8后会话登录失效的问题——毕竟这俩版本在Session机制上有不少关键变化,尤其是你遇到的「PHP不读Cookie里的Session ID反而重建」的情况,咱们一步步排查:
1. 先查Session核心配置的差异
CodeIgniter 3.x对Session系统做了重构,默认驱动从CI2的cookie改成了files,这是最容易踩坑的点:
- 首先确认
application/config/config.php里的$config['sess_driver']:如果还想沿用Cookie存储会话数据,必须设为'cookie';如果用files驱动,一定要配置$config['sess_save_path']为服务器上的可写目录(比如'/var/www/html/application/sessions'),Linux下要给这个目录设置700权限,并且属主是PHP-FPM的运行用户(一般是www-data),不然PHP写不了会话文件,只能每次重建Session ID。 - 然后核对Cookie相关的Session配置,CI3把这些和Session绑定在一起了,别和CI2的全局Cookie配置搞混:
$config['sess_cookie_name']:默认是'ci_session',确保升级前后没被修改,保持一致;$config['sess_cookie_domain']:这是关键!如果你的虚拟机用自定义域名(比如test.local),要设为'.test.local'(前面的点支持子域名);如果用IP或localhost访问,设为''或者'localhost'就行,域名不匹配的话浏览器根本不会把Cookie发回服务器;$config['sess_cookie_path']:设为'/'确保全站有效;$config['sess_cookie_secure']:如果没启用HTTPS,必须设为FALSE,不然Cookie会被浏览器拦截;$config['sess_cookie_httponly']:默认是TRUE(安全设置),如果你的前端不需要读取Cookie(登录场景一般不需要),可以暂时改成FALSE测试,排除这个因素。
2. 排查PHP环境和Nginx配置
你用的是PHP 7.1.12 + Nginx + PHP-FPM,这些环境配置也可能影响Session:
- 检查
php.ini里的Session相关项:session.use_cookies:必须设为1,否则PHP不会用Cookie存储Session ID;session.use_only_cookies:建议设为1,避免URL传递Session ID的安全风险;session.cookie_domain和session.cookie_path:最好留空,让CodeIgniter的配置来控制,避免冲突;
修改后记得重启PHP-FPM和Nginx,确保配置生效。
- 检查Nginx配置:别在location块里加了
proxy_set_header Cookie "";这类禁用Cookie的错误规则,也确保没有影响Cookie传递的rewrite规则。 - 核对虚拟机的hosts配置:如果你用自定义域名访问,要确保hosts里把虚拟机IP指向这个域名,否则浏览器识别不了Cookie的域名,不会发送。
3. 代码层面的细节调整
CI3的Session用法和CI2大致兼容,但有几个细节要注意:
- 登录逻辑里,确保成功认证后正确调用
$this->session->set_userdata(),比如$this->session->set_userdata('user_id', $user_id);,别误加了$this->session->sess_destroy()或者unset_userdata()的代码,提前销毁了会话; - 不要手动用
setcookie()设置Session相关的Cookie,CI3的Session类会自动处理,手动设置会导致冲突; - 如果用
files驱动,一定要确认会话目录的权限:运行chown -R www-data:www-data /path/to/your/session/dir和chmod 700 /path/to/your/session/dir来设置,权限不对的话PHP写不了会话,只能每次生成新的Session ID。
4. 调试技巧,精准定位问题
可以加几行调试代码,快速确认问题出在哪:
在登录页面和登录后的跳转页面都加上:
$cookie_name = $this->config->item('sess_cookie_name'); echo "Cookie中的Session ID: " . (isset($_COOKIE[$cookie_name]) ? $_COOKIE[$cookie_name] : '未找到'); echo "<br>当前Session ID: " . session_id();
- 如果Cookie里的ID存在,但当前Session ID每次都变:说明PHP没读取Cookie里的ID,问题出在配置(域名、路径、PHP的session设置);
- 如果Cookie里的ID根本不存在:说明CI没正确设置Cookie,检查CI的Session配置和PHP的
session.use_cookies设置; - 同时用浏览器开发者工具(F12)查看「Application」(或「Storage」)里的Cookie,检查
ci_session的域名、路径、过期时间是否正确,有没有被标记为「Secure」但你用的是HTTP。
内容的提问来源于stack exchange,提问作者mpavey




