mysqli_query无法区分真假返回值导致记录存在性判断错误
问题根因
你对mysqli_query的返回值规则理解有误:
- 针对SELECT类查询,
mysqli_query只有在SQL语法错误、库表不存在、权限不足等执行错误场景下才会返回FALSE - 只要查询执行成功,哪怕没有匹配到任何记录,都会返回
mysqli_result类型的对象,不等于FALSE,这就是你不管传入什么值都会触发存在记录提示的原因。你原来的判断逻辑只能校验查询有没有执行出错,无法判断是否匹配到记录。 - 你后续调整的
else if ($qry !== TRUE)逻辑同样不成立,查询执行成功时返回的是对象,不是布尔值TRUE,所以这个分支永远不会命中。
正确实现方式
你需要通过统计结果集的行数来判断是否存在匹配记录,示例代码如下:
// 表结构:tab_classe (id(INT), aluno(VARCHAR), prof(VARCHAR), turma(VARCHAR)) $turma = "A28"; // 精确匹配直接用=即可,LIKE不带通配符和=效果一致但执行效率更低 $str = "SELECT 1 FROM tab_classe WHERE turma = '$turma' LIMIT 1"; $qry = mysqli_query($conn, $str); if ($qry === FALSE) { // 此处为查询执行出错的场景,可按需增加报错、日志逻辑 echo "查询执行出错"; } else { // 用mysqli_num_rows统计结果集中的行数 $matchCount = mysqli_num_rows($qry); if ($matchCount > 0) { echo "There is a register!"; } else { echo "No registers!"; } // 结果集使用完毕后主动释放资源 mysqli_free_result($qry); }
安全优化建议
你当前直接拼接变量到SQL的写法存在SQL注入风险,更安全的实现方式是使用预处理语句:
$turma = "A28"; $stmt = mysqli_prepare($conn, "SELECT 1 FROM tab_classe WHERE turma = ? LIMIT 1"); mysqli_stmt_bind_param($stmt, "s", $turma); mysqli_stmt_execute($stmt); mysqli_stmt_store_result($stmt); $matchCount = mysqli_stmt_num_rows($stmt); if ($matchCount > 0) { echo "There is a register!"; } else { echo "No registers!"; } mysqli_stmt_close($stmt);
内容的提问来源于stack exchange,提问作者Ivan Sinigaglia
相关产品推荐
相关产品推荐

