mysqli_affected_rows返回-1但UPDATE语句执行成功的问题求助
解决mysqli_affected_rows始终返回-1的问题
首先,我怀疑问题大概率出在你封装的db_query_func()这类mysqli函数上,而不是mysqli本身的bug。咱们一步步排查并给出替代方案:
1. 优先排查封装函数的连接一致性问题
你现在用全局的$link_con调用mysqli_affected_rows(),但如果你的db_query_func()内部每次都重新调用db_connect_fnc()创建新连接,就会出现执行查询的连接对象和调用affected_rows的连接对象不是同一个的情况,这必然导致返回-1。
举个典型的错误封装示例:
function db_query_func($sql) { // 每次查询都新建连接,和外部的$link_con不是同一个实例 $link = db_conncet_fnc(); $result = mysqli_query($link, $sql); return $result; }
如果是这种情况,你需要修改封装函数,让它接收外部传入的连接对象:
function db_query_func($link, $sql) { return mysqli_query($link, $sql); } // 调用时传入全局连接 $result = db_query_func($link_con, $query);
2. 替代方案:用预处理语句获取可靠的受影响行数
预处理语句不仅能避免SQL注入(你当前的代码直接拼接$md_id有注入风险),还能通过语句对象自身的affected_rows属性拿到准确值,不受连接对象不一致的影响:
// 替换原来的UPDATE代码块 $hashed_psw = $p_hasher->HashPassword($newpsw); // 初始化预处理语句 $stmt = mysqli_prepare($link_con, "UPDATE `mdr` SET `userpass`=? WHERE m_id=?"); // 绑定参数("ss"表示两个字符串类型参数) mysqli_stmt_bind_param($stmt, "ss", $hashed_psw, $md_id); // 执行语句 mysqli_stmt_execute($stmt); // 从语句对象获取受影响行数 $affect_upd = mysqli_stmt_affected_rows($stmt); // 后续的判断逻辑保持不变 if ($affect_upd == 0) { $_SESSION["update_result"] = "err0"; } elseif ($affect_upd == -1) { $_SESSION["update_result"] = "err-1"; } else { $_SESSION["update_result"] = "ok"; } header("location: index.php?page=chngpass"); exit();
3. 最稳妥的验证方式:直接查询验证结果
如果不想改封装逻辑,也可以绕过mysqli_affected_rows,直接查询数据库验证密码是否更新成功:
// 执行UPDATE之后 $query = "UPDATE `mdr` SET `userpass`='$hashed_psw' WHERE m_id='" . $md_id . "' "; $result = db_query_func($query); // 新增验证逻辑 $check_query = "SELECT userpass FROM `mdr` WHERE m_id='$md_id'"; $check_result = db_query_func($check_query); $check_rec = db_fetch_assoc_func($check_result); if ($check_rec && $check_rec['userpass'] === $hashed_psw) { $_SESSION["update_result"] = "ok"; } else { $_SESSION["update_result"] = "err"; } header("location: index.php?page=chngpass"); exit();
这种方法虽然多了一次查询,但完全不受mysqli函数的bug或封装问题影响,结果最直观可靠。
4. 排查隐性错误
你可以在每次查询后打印MySQL的错误信息,确认是否有隐性问题导致返回-1:
// 执行UPDATE后添加 $_SESSION["mysql_error"] = mysqli_error($link_con);
然后在前端页面查看$_SESSION["mysql_error"]的值,即使你觉得更新成功,也可能存在警告或权限类的隐性错误。
内容的提问来源于stack exchange,提问作者harix
相关产品推荐
相关产品推荐

