PHP会话变量unset后重定向仍存在的异常问题排查
问题分析与解决方案
问题根源
核心问题出在assignSecret()函数里的unset($_SESSION)操作:
- PHP的
$_SESSION是超全局变量,默认会在脚本执行结束时自动将其内容同步到服务器的会话存储(如session文件)中。 - 当执行
unset($_SESSION)后,当前脚本中的$_SESSION就不再是关联会话存储的超全局变量了,后续重新赋值的$_SESSION只是一个普通的全局数组。 - 登出流程的实际问题:
- 脚本先执行
assignSecret(),销毁超全局$_SESSION并创建普通数组版本的$_SESSION(包含user键)。 - 随后执行
unset($_SESSION["user"]),仅删除了普通数组里的user键,但这个修改不会同步到服务器的会话存储。 - 重定向后,新请求通过
session_start()加载的还是原来未修改的会话数据,所以$_SESSION["user"]依然存在。
- 脚本先执行
修复方案
不要unset($_SESSION),改为清空$_SESSION的元素后再重新赋值,这样能保留$_SESSION的超全局属性,确保修改会同步到会话存储:
修改后的assignSecret()函数:
function assignSecret(){ // 清空会话数组,而非销毁超全局变量 $_SESSION = []; // 从数据库加载数据(示例赋值) $_SESSION = ["user" => "world", "secret" => "xyz"]; }
修复后的执行逻辑
session_start()加载会话数据,$_SESSION["user"]存在,执行assignSecret()。assignSecret()清空并重新赋值$_SESSION(仍为超全局变量)。- 执行
unset($_SESSION["user"]),此时修改的是超全局$_SESSION,脚本结束时会自动同步到会话存储。 - 重定向后,新请求加载的会话数据中
user键已被删除,符合预期。
内容的提问来源于stack exchange,提问作者Amine Tbaik
相关产品推荐
相关产品推荐

