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

PDO execute返回True但教师表为空,随机用户名登录为何判定成功?

问题根源:误解了PDO execute()的返回值

嘿,我一眼就看出问题所在了——你完全误解了PDO中execute()方法的返回值含义!

$query->execute()返回的true,只代表这条SQL语句成功执行了,和有没有查询到匹配的数据根本不是一回事。比如你用随机用户名查教师表时,虽然没有找到任何符合条件的行,但这条SELECT语句本身语法合法、没有执行错误,所以execute()还是会返回true。你的代码把这个返回值当成了“是否找到用户”的判断依据,自然会出现不管输入什么用户名都能“登录”的诡异情况。

另外,你的代码还有两个致命的安全漏洞:

  • 完全没做密码验证!只要SQL执行成功就直接登录,等于把系统大门完全敞开了
  • 两次查询的写法冗余,很容易出现逻辑疏漏
修正后的代码示例

下面是修复了所有问题的代码,兼顾了正确性和安全性:

// 先查询教师表,同时获取用户密码
$query = $pdo->prepare("SELECT `username`, `password` FROM `teachers` WHERE `username` = :username");
$query->execute(array(":username" => $username));
$teacher = $query->fetch(PDO::FETCH_ASSOC);

if ($teacher) {
    // 验证密码(注意:数据库里必须存哈希后的密码,不能存明文!)
    if (password_verify($password, $teacher['password'])) {
        $_SESSION["current_user"] = [
            "username" => $username,
            "role" => "teacher"
        ];
        echo("<script>location.href = 'home.php';</script>");
        exit;
    }
}

// 教师表没找到,再查学生表
$query = $pdo->prepare("SELECT `username`, `password` FROM `students` WHERE `username` = :username");
$query->execute(array(":username" => $username));
$student = $query->fetch(PDO::FETCH_ASSOC);

if ($student) {
    if (password_verify($password, $student['password'])) {
        $_SESSION["current_user"] = [
            "username" => $username,
            "role" => "student"
        ];
        echo("<script>location.href = 'home.php';</script>");
        exit;
    }
}

// 用户名不存在或密码错误
echo("<script>alert('用户名或密码错误'); location.href = 'index.php';</script>");
额外优化建议
  • 合并用户表:更合理的设计是用一个users表,新增role字段标记用户身份(teacher/student),这样只需要一次查询就能完成验证,减少代码冗余和数据库请求
  • 强制密码哈希:必须用password_hash()生成哈希值存进数据库,绝对不能存明文密码——这是Web系统安全的基本底线
  • 统一错误提示:为了防止恶意枚举用户名,建议统一提示“用户名或密码错误”,不要区分两种错误场景

内容的提问来源于stack exchange,提问作者user9782033

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:18:21