PHP基于password_hash的改密功能失效及VSCode调试问题求助
改密功能提交无响应问题排查与修复
现存代码的核心问题
- 提交后无跳转逻辑:整个改密处理逻辑写完后没有重定向回改密页面,也没有任何页面输出,用户点击提交后页面没有任何状态变化,就会感觉“点了没反应”
- 强制关闭所有错误提示:代码开头写了
error_reporting(0);,把SQL执行失败、数据库连接异常、字段不匹配这类错误全部屏蔽,出问题时完全看不到报错信息,只能盲猜原因 - 数据库连接变量被意外覆盖:执行UPDATE语句时,把
mysqli_query()的返回值直接赋值给了原本存储数据库连接的$con变量,虽然单条语句执行时不会立刻报错,但会造成后续数据库操作的上下文混乱 - 字符串拼接SQL存在执行失败风险:直接把POST、SESSION里的内容拼接到SQL语句中,如果用户输入的内容带单引号、特殊转义字符,会直接造成SQL语法错误,导致更新语句执行失败
- 冗余的不规范代码:把从未被调用的
console_log函数定义在条件判断块内部,函数作用域不符合PHP的编码规范,容易引发未定义函数的报错 - 写法不严谨:
$_POST[('newpass')]这种带多余括号的键名写法虽然能被PHP解析,但属于不规范用法,容易引发键值匹配错误
分步修复指引
- 开发阶段开启错误显示,删掉
error_reporting(0);,替换为ini_set('display_errors', 1); error_reporting(E_ALL);,让所有报错直接显示在页面上,不用盲目排查 - 补全流程跳转:所有改密逻辑处理完成后,通过
header("Location: 改密页面的路径"); exit;把用户重定向回改密页面,配合已写好的$_SESSION['msg1']提示信息,让用户能看到操作结果 - 避免覆盖数据库连接变量:执行UPDATE语句时,单独新建变量接收查询结果,比如用
$updateResult = mysqli_query($con, "...")代替原来的$con = mysqli_query(...) - 改用预处理语句执行数据库操作:既可以避免特殊字符导致的SQL执行失败,也能从根源上杜绝SQL注入风险
- 把冗余的
console_log函数移到所有逻辑块外部,不需要调试时直接删掉就行,避免作用域问题
VS Code 调试环境简易配置
- 本地安装PHP运行环境,给PHP装上xdebug扩展,配置好php.ini里的xdebug扩展路径和调试端口
- 在VS Code中安装官方适配的PHP Debug扩展
- 新建调试配置项,填写和php.ini中一致的xdebug端口号
- 在代码行号旁点击打断点,启动调试后就能逐行查看变量值、数据库查询的返回结果,快速定位代码执行卡壳的位置
修复后的参考实现代码
<?php // 开发阶段开启报错,上线部署前可以关闭 ini_set('display_errors', 1); error_reporting(E_ALL); session_start(); include("checklogin.php"); check_login(); include("dbconnection.php"); // 调试辅助函数移到逻辑外部,需要时再调用 function console_log($data) { echo '<script>'; echo 'console.log('. json_encode($data) .')'; echo '</script>'; } if (isset($_POST['Change'])) { // 预处理查询当前登录用户的密码哈希 $selectStmt = mysqli_prepare($con, "SELECT password FROM user WHERE email = ?"); mysqli_stmt_bind_param($selectStmt, "s", $_SESSION['login']); mysqli_stmt_execute($selectStmt); $queryResult = mysqli_stmt_get_result($selectStmt); $userInfo = mysqli_fetch_array($queryResult); if ($userInfo) { // 校验输入的旧密码是否和库内哈希匹配 if (password_verify($_POST['oldpass'], $userInfo['password'])) { $newHashedPwd = password_hash($_POST['newpass'], PASSWORD_DEFAULT); // 预处理更新密码,不覆盖原数据库连接变量 $updateStmt = mysqli_prepare($con, "UPDATE user SET password = ? WHERE email = ?"); mysqli_stmt_bind_param($updateStmt, "ss", $newHashedPwd, $_SESSION['login']); $updateRes = mysqli_stmt_execute($updateStmt); $_SESSION['msg1'] = $updateRes ? "Password Has Been Changed!" : "Password update failed, please retry"; } else { $_SESSION['msg1'] = "Error, the Old Password doesn't match!"; } } // 处理完成跳回改密页面,给用户反馈 header("Location: change-password.php"); exit; }
内容的提问来源于stack exchange,提问作者Zgames
相关产品推荐
相关产品推荐

