PHP PDO Insert query with prepared statements - php

I am trying to run an sql query using PDO prepared statements
$sql = "INSERT INTO tickets (ticketnumber, status) VALUES (1234, Open) ";
$stmt = $connection->prepare($sql);
$stmt->execute();
But it is just not inserting. What have I done wrong?
Here is my connection:
$host = "localhost";
$db_name = "";
$username = "";
$password = "";
$connection = new PDO("mysql:host={$host};dbname={$db_name}", $username, $password);

Try this. It's much more secure.
Make sure you have included your connection file.
EDITED
$sql = "INSERT INTO `tickets` (ticketnumber, status) VALUES (:ticketnumber, :status)";
$stmt = $connection->prepare($sql);
$stmt->bindValue(':ticketnumber', 1234, PDO::PARAM_INT);
$stmt->bindValue(':status', 'Open', PDO::PARAM_STR);
$stmt->execute();
Also, the named parameters used above must NOT be enclosed in quotes. If you do so, it'll be treated as a literal string and not a named parameter.

You need to use quotes on strings before inserting them into a database.
Why use prepare if you're not preparing your data before sending it to the database?

Related

PHP: mysqli INSERT INTO statement is not working [duplicate]

This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 3 years ago.
My php code for registration does not insert values to the database. I tried different ways but it is still not working. Here is the code:
Database connection:
<?php $link=mysqli_connect("localhost", "root", "");
mysqli_select_db($link, "dataadventurers");
?>
My registration form PHP code:
<?php
include "connection.php"; ?>
<?php
if(isset($_POST['submit1'])){
$firstname = $_POST['first_name'];
$lastname = $_POST['last_name'];
$middle = $_POST['middle_initial'];
$idnum = $_POST['id_number'];
$email = $_POST['email_add'];
$pass = $_POST['password'];
$bday = $_POST['birthdate'];
$course = $_POST['course'];
$year = $_POST['year'];
mysqli_query($link, "insert into member_registration values('', '$firstname', '$lastname'
, '$middle', '$idnum', '$email', '$pass', '$bday', '$course', '$year')");
?>
Welcome to StackOverflow.
First of all, your code is vulnerable to SQL Injection. This is a major flaw but thankfully, one that's easily fixed. It is important that you do not leave this open to SQL Injection, even if this is something just for you to use. It'll keep your data safe in the event that someone else manages to access it and also gets you in to good habits.
Secondly, your code isn't working because you haven't specified what columns you want to insert into.
Using your example as a basis, here's a working version.
DO NOT USE THIS, IT IS VULNERABLE CODE
<?php
$link=mysqli_connect("localhost", "root", "");
mysqli_select_db($link, "dataadventurers");
?>
<?php
include "connection.php";
?>
<?php
if(isset($_POST['submit1'])){
$firstname = $_POST['first_name'];
$lastname = $_POST['last_name'];
$middle = $_POST['middle_initial'];
$idnum = $_POST['id_number'];
$email = $_POST['email_add'];
$pass = $_POST['password'];
$bday = $_POST['birthdate'];
$course = $_POST['course'];
$year = $_POST['year'];
//If someone passes 2019'); drop table member_registration; -- for example as the year parameter, MySQL interprets the query string as two separate queries. One to insert a record and the second to drop the table and will execute both
mysqli_query($link, "insert into member_registration (firstname, lastname, middle, idnum, email, pass, bday, course, year) values( '$firstname', '$lastname', '$middle', '$idnum', '$email', '$pass', '$bday', '$course', '$year')");;
}
?>
A MORE SECURE VARIANT
I have a couple of SQL convenience functions based on PDO I use on a regular basis.
They pick up their credentials from an ini file stored outside of the publicly accessible folder structure.
The GetData procedure returns the results in the form of an associative array
UpdateData returns the amount of rows affected.
Ini file example
host=localhost
dbname=dataadventurers
username=user
password=pass
Convenience Functions
/*Put credential ini file path here*/
$credentialFile = "...";
function GetData($sql, $params = null, $paramtypes = null){
//Get database connection details
$credentialsArray = parse_ini_file($credentialFile);
//Create PDO Instance
$db = new PDO('mysql:host='.$credentialsArray['host'].';dbname='.$credentialsArray['dbname'].';charset=utf8mb4', $credentialsArray['username'], $credentialsArray['password'], array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
if(is_null($params)){ //If no parameters supplied, execute the query as is
$stmt = $db->query($sql);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
else{
if(count($params) <> count($paramtypes)){ //Check that the parameter count and type count are the same
throw new InvalidArgumentException;
}
$stmt = $db->prepare($sql); //Prepare the statement
for($i=0; $i<count($params); $i++){ //Bind the parameters
$stmt->bindValue($i+1, $params[$i], $paramtypes[$i]);
}
$stmt->execute(); //Execute query
$results = $stmt->fetchAll(PDO::FETCH_ASSOC); //Return the results as an associative array
}
return $results;
}
function UpdateData($sql, $params){
//Get database connection details
$credentialsArray = parse_ini_file($credentialFile);
//Create PDO Instance
$db = new PDO('mysql:host='.$credentialsArray['host'].';dbname='.$credentialsArray['dbname'].';charset=utf8mb4', $credentialsArray['username'], $credentialsArray['password'], array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
try{
$stmt = $db->prepare($sql); //Prepare the statement
is_null($params){ //If there aren't any parameters to bind...
$stmt->execute(); //...execute statement as is
}
else{
$stmt->execute($params); //otherwise execute with the supplied parameters
}
$results = $stmt->rowCount(); //Return the rowcount
return $results;
}
catch(PDOException $ex){ //Catch any PDO Exceptions
return $ex->getMessage(); //Return the exception message
}
}
Usage
The usage is simple. When selecting data, pass a SQL string, an array containing any parameters and an array containing the parameter types. These arrays must be of the same length.
When updating/inserting/deleting data, pass a SQL string and an array containing the parameters. There is no parameter type requirement for UpdateData.
//GetData with no parameters
$results = GetData('select * from member_registration', [], []);
//GetData with one parameter of type String.
$results2 = GetData('select * from member_registration where firstname = ?', ['David'], [PDO::PARAM_STR]);
//Your insert example
$parameters = [
$firstname,
$lastname,
$middle,
$idnum,
$email,
$pass,
$bday,
$course,
$year
];
$rowsAffected = UpdateData('insert into member_registration (firstname, lastname, middle, idnum, email, pass, bday, course, year) values(?, ?, ?, ?, ?, ?, ?, ?, ?)', $parameters);
Final Thoughts
You'll need to substitute the column names for the fields you have in your database. If any are auto-generated, such as an auto-incrementing ID field, omit that field so it works correctly.
One of your parameters is called $pass. If you're storing passwords in a database, ALWAYS store them in an encrypted form, preferably using bCrypt. This StackOverflow answer explains why/how.

Escaping loads of characters going into MySQL

I've got an HTML form into which a user can enter an SQL query.
The query needs to be entered into a field of my MYSql database. But for complex queries that include % _ , ; ' " $ < > etc... it fails.
How would i go about entering this info into the DB without error?
I know the below is not a very secure way to do it, for now, I just need it to work :)
// Get values from form
$username = $_SESSION['user'];
$appname = $_POST['appname'];
$sql2 = $_POST['sql'];
// Insert data into mysql
$sqlquery="INSERT INTO puresql (username,appnm, query)VALUES('$username','$appname', '$sql2')";
$result=mysqli_query($dbconn,$sqlquery);
For anyone else with this issue. the below works, using mysqli_real_escape_string
$date = date("Y/m/d");
echo "$date";
$appname = mysqli_real_escape_string($dbconn, $_POST['appname']);
$sql2 = mysqli_real_escape_string($dbconn, $_POST['sql']);
$username = mysqli_real_escape_string($dbconn, $_SESSION['user']);
// Insert data into mysql
$sqlquery="INSERT INTO livepurespark (username,appnm, query, date)VALUES('$username','$appname', '$sql2', '$date')";
$result=mysqli_query($dbconn,$sqlquery);
Another way of saving complex texts in database fields with added benefit of protection from sql injection is by using parameterized query statements (Prepared Statements).
$username = $_SESSION['user'];
$appname = $_POST['appname'];
$sql2 = $_POST['sql'];
$stmt = mysqli_prepare($dbconn, "INSERT INTO puresql (username,appnm, query)VALUES('?','?','?')");
mysqli_stmt_bind_param($stmt, "sss", $username, $appname, $sql2);
mysqli_stmt_execute($stmt);

Inserting variables in database in php + mysql

I'm totally PHP beginner, and I'm trying to insert variables in a database in PHP and MySQL.
This is my code:
$link = mysql_connect('localhost','','','onlynews') or die('Cannot connect to the DB');
mysql_select_db('TEST',$link) or die('Cannot select the DB');
$strSQL = "INSERT INTO news(id, title,photo,url,source, at) VALUES('$x','$title','$url','$imgurl ','$source','$at')";
mysql_query($strSQL) or die(mysql_error());
The problem is it is doing: NOTHING! No Entries at all, Nothing changes in the database.
-How can I fix this?
-Do I have to write codes to prevent SQL Injection, even if the variables are coming from an API, not from users?
You have to execute your query using $conn->query($sql);.
However, to avoid SQL injections you should definitely use prepared statements or at least $conn->real_escape_string() to escape the values in your SQL statement.
For example, this is your code using prepared statements:
$servername = "localhost";
$username = "";
$password = "";
$dbname = "onlynews";
$tableName = "news";
$conn = new mysqli($servername, $username, $password, $dbname);
$stmt = $conn->prepare("INSERT INTO news (id, title, photo, url, source, at)
VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param('ssssss', $thetitle, $urlToImage, $theurl, $thesource, $thetime);
$stmt->execute();
$stmt->close();
You should also add some error checking, since $conn->prepare() and $stmt->execute() may fail (and return false). Of course, establishing the connection to the database during the construction of $conn could also fail, which can be checked using $conn->connect_error.

MySQLi insert, successful database connection but not successfully inserted [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I'm attempting to insert some data into a table using mysqli functions.
My connection works fine using the following:
function connectDB(){
// configuration
$dbuser = "root";
$dbpass = "";
// Create connection
$con=mysqli_connect("localhost",$dbuser,$dbpass,"my_db");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
return false;
}else{
echo '<br />successfully connected<br />';
return $con;
}
}
But when I attempt to run my insert function I get nothing in the database.
function newUserInsertDB($name,$email,$password){
$con = connectDB();
// Prepare password
$password = hashEncrypt($password);
echo $password . "<br />";
// Perform queries
mysqli_query($con,"SELECT * FROM users");
mysqli_query($con,"INSERT INTO users (name,email,password,isActivated) VALUES ($name,$email,$password,0)");
// insert
mysqli_close($con);
}
I have been looking through the list of mysqli functions for the correct way to give errors but they all seem to be regarding the connection to the DB, not regarding success of an insert (and I can clearly see in my DB that it is not inserting.)
What would be the best way to debug? Which error handling shall I use for my insert?
I've tried using mysqli_sqlstate which gives a response of 42000 but I cannot see any syntax errors in my statement.
As mentioned in my comment, you would be better off using a prepared statement. For example...
$stmt = $con->prepare(
'INSERT INTO users (name, email, password, isActivated) VALUES (?, ?, ?, 0)');
$stmt->bind_param('sss', $name, $email, $password);
$stmt->execute();
Using this, you don't have to worry about escaping values or providing quotes for string types.
All in all, prepared statements are much easier and much safer than attempting to interpolate values into an SQL string.
I'd also advise you to pass the $con variable into your function instead of creating it within. For example...
function newUserInsertDB(mysqli $con, $name, $email, $password) {
// Prepare password
$password = hashEncrypt($password);
// functions that "echo" can cause unwanted side effects
//echo $password . "<br />";
// Perform queries
$stmt = $con->prepare(
'INSERT INTO users (name, email, password, isActivated) VALUES (?, ?, ?, 0)');
$stmt->bind_param('sss', $name, $email, $password);
return $stmt->execute(); // returns TRUE or FALSE based on the success of the query
}
The quotes are missing from the mysql statement from around the values. Also, you should escape the values before inserting them into the query. Do this way:
mysqli_query($con,"INSERT INTO users (name,email,password,isActivated) VALUES ('".
mysqli_real_escape_string($con,$name)."','".
mysqli_real_escape_string($con,$email)."','".
mysqli_real_escape_string($con,$password)."',0)");
Regards

Convert into secure PDO statement?

Could someone show me how I would go about converting my current UPDATE tablename SET column into a safe and secure statement using PDO to protect against SQL injection ? I am trying to better understand binding and PDO but am having trouble with setting it up with PDO. Here is what I currently have with regular msqli
<?php
session_start();
$db = mysqli_connect("hostname", "username", "password", "dbname");
$username = $_SESSION['jigowatt']['username'];
mysqli_query($db, "UPDATE login_users SET Points=Points+15 WHERE username='$username'");
?>
MySQL
You don't need PDO or MySQLi for that. mysql_real_escape_string protect you against sql injection:
$name = 'Bob';
$age = 25;
$description = "' OR 1=1"; // a SQL injection string
$query = "
UPDATE people(name, age, description)
VALUES ('".mysql_real_escape_string($name)."', ".(int) $age.", '".mysql_real_escape_string($description)."');";
// a secure query execution
$result = mysql_query($query);
PDO
With PDO::quote()
PDO::quote() is equal to mysql_real_escape_string:
$pdo = new PDO(...);
$name = 'Bob';
$age = 25;
$description = "' OR 1=1"; // a SQL injection string
$query = "
UPDATE people(name, age, description)
VALUES (".$pdo->quote($name).", ".(int) $age.", ".$pdo->quote($description).");";
// a secure query execution
$result = $pdo->query($query);
With prepared statements
You can use prepared statements. You could put the hole query inside the prepared statement, but it is better to use placeholders for variables:
$pdo = new PDO(...);
$name = 'Bob';
$age = 25;
$description = "' OR 1=1"; // a SQL injection string
$query = "
UPDATE people(name, age, description)
VALUES (:name, :age, :description);";
$stmt = $pdo->prepare($query); // prepare the query
// execute the secure query with the parameters
$result = $pdo->execute(array(
':name' => $name,
':age' => $age,
':description' => $description,
));

Categories