PHP医疗网站搜索结果Session覆盖问题解决方案求助
问题分析与解决方案
核心问题
你遇到的这个问题很常见:在while循环里反复覆盖同一个Session变量,导致不管点击哪个医生的"voir profile",Session里永远只保留最后一位医生的信息。Session是全局存储的,循环每执行一次就会把新的医生数据覆盖进去,自然没法区分不同的医生。
最佳解决方案:用URL传递医生ID替代Session
完全不需要用Session临时存医生信息,直接把医生的唯一标识(比如idm)通过URL参数传到个人主页,然后在个人主页根据这个ID查询对应医生的完整信息就行。这样既解决了Session覆盖的问题,也更符合HTTP无状态的设计逻辑。
步骤1:修改卡片里的"voir profile"链接
在你的card.php文件中,把跳转链接改成携带医生ID的形式:
<!-- 假设原来的链接是这样,修改为传递idm参数 --> <a href="doctor_profile.php?idm=<?php echo $rows['idm']; ?>" class="btn">voir profile</a>
步骤2:删掉循环里的Session赋值代码
直接移除原循环中所有给Session赋值的代码,这些完全没必要:
// 删掉以下所有Session赋值的行 $_SESSION['mname']=$rows['lname']; $_SESSION['mfname']=$rows['fname']; $_SESSION['idm']=$rows['idm']; $_SESSION['gnd']=$rows['civilite']; // ... 其他Session赋值代码
步骤3:在医生个人主页查询对应数据
在doctor_profile.php里,通过URL参数idm获取医生ID,再查询该医生的详细信息:
<?php $db= mysqli_connect("localhost","root","","easydoc"); // 检查URL参数是否合法 if(isset($_GET['idm']) && is_numeric($_GET['idm'])){ $idm = $_GET['idm']; // 用预处理语句防止SQL注入! $sql = "SELECT medecin.*, spec.nom as spec_name FROM medecin JOIN spec ON medecin.code = spec.code WHERE medecin.idm = ?"; $stmt = mysqli_prepare($db, $sql); mysqli_stmt_bind_param($stmt, "i", $idm); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $doctor = mysqli_fetch_assoc($result); if($doctor){ // 直接用$doctor数组渲染页面即可 echo "<h2>".$doctor['fname']." ".$doctor['lname']."</h2>"; echo "<p>Spécialité: ".$doctor['spec_name']."</p>"; echo "<p>Disponibilité: ".$doctor['dday']." à ".$doctor['fday']."</p>"; // ... 其他医生信息 } else { echo "<h3><span style='color:red'>Médecin non trouvé</span></h3>"; } } else { echo "<h3><span style='color:red'>Paramètre invalide</span></h3>"; } ?>
关键提醒:修复SQL注入漏洞
你的原代码存在严重的SQL注入风险——直接把$_POST['spec']、$_POST['wilaya']拼进SQL语句里,攻击者可以轻易篡改数据库查询。必须改用预处理语句修复,比如搜索部分的代码可以改成:
if(isset($_POST['rech'])) { $spec= $_POST['spec']; $wilaya=$_POST['wilaya']; // 预处理查询cabinet的idca $sql = "SELECT idca FROM cabinet WHERE wilaya = ?"; $stmt = mysqli_prepare($db, $sql); mysqli_stmt_bind_param($stmt, "s", $wilaya); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $resultcheck = mysqli_num_rows($result); if ($resultcheck > 0) { // 原代码只取了一行cabinet,这里改成while循环遍历所有结果 while($row= mysqli_fetch_assoc($result)) { // 预处理查询对应专科的医生 $sql_med = "SELECT * FROM medecin WHERE code = ?"; $stmt_med = mysqli_prepare($db, $sql_med); mysqli_stmt_bind_param($stmt_med, "s", $spec); mysqli_stmt_execute($stmt_med); $result_med = mysqli_stmt_get_result($stmt_med); $resultcheck_med = mysqli_num_rows($result_med); if ($resultcheck_med > 0){ while( $rows= mysqli_fetch_assoc($result_med)) { // 直接传递idm到card.php,无需Session include("card.php"); } } else { echo "<h3><span style='color:red'>Aucun médecin trouvé</span></h3>"; } } } else { echo "<h3><span style='color:red'>Aucun cabinet trouvé</span></h3>"; } }
另外注意原代码里查询cabinet后只取了一行数据,若同一个wilaya有多个cabinet,会漏掉后续结果,建议改成while循环遍历所有匹配的cabinet。
内容的提问来源于stack exchange,提问作者Ammari Amira
相关产品推荐
相关产品推荐

