This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best way to prevent SQL injection?
I'm having trouble understanding how to sanitise php against SQL injection and hope someone would be kind enough to explain to me what I need to change here in order to make my code safe?
<?php
$dbConnection = mysqli_connect('****', '****', '****', 'db');
$query = "INSERT INTO `table` (`1`, `2`, `3`) VALUES ('$_POST[1]', '$_POST[2]', '$_POST[3]')";
if (mysqli_query($dbConnection, $query)) {
echo "Successfully inserted " . mysqli_affected_rows($dbConnection) . " row";
} else {
echo "Error occurred: " . mysqli_error($dbConnection);
}
?>
MySQLi supports prepared statements, which is better than manually escaping:
Since you are using procedural MySQLi, here is an example:
/* create a prepared statement */
if ($stmt = mysqli_prepare($dbConnection, "INSERT INTO `table` (`1`, `2`, `3`) VALUES (?, ?, ?)"))
{
/* bind parameters for markers */
mysqli_stmt_bind_param($stmt, "sss", $_POST[1], $_POST[2], $_POST[3]);
/* execute query */
if(mysqli_stmt_execute($stmt))
{
echo "Successfully inserted " . mysqli_affected_rows($dbConnection) . " row";
}
else
{
echo "Error occurred: " . mysqli_error($dbConnection);
}
/* close statement */
mysqli_stmt_close($stmt);
}
To prevent SQL injections, you could use prepared statements. You'll need some more mysqli_ functions for that:
mysqli_prepare()
mysqli_stmt_bind_param()
mysqli_stmt_execute()
With these you can write something like the following:
$dbConnection = mysqli_connect('****', '****', '****', 'db');
// prepare the query
$query = mysqli_prepare( $dbConnection, "INSERT INTO `table` (`1`, `2`, `3`) VALUES (?, ?, ?)";
// bind parameters; 2nd parameter is for data-types
mysqli_stmt_bind_param( $query, "sss", $_POST[1], $_POST[2], $_POST[3] );
// execute query
if ( mysqli_stmt_execute($query) ) {
echo "Successfully inserted " . mysqli_affected_rows($dbConnection) . " row";
} else {
echo "Error occurred: " . mysqli_error($dbConnection);
}
If you want to keep using the old mysql_* functions look at http://php.net/manual/en/function.mysql-real-escape-string.php
$datapoint1 = mysql_real_escape_string($_POST[1]);
...
$query = "INSERT INTO `table` (`1`, `2`, `3`) VALUES ('$datapoint1', '$datapoint2', '$datapoint3')";
You can use prepared statements or mysqli_real_escape_string
Related
Trying to get the id of the last insert using a prepared statement. mysqli_insert_id always returns zero.
$sql = "INSERT INTO classes (id_course, id_organization, start_date, end_date, status, id_creator, assign_interval) VALUES (?, ?, ?, ?, ?, ?, 'monthly')";
if ($stmt = mysqli_prepare($link, $sql)) {
if (!mysqli_stmt_bind_param($stmt, "ssssss", $course, $idOrg, $thisClass["startDate"], $endDate, $thisClass["status"], $idUser)) {
echo "Error:could not bind parameters";
}
# CODE MISSING...
{
mysqli_stmt_execute($stmt);
$idClass = mysqli_insert_id($stmt);
}
}
else
{
echo 'ERROR: Could not prepare statement';
}
$sql = "INSERT INTO class_modules (id_class, id_module) select ?,id_module from modules m where m.id_course = ?";
if ($stmt = mysqli_prepare($link, $sql)) {
if (!mysqli_stmt_bind_param($stmt, "ss", $idClass, $course)) {
echo "Error:could not bind parameters";
}
if (!mysqli_stmt_execute($stmt)) {
echo "Error: could not update class modules:";
}
}
else
{
echo 'ERROR: Could not prepare statement';
}
I strogly recommend to use object-oriented approach. The reason for this is that you have confused two functions are mixed their parameters. If you used OOP, this mistake would be less likely to happen.
There are 4 ways to get the auto-generated ID from MySQLi prepared statement:
var_dump($stmt->insert_id);
var_dump($mysqli->insert_id);
var_dump(mysqli_stmt_insert_id($stmt));
var_dump(mysqli_insert_id($mysqli));
As you can see the first two are much cleaner and easier to understand and spot a mistake. What you have done is confused the last two. You used mysqli_insert_id() but you passed in the statement as an argument. Either change the function name or pass the mysqli object instead. The best option would be to use OOP and get the property value.
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 5 years ago.
How do i protect against SQL Injection if i wrote the site in PHP procedural? Can i use prepared statements? Or exists other ways?
example:
$query ="INSERT INTO users (name,username,password,email,gender) VALUES ('$name','$username','$password','$email','$gender')";
$result = mysqli_query($connect,$query) or die ( "Error : ". mysqli_error($connect) );
Yes, you can write prepared statements with bound parameters in procedural code using mysqli. Here's a solution based on your example.
$query ="
INSERT INTO users (name, username, password, email, gender)
VALUES (?, ?, ?, ?, ?)";
if (($stmt = mysqli_prepare($connect, $sql)) === false) {
die("Error : " . mysqli_error($connect));
}
if (mysqli_stmt_bind_param($stmt, "ssss", $name, $username, $password, $email, $gender) === false) {
die("Error : " . mysqli_stmt_error($stmt));
}
if (mysqli_stmt_execute($stmt) === false) {
die("Error : " . mysqli_stmt_error($stmt));
}
$result = mysqli_stmt_get_result($stmt);
if (mysqli_errno()) {
die("Error : " . mysqli_stmt_error($stmt));
}
... fetch from $result ...
does anybody know why i get return value of 0 with this code:
/* check connection */
if (mysqli_connect_errno()) {
error_log("Connect failed: " . mysqli_connect_error());
echo '{"success":0,"error_message":"' . mysqli_connect_error() . '"}';
} else {
$stmt = $mysqli->prepare("INSERT INTO teams (name, token) VALUES (?, ?)");
$stmt->bind_param('ss', $team, $token);
/* execute prepared statement */
$stmt->execute();
if ($stmt->error) {error_log("Error: " . $stmt->error); }
$success = $stmt->affected_rows;
//Get the last insert ID of the insert Team
$lastInsertID = $stmt->insert_id;
//Insert into the Mapping Table
$stmt = $mysqli->prepare("INSERT INTO usersTeamsMap (users_idUser, teams_idTeam) VALUES (?, ?)");
$stmt->bind_param('ii', $userID , $lastInsertID );
/* execute prepared statement */
$stmt->execute();
//Get the last insert ID of the insert Team
$lastInsertID = $stmt->insert_id;
echo "ID: " . $lastInsertID;
The last echo always returns 0. The first " $lastInsertID = $stmt->insert_id;" of the first Insert into query works fine.
Thanks in advance.
EDIT:
Thanks for all answers. Now i know why the service didnt work. My mapping table did not have an AutoIncrement field.
insert_id is an attribute of the mysqli object, not of the statement! It is connection specific.
So it should be $mysqli->insert_id.
Hey guys I am new to the whole database scene and trying to perform a relatively simple task but apparently I am doing something wrong. Every time I try to execute this statement I get a 1064 error telling me either my syntax is wrong or the server version is too old. the SQL server version is 5.1.x and I am running PHP5.
Here is my code:
$query = "INSERT INTO `cut_log` (`driver`, `date1`, `time`, `cut`, `flood`, `notes`) VALUES ($driver, $date, $time, $cut, $flood, $notes)";
$result = $mysqli->query($query);
if($result) {
echo "success";
} else {
echo "" . $mysqli->errno . $mysqli->error;
}
You're missing quotes around your string values:
$query = "INSERT INTO `cut_log` (`driver`, `date1`, `time`, `cut`, `flood`, `notes`) VALUES ('$driver', '$date', '$time', '$cut', '$flood', '$notes')";
Like John said, the problem is that it's missing quotes.
What you should have done is prepare the query to avoid SQL injection attacks:
$query = "INSERT INTO `cut_log` (`driver`, `date1`, `time`, `cut`, `flood`, `notes`)
VALUES (?, ?, ?, ?, ?, ?)";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param("ssssss", $driver, $date, $time, $cut, $flood, $notes);
if($stmt->execute()) {
echo "success";
} else {
echo "" . $mysqli->errno . $mysqli->error;
}
}
hello i am a java developer but new to php here i am trying to insert data in to the database using prepared statements as mentioned in here http://www.php.net/manual/en/pdo.prepared-statements.php but i am getting an error may i know what sort of error is this and any help to resolve this.
Error: Fatal error: Call to undefined method mysqli_stmt::bindParam() in G:****\xampp\htdocs****\registrationControl.php on line 17
<?php
$con = new mysqli("127.0.0.1", "root", "", "ksbka");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// escape variables for security
$firstname = mysqli_real_escape_string($con, $_POST['username_first']);
$username_email = mysqli_real_escape_string($con, $_POST['username_email']);
$username_tele = mysqli_real_escape_string($con, $_POST['username_tele']);
echo $firstname."#####".$username_email;
$query="INSERT INTO instructorregistration (Id, Name, email, telephone) VALUES (?, ?, ?, ?)";
$pst = $con->prepare($query);
$pst->bindParam(1, "");
$pst->bindParam(2, $firstname);
$pst->bindParam(3, $username_email);
$pst->bindParam(4, $username_tele);
$pst->execute();
if (!mysqli_query($con,$pst)) {
die('Error: ' . mysqli_error($con));
}
echo "1 record added";
mysqli_close($con);
?>
I think if you want to use bindParam() method, the value should be an instance of PDOStatement .
The doc you see as bellow:
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$dbh is a PDO instance, I think, NOT mysqli instance. Because there is no mysqli::bindParam().
To solve this problem, you can:
use PDO class instead of Mysqli
create the query as the simplest way:
$query="INSERT INTO instructorregistration (Id, Name, email, telephone) VALUES (NULL, $firstname, $username_email, $username_tele)";
you have to use the mysqli methods, when you use mysqli
$stmt = $con->prepare($query);
$stmt->bind_param(1, "");
...
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
/* explicit close recommended */
$stmt->close();
/* Non-prepared statement */
$res = $mysqli->query("SELECT id FROM test");
var_dump($res->fetch_all());
edit: added some code from the official documentation