What's wrong with this SQL INSERT prepared statement? [duplicate] - php

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Reference - What does this error mean in PHP?
(38 answers)
Why does this PDO statement silently fail?
(2 answers)
Closed 2 years ago.
I'm creating a user registration system for my website. I had this working code:
$sqlQuery = "INSERT INTO GH_users (firstname, surname, email, accountConfirmed, username, passwordHash)
VALUES ('$firstname', '$surname', '$email', 0, '$usernameSignup', '$passwordHash')";
$execute = $dbConn->exec($sqlQuery);
However, I found out that this invites the risk of SQL injection. Therefore, I have tried to use a prepared statement to prevent this but I am unable to get it to work. Codes that I've tried:
$sqlQuery = "INSERT INTO GH_users (firstname, surname, email, accountConfirmed, username, passwordHash)
VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $dbConn->prepare($sqlQuery);
$stmt->bindParam($firstname, $surname, $email, 0, $usernameSignup, $passwordHash);
$stmt->execute();
$sqlQuery = "INSERT INTO GH_users (firstname, surname, email, accountConfirmed, username, passwordHash)
VALUES (?, ?, ?, 0, ?, ?)";
$stmt = $dbConn->prepare($sqlQuery);
$stmt->bindParam("sssss", $firstname, $surname, $email, $usernameSignup, $passwordHash);
$stmt->execute();
// These give the following error: PDOStatement::bindParam() expects at most 5 parameters, 6 given
// So I tried this:
$sqlQuery = "INSERT INTO GH_users (firstname, surname, email, accountConfirmed, username, passwordHash)
VALUES (?, ?, ?, 0, ?, ?)";
$stmt = $dbConn->prepare($sqlQuery);
$stmt->bindParam($firstname, $surname, $email, $usernameSignup, $passwordHash);
$stmt->execute();
// But this throws: PDOStatement::bindParam() expects parameter 3 to be long, string given
I'm not sure why these are throwing the errors given, especially the "expects parameter 3 to be long" as the email field is a string (varchar) data type. Can anyone help with this and explain what is wrong(accountConfirmed is a bit if it helps)?
UPDATE
I realised that I was receiving these errors because I was not using prepared statements and bound parameters in PDO. Thanks to #tadman and #user3783243 in the comment section, I was able to shorten my code by adding my parameters to execute() to do the binding instead of using bindParam() for each of the parameters.
SOLUTION
$sqlQuery = "INSERT INTO GH_users (firstname, surname, email, accountConfirmed, username, passwordHash)
VALUES (?, ?, ?, 0, ?, ?)";
$stmt = $dbConn->prepare($sqlQuery);
$stmt->execute(array($firstname, $surname, $email, $usernameSignup, $passwordHash));

Related

Can a prepared statement hold multiple queries in php

