[英]php mysqli binding parameter:No data supplied for parameters in prepared statement
[英]No data supplied for parameters in MySQLi prepared statement
我一直在將我的網站從不受保護的 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 的主要原因之一。
要解決這個問題,您需要動態准備 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();
}
你使用 Zend 框架嗎? 這可能是 Php 和 Zend 之間的版本問題。 我遇到了 PHP 5.3 + 的問題,他們在使用 Zend 框架 1.8.3 插入或更新時遇到了同樣的錯誤。
如果是這種情況,解決方案之一是更改連接到數據庫的連接器。 試試這個,它對我有用:
$db = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));
“未為准備好的語句中的參數提供數據”表示語句沒問題,但您提供給 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)
我剛剛找到了解決同樣問題的方法。
這是一個傳遞給 MySQL 的值,即NULL
。 而此列在表定義中不能為NULL
...
我一直在將網站從不受保護的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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.