I've been reworking my website from unprotected MySQL queries to mysqli prepared statements and it all went well until I got this: No data supplied for parameters in prepared statement.
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("sss", $firstname, $lastname, $email); This function binds the parameters to the SQL query and tells the database what the parameters are. The "sss" argument lists the types of data that the parameters are.
Definition and Usage. The mysqli_prepare() function prepares an SQL statement for execution, you can use parameter markers ("?") in this query, specify values for them, and execute it later.
" $stmt " obviously (I think) stands for "statement". As a variable name it's arbitrary, you can name that variable anything you want. $stmt is just rather idiomatic. A prepared statement as such is a database feature.
The error you are getting is becauses of these lines:
$stmt->bind_param("s", $_POST['username']);
$stmt->bind_param("s", $_POST['email']);
You can only call bind_param()
once and you need to provide the exact number of values as you have placeholders in the SQL. This function is not well designed, which is one of the main reasons people prefer PDO.
To solve the problem you need to dynamically prepare 3 things: placeholders, types and variables to bind. Here is how you could dynamically build such query:
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With