我一直在将我的网站从不受保护的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;
}
}
此致 哈利
答案 0 :(得分:4)
您遇到的错误是由于以下几行:
$stmt->bind_param("s", $_POST['username']);
$stmt->bind_param("s", $_POST['email']);
您只能调用一次bind_param()
,并且需要提供确切数量的值,因为SQL中有占位符。该功能的设计不当,这是人们偏爱PDO的主要原因之一。
要解决此问题,您需要动态准备3件事:占位符,类型和要绑定的变量。您可以通过以下方式动态构建此类查询:
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();
}
答案 1 :(得分:2)
您使用Zend Framework吗? 它可能是Php和Zend之间的版本问题。 我遇到了PHP 5.3 +的问题,他在使用Zend framework 1.8.3进行插入或更新时遇到了同样的错误。
如果您遇到这种情况,其中一种解决方案是将连接器更改为数据库。试试这个,它对我有用:
$db = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));
答案 2 :(得分:0)
“没有为预准备语句中的参数提供数据”意味着声明没有问题,但是您为bind_param提供的至少一个变量不符合预期!我打印出$ _POST,看看最新情况,并最终设置$ pSETQuery ='';而不是为了空!
$_POST['username']
$_POST['email']
$_POST['password']
$_POST['usertype']
$_POST['userid'] // this one is the one i would really watch after, how do you tell the userid if the user is not logged ( i assume that from email, passwrod and might be wrong)
欢呼声
答案 3 :(得分:0)
我刚刚找到解决同样问题的方法。
这是MySQL过去的一个值,它是NULL
。而这个列在表定义中不能是NULL
...
答案 4 :(得分:0)
似乎您可能希望在继续并更新其个人资料之前验证所有这些字段。
if(empty($err)) {
//Check for UserId, otherwise you can't update a profile
if (empty($_POST['userid'])) {
//Handle error here...
exit;
}
$userid = $_POST['userid'];
//Filter out all NULL values and replace with empty strings (safety first!)
$username = empty($_POST['username']) ? '' : $_POST['username'];
$password = empty($_POST['password']) ? '' : $_POST['password'];
$email = empty($_POST['email']) ? '' : $_POST['email'];
$usertype = empty($_POST['usertype']) ? '' : $_POST['usertype'];
$pSETQuery = '';
$pSETQuery .= !empty($username) ? ", username = ?" : "";
$pSETQuery .= !empty($password) ? ", password = ?" : "";
$pSETQuery .= (!empty($usertype) && $session->isSuperuser()) ? ", usertype = ?" : "";
//This line stops someone from being able to enter a blank username
//Prepare statement
if(!($stmt = $database->prepare("UPDATE user SET email = ? $pSETQuery WHERE UserId = ?"))) {
$err[] = "PREPARE FAILED.";
}
//Bind parameters where appropriate
$stmt->bind_param("s", $email);
if(!empty($username)) $stmt->bind_param("s", $username);
if(!empty($password)) $stmt->bind_param("s", $password);
if($session->isSuperuser() && !empty($usertype)) $stmt->bind_param("s", $usertype);
$stmt->bind_param("i", $userid);
//Execute statement
if(!$stmt->execute()){
$err[] = "Execute failed. ERROR: " . $stmt->error;
}
}