PHP调用mysqli_stmt_store_result参数为bool类型报错排查求助
问题原因
- 函数参数传递错误:
mysqli_stmt_execute()的返回值是布尔类型,执行成功返回true,失败返回false,不会生成新的stmt对象。你将该函数返回的布尔值直接传入了要求参数为mysqli_stmt类型的mysqli_stmt_store_result()、mysqli_stmt_num_rows(),直接触发类型不匹配的致命错误。 - 操作顺序错误:你在读取查询结果行数之前就提前调用
mysqli_stmt_close()关闭了stmt对象,即便参数类型正确也无法正常获取行数。
修复方案
修改后的可运行代码如下,核心改动是使用mysqli_prepare()返回的原始stmt对象操作结果,调整stmt关闭的顺序到读取行数之后:
// NRIC重复校验 $allaccounts = mysqli_prepare($this->conn, "SELECT 'patient' as Role, FirstName, LastName, NRIC, password FROM patients WHERE NRIC = ? UNION ALL SELECT 'doctor', FirstName, LastName, NRIC, password FROM doctor WHERE NRIC = ? UNION ALL SELECT 'nurse', FirstName, LastName, NRIC, password FROM nurse WHERE NRIC = ? UNION ALL SELECT 'admin', FirstName, LastName, NRIC, password FROM administrator WHERE NRIC = ? UNION ALL SELECT 'HospitalAdmin', FirstName, LastName, NRIC, password FROM hospitaladmin WHERE NRIC = ? "); mysqli_stmt_bind_param($allaccounts, "sssss", $NRIC, $NRIC, $NRIC, $NRIC, $NRIC); mysqli_stmt_execute($allaccounts); // 用prepare返回的stmt对象操作结果 mysqli_stmt_store_result($allaccounts); $nricHasDuplicate = mysqli_stmt_num_rows($allaccounts) != 0; // 读取完行数再关闭stmt mysqli_stmt_close($allaccounts); // 邮箱重复校验 $allaccounts_Email = mysqli_prepare($this->conn, "SELECT 'patient' as Role, FirstName, LastName, NRIC, password FROM patients WHERE Email = ? UNION ALL SELECT 'doctor', FirstName, LastName, NRIC, password FROM doctor WHERE email = ? UNION ALL SELECT 'nurse', FirstName, LastName, NRIC, password FROM nurse WHERE email = ? UNION ALL SELECT 'admin', FirstName, LastName, NRIC, password FROM administrator WHERE email = ? UNION ALL SELECT 'HospitalAdmin', FirstName, LastName, NRIC, password FROM hospitaladmin WHERE email = ? "); mysqli_stmt_bind_param($allaccounts_Email, "sssss", $Email, $Email, $Email, $Email, $Email); mysqli_stmt_execute($allaccounts_Email); // 用prepare返回的stmt对象操作结果 mysqli_stmt_store_result($allaccounts_Email); $emailHasDuplicate = mysqli_stmt_num_rows($allaccounts_Email) != 0; // 读取完行数再关闭stmt mysqli_stmt_close($allaccounts_Email); // 最终判断是否存在重复 if ($nricHasDuplicate OR $emailHasDuplicate){ // 你原有重复时的业务逻辑 }
如果需要更高的健壮性,可以额外增加mysqli_prepare、mysqli_stmt_execute的失败判断,打印错误信息方便排查SQL语法问题。
内容的提问来源于stack exchange,提问作者yukang
相关产品推荐
相关产品推荐

