注册功能正常但登录失效,PHP登录代码问题排查求助
登录功能失败的问题分析与修复
核心问题点
- 第一个SQL执行参数冗余:
SELECT pwd FROM users WHERE uid = ?只有一个占位符,但execute(array($uid, $pwd))传了两个参数,虽然PDO会忽略多余参数,但属于错误写法。 - 第二次查询逻辑错误:密码验证通过后,执行
SELECT * FROM users WHERE uid = ? AND pwd = ?,这里用明文$pwd去匹配数据库中存储的哈希密码——而数据库里的密码是注册时通过password_hash生成的哈希值,所以这个查询永远找不到用户,直接触发usernotfound错误跳转,这是登录失败的核心原因。 - 重复查询冗余:两次查询完全没必要,验证密码后不需要再次查询用户信息,第一次查询可以顺便获取所需的用户字段。
修复后的代码
<?php class Login extends db { protected function getUser($uid, $pwd) { // 第一次查询就获取用户的id、uid和哈希密码,避免重复查询 $stmt = $this->connect()->prepare('SELECT id, uid, pwd FROM users WHERE uid = ?;'); // 只传uid一个参数,对应SQL里的一个占位符 if (!$stmt->execute(array($uid))) { $stmt = null; header("location: ../index.php?error=stmtfailed"); exit(); } if ($stmt->rowCount() == 0) { $stmt = null; header("location: ../index.php?error=usernotfound"); exit(); } $userData = $stmt->fetch(PDO::FETCH_ASSOC); // 用fetch而非fetchAll,因为仅返回一条用户数据 $checkpwd = password_verify($pwd, $userData["pwd"]); if (!$checkpwd) { $stmt = null; header("location: ../index.php?error=wrongpassword"); exit(); } // 密码验证通过后直接使用第一次查询到的用户数据 session_start(); $_SESSION["userid"] = $userData["id"]; $_SESSION["useruid"] = $userData["uid"]; $stmt = null; } }
额外优化建议
- 用
fetch()替代fetchAll(),根据uid查询用户只会返回一条数据,无需获取数组集合。 - 错误提示语尽量规范(比如把
stmtfucked改成stmtfailed),避免不专业的命名。 session_start()最好放在脚本最顶部,确保没有输出前启动会话。
内容的提问来源于stack exchange,提问作者Xanward
相关产品推荐
相关产品推荐

