PHP报错求助:mysqli_num_rows()参数类型错误及登录代码排查
问题排查与解决:mysqli_num_rows() 参数类型错误
先直接拆解核心问题:你这段代码触发报错是连锁问题导致的,咱们一步步理清楚:
一、直接触发报错的原因
看这段关键代码:
$result = mysqli_query($db,$sql); $rows = mysqli_fetch_array($result); $active = $rows["user_id"]; $count = mysqli_num_rows($active);
mysqli_num_rows() 这个函数必须接收 mysqli_result 类型的参数——也就是 mysqli_query() 执行后返回的查询结果对象。但你这里传给它的是 $active,这是从查询结果里取出的 user_id 值;更糟的是,如果前面的SQL查询失败,$result 会变成 null,$rows 也跟着变成 null,$active 自然也是 null,直接就触发了「期望参数1为mysqli_result,传入null」的报错。
二、导致查询失败的根源:SQL语法错误
你的SQL语句犯了一个常见低级错误:字符串类型的字段值没有用单引号包裹:
$sql = "SELECT user_id FROM user WHERE username = $myusername and password = $mypassword";
假设用户输入的用户名是 alex、密码是 123,拼接后的SQL会变成:
SELECT user_id FROM user WHERE username = alex and password = 123
数据库会把 alex 当成一个字段名,而不是字符串值,直接导致SQL执行失败,mysqli_query() 返回 null,这才是所有问题的起点。
三、完整的解决步骤
1. 修复SQL语句(强烈推荐用预处理语句)
直接拼接变量不仅有语法问题,还存在严重的SQL注入风险,改用预处理语句能彻底解决这两个问题:
// 准备带占位符的SQL $stmt = mysqli_prepare($db, "SELECT user_id FROM user WHERE username = ? AND password = ?"); // 绑定参数:"ss"表示两个参数都是字符串类型 mysqli_stmt_bind_param($stmt, "ss", $myusername, $mypassword); // 执行语句 mysqli_stmt_execute($stmt); // 获取查询结果集 $result = mysqli_stmt_get_result($stmt);
如果临时要使用字符串拼接(不推荐),记得给变量加上单引号:
$sql = "SELECT user_id FROM user WHERE username = '$myusername' AND password = '$mypassword'";
2. 修正mysqli_num_rows()的使用逻辑
先检查查询是否成功,再把正确的结果对象传给mysqli_num_rows():
// 先判断查询是否成功 if ($result) { $count = mysqli_num_rows($result); // 根据查询结果行数判断登录状态 if ($count > 0) { $rows = mysqli_fetch_array($result); $active = $rows["user_id"]; // 这里可以把用户ID存入session,完成登录逻辑 $_SESSION['user_id'] = $active; echo "登录成功!"; } else { echo "用户名或密码错误"; } } else { // 开发环境可以输出错误信息调试,生产环境请删除这行 echo "SQL执行错误:" . mysqli_error($db); }
3. 必须做的安全优化
你现在的代码直接存储明文密码,这是非常危险的行为,一定要改用密码哈希:
- 注册用户时:用
password_hash()加密密码再存入数据库:$hashed_pwd = password_hash($user_input_pwd, PASSWORD_DEFAULT); // 把$hashed_pwd存入user表的password字段 - 登录验证时:先根据用户名查询哈希密码,再用
password_verify()验证:$stmt = mysqli_prepare($db, "SELECT user_id, password FROM user WHERE username = ?"); mysqli_stmt_bind_param($stmt, "s", $myusername); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if ($result && mysqli_num_rows($result) > 0) { $user_data = mysqli_fetch_assoc($result); // 验证密码是否匹配 if (password_verify($mypassword, $user_data['password'])) { $_SESSION['user_id'] = $user_data['user_id']; echo "登录成功!"; } else { echo "密码错误"; } } else { echo "用户名不存在"; }
内容的提问来源于stack exchange,提问作者Alexis Villar
相关产品推荐
相关产品推荐

