PHP登录页面报错'Trying to access array offset on null'及逻辑问题求助
问题分析与修复方案
问题根源
- 空数组偏移访问错误:当用户名或密码错误时,
mysqli_num_rows($result)返回0,此时mysqli_fetch_array($result)会返回null。后续代码尝试访问$row["user_name"]和$row["password"],相当于对null进行数组偏移访问,触发Notice错误。 - 双错误提示:因为
null与任何值比较结果都是true,所以两个if条件都会成立,导致同时输出用户名和密码错误的提示。 - SQL注入风险:当前代码直接将用户输入拼接到SQL语句中,存在严重的SQL注入漏洞,必须修复。
修复后的代码
if(isset($_POST['login'])) { $username = $_POST['username']; $password = $_POST['password']; // 使用预处理语句防止SQL注入 $sql = "select * from users where user_name = ?"; $stmt = mysqli_prepare($con, $sql); mysqli_stmt_bind_param($stmt, "s", $username); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $row = mysqli_fetch_array($result, MYSQLI_ASSOC); if (mysqli_num_rows($result) === 1) { // 验证密码(注意:实际项目中推荐用password_verify,此处假设密码为明文存储) if($row["password"] === $password) { echo '<script>alert("Login successfully")</script>'; } else { echo "password is incorrect"; } } else { echo "username is incorrect"; } }
关键修复说明
- 预处理语句:替换原字符串拼接SQL的写法,用参数绑定方式避免SQL注入攻击。
- 逻辑调整:先查询是否存在目标用户名,存在则继续验证密码,不存在直接提示用户名错误,既解决了空值访问问题,也不会同时弹出两个错误提示。
- 密码安全建议:如果数据库中存储的是明文密码,强烈建议改为
password_hash()加密存储,验证时使用password_verify():
// 注册时加密密码 $hashedPassword = password_hash($password, PASSWORD_DEFAULT); // 登录时验证密码 if(password_verify($password, $row["password"])) { // 登录成功逻辑 }
内容的提问来源于stack exchange,提问作者Rana Rashid
相关产品推荐
相关产品推荐

