PHP注册表单password_hash返回0导致登录验证失败咨询
密码哈希为0导致登录验证失败?问题排查与解决
首先明确说:password_hash返回0绝对不正常。正常情况下,用PASSWORD_DEFAULT生成的密码哈希是一串以$2y$开头的60字符左右的字符串,出现0肯定是哪里出问题了,而且这大概率就是你登录验证失败的直接原因。
为什么会出现哈希为0?
最常见的原因是你的数据库users表中password字段的类型设置错误:
- 如果字段设成了INT(整数类型),当你试图插入哈希字符串(文本类型)时,数据库会自动把它转换成整数0,这就导致你看到数据库里存的是0。
- 另外,要是字段长度不够(比如设成
VARCHAR(10)),哈希字符串会被截断,也可能出现异常值,但0的情况基本都是INT类型的锅。
再看你的注册代码,还有个小错误:你对用户输入的密码用了mysqli_real_escape_string处理,这完全没必要,甚至会帮倒忙——如果用户密码里包含转义字符(比如'),escape后会变成\',你哈希的就是转义后的密码,而不是用户实际输入的密码,这也会导致登录时验证失败。
怎么修复?
1. 先修正数据库字段
把users表的password字段改成VARCHAR(255)(255长度足够容纳当前和未来版本的密码哈希,兼容性拉满)。注意:之前已经注册的用户数据(密码存成0的)没法恢复,需要重新注册。
2. 修正注册代码
移除密码的escape处理,改用预处理语句(彻底避免SQL注入,同时不用手动处理字符转义):
// 获取原始密码,不需要escape $pwd = $_POST['pwd']; // 哈希密码 $hashedPwd = password_hash($pwd, PASSWORD_DEFAULT); // 用预处理语句插入数据 $sql = "INSERT INTO users (name, class, email, username, password) VALUES (?, ?, ?, ?, ?);"; $stmt = mysqli_stmt_init($conn); if (!mysqli_stmt_prepare($stmt, $sql)) { header("Location: ../welcome.php?signup=error"); exit(); } else { // 绑定参数,"sssss"表示5个字符串类型参数 mysqli_stmt_bind_param($stmt, "sssss", $name, $class, $email, $uid, $hashedPwd); mysqli_stmt_execute($stmt); header("Location: ../welcome.php?signup=success"); exit(); }
3. 优化登录代码
同样改用预处理语句,并且不要对登录密码做escape处理(password_verify需要原始的用户输入密码):
$uid = $_POST['uid']; $pwd = $_POST['pwd']; // 直接用原始密码,不需要escape $sql = "SELECT * FROM users WHERE username=?;"; $stmt = mysqli_stmt_init($conn); if (!mysqli_stmt_prepare($stmt, $sql)) { header("Location: ../index.php?login=error"); exit(); } else { mysqli_stmt_bind_param($stmt, "s", $uid); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if ($row = mysqli_fetch_assoc($result)) { // 验证密码 $hashedPwdCheck = password_verify($pwd, $row['password']); if (!$hashedPwdCheck) { header("Location: ../index.php?login=pass"); exit(); } elseif ($hashedPwdCheck) { $_SESSION['u_name'] = $row['name']; $_SESSION['u_class'] = $row['class']; $_SESSION['u_email'] = $row['email']; $_SESSION['u_uid'] = $row['username']; header("Location: ../index.php?login=success"); exit(); } } else { header("Location: ../index.php?login=user"); exit(); } }
总结
你的核心问题是数据库密码字段类型错误,导致哈希字符串被转成0存入,同时注册时的escape操作也可能干扰了密码哈希。按照上面的步骤修复后,重新注册用户,登录验证就能正常工作了。
内容的提问来源于stack exchange,提问作者sunidhi
相关产品推荐
相关产品推荐

