我一直在重新设计我的网站,从不受保护的 MySQL 查询到 mysqli 准备好的语句,一切都很顺利,直到我得到这个:没有为准备好的语句中的参数提供数据。
if(empty($err)) {
$pSETQuery = NULL;
if(!empty($_POST['password'])) {
$pSETQuery .= ", password = ?";
}
if($session->isSuperuser()) {
$pSETQuery .= ", usertype = ?";
}
if(!($stmt = $database->prepare("UPDATE user SET username = ?, email = ? $pSETQuery WHERE UserId = ?"))) {
$err[] = "PREPARE FAILED.";
}
$stmt->bind_param("s", $_POST['username']);
$stmt->bind_param("s", $_POST['email']);
if(!empty($_POST['password'])) {
$stmt->bind_param("s", $_POST['password']);
}
if($session->isSuperuser()) {
$stmt->bind_param("s", $_POST['usertype']);
}
$stmt->bind_param("i", $_POST['userid']);
if(!$stmt->execute()){
$err[] = "Execute failed. ERROR: " . $stmt->error;
}
}
您收到的错误是由以下几行引起的:
$stmt->bind_param("s", $_POST['username']);
$stmt->bind_param("s", $_POST['email']);
你应该只打电话bind_param()
一次,您需要提供与 SQL 中占位符相同数量的可变参数。这个功能设计得不好,这也是人们更喜欢PDO的主要原因之一。
为了解决这个问题,你需要动态准备三件事:占位符、类型和要绑定的变量。以下是动态构建此类查询的方法:
if(empty($err)) {
$pSETQuery = '';
$types = 'sss'; // for the three constant placeholders
$data = [$_POST['username'], $_POST['email']];
if(!empty($_POST['password'])) {
$pSETQuery .= ", password = ?";
$types .= 's'; //concat one more
$data[] = $_POST['password'];
}
if($session->isSuperuser()) {
$pSETQuery .= ", usertype = ?";
$types .= 's'; //concat one more
$data[] = $_POST['usertype'];
}
$data[] = $_POST['userid']; // for UserId
$stmt = $database->prepare("UPDATE user SET username = ?, email = ? $pSETQuery WHERE UserId = ?");
$stmt->bind_param($types, ...$data);
$stmt->execute();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)