PHP中Session变量重置问题:添加unset后刷新页面报错
问题分析
报错的核心原因是session变量的销毁时机错误:
你在search.php的底部提前执行了unset($_SESSION['one'], $_SESSION['second']),但当点击INTERACTION按钮后,页面会跳转到del.php设置$_SESSION['yes']=true,再跳转回search.php。此时search.php会进入isset($_SESSION['yes'])的分支,尝试用$_SESSION['one']和$_SESSION['second']调用$model->getDrugInt()方法,但这两个变量已经被底部的unset语句销毁,因此触发未定义变量的错误。
同时,你的需求是刷新页面时重置所有状态,但当前的unset逻辑没有区分“页面刷新”和“从其他页面跳转回来”的场景,导致必要的session变量被提前销毁。
解决方案
1. 调整session变量的销毁时机
将unset($_SESSION['one'], $_SESSION['second'])移到所有依赖这两个变量的代码执行完成之后,也就是在处理完$_SESSION['yes']的分支逻辑之后。这样既能保证渲染交互结果时有可用的session变量,又能在页面所有逻辑执行完毕后销毁变量,满足刷新页面重置状态的需求。
2. 修复跳转后的代码执行问题
在所有使用header('Location: ...')的位置(new.php和del.php)添加exit()或die(),避免后续代码继续执行导致session被意外修改。
修改后的代码
search.php
<?php session_start(); ?> <body> <form action="new.php" method="post"> <div> <input type="search" name='search1' list="doc" id="inp1"> <datalist id='doc'> <option value="diclo">diclo</option> <option value="keto">keto</option> </datalist> </div> <div> <input type="search" name='search2' list="doc2" id="inp2"> <datalist id='doc2'> <option value="diclo">diclo</option> <option value="keto">keto</option> </datalist> </div> <div> <button name='btn'>Save</button> </div> </form> <?php if(isset($_SESSION['error'])) { ?> <div> <?= $_SESSION['error'] ?></div> <?php } unset($_SESSION['error']); if(isset($_SESSION['one']) && isset($_SESSION['second'])) { ?> <div> <div> <p><?= $_SESSION['one'] ?></p> </div> <p><?= $_SESSION['second'] ?></p> <form action="del.php" method='post'> <button name='btn1'>INTERACTION</button> </form> </div> <?php } ?> <?php if (isset($_SESSION['yes'])) { // 此时$_SESSION['one']和$_SESSION['second']仍存在,可以正常调用方法 $getDrugInt = $model->getDrugInt($_SESSION['one'], $_SESSION['second']); for ($i = 0; $i < count($getDrugInt); $i++) { ?> <div> <p> <?= $getDrugInt[$i]['profDescription']?> </p> </div> <?php } } unset($_SESSION['yes']); // 所有依赖session的逻辑执行完毕后,再销毁变量 unset($_SESSION['one'], $_SESSION['second']); ?> </body>
new.php
<?php session_start(); $arr = array('diclo', 'keto'); if(isset($_POST['btn'])) { unset($_SESSION['one'], $_SESSION['second']); $inputone = $_POST['search1']; $inputsecond = $_POST['search2']; if(in_array($inputone, $arr) && in_array($inputsecond, $arr)) { $_SESSION['one'] = $inputone; $_SESSION['second'] = $inputsecond; header('location: search.php'); exit(); // 添加exit阻止后续代码执行 } else { $_SESSION['error'] = 'No results found'; unset($_SESSION['one'], $_SESSION['second']); header('location: search.php'); exit(); // 添加exit阻止后续代码执行 } } ?>
del.php
<?php session_start(); if(isset($_POST['btn1'])) { $_SESSION['yes'] = true; header('location: search.php'); exit(); // 添加exit阻止后续代码执行 } else { $_SESSION['yes'] = false; } ?>
补充说明
- 调整unset位置后,当用户点击
INTERACTION按钮跳转回search.php时,$_SESSION['one']和$_SESSION['second']会先被用来渲染交互结果,之后才被销毁,既满足了展示需求,又保证了刷新页面时所有状态被重置。 - 添加
exit()是PHP跳转的最佳实践,避免header跳转后后续代码继续执行,导致session变量被意外修改或其他逻辑错误。
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