I am trying to protect my queries from SQL injections, recently. I have started turning the strings I used to make the queries into statements, however, some of the strings I made need to make multiple queries simultaneously, because one insert's id will be added to the next one as a foreign key, which I'll get by using the LAST_INSERT_ID(), and I need them to be executed one after another because of it.
Can a statement hold multiple queries simultaneously and be executed at once?
Here's what the code was before, by the by.
$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`)
VALUES ('{$firstName}', '{$lastName}', '{$phone}', '{$cpf}');";
$sql .= "SELECT LAST_INSERT_ID() INTO #mysql_variable_here;";
$sql .= "INSERT INTO `{$table}`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
VALUES ('{$email}','{$password}', 1, #mysql_variable_here, '{$created}', {$role}" . $restaurantValue . " );";
$sql .= "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
VALUES ('{$number}', '{$street}', '{$city}', '{$stateCode}', '{$zip}', '{$district}', 'BR', '{$created}', #mysql_variable_here);";
$result = $conn->multi_query($sql);```
You can't execute multiple statements in a prepared query:
SQL syntax for prepared statements does not support multi-statements
(that is, multiple statements within a single string separated by ;
characters)
so you will need to prepare and execute each of the queries separately, using mysqli_stmt::insert_id to get the appropriate id value for the second and third queries:
$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`)
VALUES (?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssss', $firstName, $lastName, $phone, $cpf);
$stmt->execute();
$insert_id = $stmt->insert_id;
$stmt->close();
$sql = "INSERT INTO `{$table}`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
VALUES (?, ?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssiisss', $email, $password, 1, $insert_id, $created, $role, $restaurantValue);
$stmt->execute();
$stmt->close();
$sql = "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
$stmt = $conn->prepare($sql);
$country = 'BR';
$stmt->bind_param('sssssssi', $number, $street, $city, $stateCode, $zip, $district, $country, $created, $insert_id);
$stmt->execute();
$stmt->close();
Note I'm not 100% certain what you're trying to achieve with role_id" . $restaurantInsert . ", you might need to edit the second query appropriately to use that.

PHP mysqli prepare statement bind_param boolean error

Testing the statement from all side, but failed to find a solution for it.
// Insert the new user into the database
if( $insert_stmt = $mysqli->prepare("INSERT INTO client (username, email,
password, reg_ip, salt, country, ref_id, pin, ref_by, ref_by_2) VALUES ( ?,
?, ?, ?, ?, ?, ?, ?, ?, ?)")){
$insert_stmt->bind_param("ssssssssii", $username, $email, $pass_2,
$reg_ip, $random_salt, $countryname, $ref_code, $hashed_pin, $user_id3,
$user_id4);
$insert_stmt->execute();
This never executes or gets inside the if statement.
I debugged it by removing the if part, that shows bind_param() is boolean error.
$insert_stmt = $mysqli->prepare("INSERT INTO client (username, email,
password, reg_ip, salt, country, ref_id, pin, ref_by, ref_by_2) VALUES ( ?,
?, ?, ?, ?, ?, ?, ?, ?, ?)");
$insert_stmt->bind_param("ssssssssii", $username, $email, $pass_2, $reg_ip,
$random_salt, $countryname, $ref_code, $hashed_pin, $user_id3, $user_id4);
if($insert_stmt->execute()){
Fatal error: Call to a member function bind_param() on boolean
I have done following test:
All 10 variables data type test = OK (with gettype() function)
Variables data value = OK (printed all data value for checking)
Mysql query statement = OK (tested on MYSQL directly with inputted data, mysql is inserting values)
There is no syntax error either.
Variable alignment is = Ok
Data connection is = ok (as it runs other prepare statements without errors on same page)
Then where is the mistake?
I figure it out.
Solution:
It was not working because of the previous prepare statement $stmt_aff connection was not closed.
Once I closed it. Next Prepare statement $insert_stmt started working.
A good lesson learned why bind_param boolean error get produced if there are multiple prepare statement on the same page.
$stmt_aff->close();

Insering question marks('?') into the database rather than actual values

I'm making a registration form and I am using PHP bind parameters when inserting data into the database.
$fnameclean = mysqli_real_escape_string($mysqli_conn, $_POST['first_name']);
$passwordclean = mysqli_real_escape_string($mysqli_conn, hash("sha512", $_POST['password']));
$lnameclean = mysqli_real_escape_string($mysqli_conn, $_POST['last_name']);
$emailclean= mysqli_real_escape_string($mysqli_conn, $_POST['email']);
$stmt = $mysqli_conn->prepare("INSERT INTO user (firstname, surname, email, password) VALUES ('?', '?', '?', '?')");
$stmt->bind_param("ssss", $fnameclean, $lnameclean, $emailclean, $passwordclean);
$stmt->execute();
$stmt->close();
When I press the submit button, all I can see in my database are question marks in the fields: firstname, surname, email and password.
However, when I try to add information to the database without bind parameters it works perfectly fine
code:
$query1 = "INSERT INTO user (firstname, surname, email, password) VALUES ('$fnameclean', '$lnameclean', '$emailclean', '$passwordclean')";
$mysqli_conn->query($query1);
What am I doing wrong here?
VALUES (?, ?, ?, ?)
No ' to be used in query where you use ? for binding parameter. So your query should be like
$stmt = $mysqli_conn->prepare("INSERT INTO user (firstname, surname, email, password) VALUES (?, ?, ?, ?)");

Prepare Statement Issue sending encrypted information

This is my current statement. Everything was working fine until I added the key
Key is just a generated hash for the user to activate the account.
$stmt = $mysqli->prepare("INSERT INTO Account (accountUsername,accountPassword,accountEmail,accountActivate,accountKey) VALUES (?, ?, ?,?,?)");
$stmt->bind_param('sssiss', $username, $newPassword, $email,0,$key,time());
When I'm doing this code I'm getting an error.
Cannot pass parameter 5 by reference
Do you know what could be the issue?
Thanks!
Edit Code:
$stmt = $mysqli->prepare("INSERT INTO Account (accountUsername,accountPassword,accountEmail,accountActivate,accountKey,accountCreated) VALUES (?, ?, ?,?,?,?)");
$stmt->bind_param('sssisi', $username, $newPassword, $email,0,$key,$time);
http://i.stack.imgur.com/Th5tl.png
If you use bind_param that 0 needs to be in a variable since bind_param passes by reference.
$somevar=0;
$stmt = $mysqli->prepare("INSERT INTO Account (accountUsername,accountPassword,accountEmail,accountActivate,accountKey) VALUES (?, ?, ?, ?,?,?)");
$stmt->bind_param('sssiss', $username, $newPassword, $email,$somevar,$key,$time);

Prepared statements in MySQLi

I'm doing SQL queries in prepared statements(MySQLi)
This is the query
$register = $friend_zone->prepare("INSERT INTO users (name, username, password, email, security_answer, date, user_level, security_question) VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
$register->bind_param($name, $username, $password, $email, $security_answer, $date, $user_level, $security_question);
$register->execute();
Im getting a warning
Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables in /var/www/includes/functions.php on line 152 Notice: Undefined variable: result in /var/www/includes/functions.php on line 159
Can someone help?
You are using the bind_param() function wrong. The first parameter is a string containing the data types. For example:
$register->bind_param('ssssssis', $name, $username, $password, $email, $security_answer, $date, $user_level, $security_question);
Each letter corresponds to it's respective variable. s is for strings and i is for integers. There are some other ones available too.
Try:
$register = $friend_zone->prepare("INSERT INTO users (name, username, password, email, security_answer, date, user_level, security_question) VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
$register->execute( array($name, $username, $password, $email, $security_answer, $date, $user_level, $security_question) );

Categories