You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:53:40