PHP/MySQL修改用户密码时触发SQLSTATE[HY093]参数错误求助
问题:PHP/MySQL密码更新程序SQL参数错误排查
我正在开发基于PHP/MySQL的用户密码更新程序,数据库表utilisateurs包含numero(自增)、identifiant(用户ID)、motdepasse(密码)字段。用户需输入当前密码$ancienmdp,两次输入新密码$nouveaumdp1、$nouveaumdp2后提交表单。
以下是相关代码片段,运行时出现错误却无法排查:
//获取用户输入的当前密码及两个新密码 $ancienmdp = $_POST['ancienmdp']; $nouveaumdp1 = $_POST['nouveaumdp1']; $nouveaumdp2 = $_POST['nouveaumdp2']; if ($nouveaumdp1 != $nouveaumdp2) { //若两个新密码不一致... //...显示错误提示,告知两次新密码不匹配 $message = '<p class="normal">Le nouveau mot de passe et sa confirmation ne correspondent pas ! Veuillez taper à nouveau votre nouveau mot de passe.</p>'; } else { //若两个新密码一致... //查询用户当前密码 $identifiantrecherche = $_SESSION['identifiant']; $q= $dbco->prepare("SELECT motdepasse FROM `utilisateurs` WHERE identifiant=?"); $q->execute([$identifiantrecherche]); $actuelmdp = $q->fetchColumn(); if ($ancienmdp != $actuelmdp) { //若输入的当前密码与数据库中不符... //...显示错误提示,告知当前密码无效 $message = '<p class="normal">Mot de passe actuel invalide ! Veuillez taper à nouveau vos actuel et nouveau mots de passe.</p>'; } else { //若密码验证通过... //...更新用户密码... $sth = $dbco->prepare("UPDATE `utilisateurs` SET `motdepasse` = :nouveaumdp1 WHERE `identifiant` = :identifiantrecherche"); //echo '$identifiant = ' . $identifiantrecherche . ' ; $motdepasse = ' . $nouveaumdp1; $sth->bindParam(':identifiant',$identifiantrecherche, PDO::PARAM_STR); $sth->bindParam(':motdepasse',$nouveaumdp1, PDO::PARAM_STR); $sth->execute(); //...并提示用户密码已修改成功 $message = '<p class="normal">Mot de passe modifié !</p>'; } }
报错信息:
'Erreur !: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined'
我需更新motdepasse字段,通过identifiant定位用户,已对二者使用bindParam,请问代码哪里出错了?
错误原因与修复方案
核心错误:SQL参数名与绑定参数名不匹配
你的UPDATE语句中定义的参数是:nouveaumdp1(对应新密码)和:identifiantrecherche(对应用户ID),但调用bindParam时使用的却是:identifiant和:motdepasse——这两组参数名完全不对应,PDO找不到SQL语句中定义的参数,因此抛出HY093错误。
修复方法(二选一即可)
方法1:修改bindParam的参数名,匹配SQL语句中的定义
// 原bindParam代码替换为: $sth->bindParam(':identifiantrecherche', $identifiantrecherche, PDO::PARAM_STR); $sth->bindParam(':nouveaumdp1', $nouveaumdp1, PDO::PARAM_STR);
方法2:修改SQL语句的参数名,匹配bindParam的定义
// 原UPDATE语句替换为: $sth = $dbco->prepare("UPDATE `utilisateurs` SET `motdepasse` = :motdepasse WHERE `identifiant` = :identifiant");
额外安全建议
当前代码直接存储明文密码,存在严重安全风险。必须使用PHP内置的password_hash()加密密码,验证时用password_verify():
- 存储新密码时:
$hashedPassword = password_hash($nouveaumdp1, PASSWORD_DEFAULT); // 后续绑定参数时传入$hashedPassword而非明文
- 验证当前密码时:
// 原$ancienmdp != $actuelmdp替换为: if (!password_verify($ancienmdp, $actuelmdp)) { // 密码不匹配提示 }
内容的提问来源于stack exchange,提问作者Fabien Nguyen
相关产品推荐
相关产品推荐

