PHP PDO插入数据报SQLSTATE[HY093]参数数量不匹配错误如何解决
错误修复方案
核心报错原因
你当前的报错是变量名误用导致的:
你为INSERT插入语句提前创建了预处理对象$stmtinsertar,但实际执行的时候调用的仍然是之前查询用户存在性的$stmt对象。这个$stmt对应的SELECT语句只有1个占位符:mailparam,你给它传入了5个绑定参数,参数数量不匹配就触发了HY093错误。
只需要把执行语句里的$stmt->execute()改成$stmtinsertar->execute()即可解决这个报错:
// 修复前错误写法 // $stmt->execute( // 修复后正确写法 $stmtinsertar->execute( array( ':mail'=> $correuFormulari, ':passwordform'=> password_hash($passwordFormulari, PASSWORD_DEFAULT), // 密码加密,强制要求添加 ':usuari'=> $user, ':nomFormulari'=> $nomFormulari, ':forgotpass'=> "forgotpass", ':state'=> 1 // 补充state字段赋值,避免后续报错 ) );
同时你需要修改INSERT的SQL语句,加上缺失的state字段,否则会因为字段无默认值触发新的报错:
$sqlinsert = 'INSERT INTO users (mail, password, role, name, forgotpass, state) VALUES (:mail, :passwordform,:usuari, :nomFormulari,:forgotpass, :state)';
其他需要修复的潜在问题
- 禁止明文存储密码:你现在直接把用户输入的明文密码存入数据库是严重的安全漏洞,必须使用PHP内置的
password_hash()函数对密码做单向加密后再存储,后续登录校验用password_verify()即可。 bindParam传参错误:你注释里尝试的bindParam(':forgotpass', "forgotpass")写法本身就有问题,bindParam第二个参数是引用传递,只能传变量不能传字面量字符串,如果要绑定字面量可以用bindValue(),或者直接用execute数组传参即可。- 缺少执行结果判断:你现在不管插入执行成功还是失败,都会输出用户创建成功的提示,建议增加执行结果判断逻辑。
PDO参数绑定方式选择
两种方式没有绝对的优劣,按照场景选择即可:
- 普通业务场景优先用execute数组传参:代码更简洁,不需要多行绑定操作,开发效率最高,适合不需要特殊指定参数类型的场景。
- 以下场景选择
bindParam/bindValue:- 需要显式指定参数类型,比如绑定整型ID的时候指定
PDO::PARAM_INT,避免PDO默认转成字符串导致的索引失效 - 需要绑定存储过程的输出参数
- 同一个预处理对象需要多次循环执行不同参数,用bindParam复用性更高
- 需要显式指定参数类型,比如绑定整型ID的时候指定
内容的提问来源于stack exchange,提问作者caralps.a
相关产品推荐
相关产品推荐

