What is the difference between PDO and MySQLi prepared statements? - php

What is the difference between these two prepared statements?
1
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
2
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
i checked many courses about prepared statements but the only one i understood was the 2nd way, since it could be written in procedural, Isn't it the same as PDO? since both of them are Prepared statements? Is there any speed difference or ease of use between them? I learnt the 2nd way because i thought PreparedStatment = PDO but i was shocked when i knew that it is not PDO, using
mysqli_prepare
mysqli_stmt_bind_param
mysqli_stmt_execute
mysqli_stmt_bind_result

The difference is below:-
Mysqli is only for the MySQL database. PDO supports other database using the same functions.
Mysqli can be used in either an object-oriented style or a procedural style. PDO is always object-oriented.
Mysqli supports prepared statements with ? placeholders for parameters. PDO supports both ? placeholders and also named placeholders, like :columnName.
Mysqli requires that you use a function to bind each parameter value to the prepared statement. PDO also allows you to simply pass an array of parameter values as you execute the prepared statement.

Related

PHP prepared statments with select query

I just started learning PHP today and am trying to write a few queries using prepared statements. so far I have this:
$query = "select * from users where 1 = ?";
$result = sqlsrv_query($connection,$query,array(1));
if($result === false){
echo "error";
}
while($row = sqlsrv_fetch_array($result,SQLSRV_FETCH_ASSOC)){
print_r($row);
}
It produces the desired result (simply printing everything returned).
I am struggling on making it a prepared query, to avoid SQL injection
This already is a prepared query, where the third argument of sqlsrv_query is the array of variables you want to bind.

Parametrized queries in PHP

$postid = $_GET['p'];
$stmt = $conn->prepare("SELECT * FROM posts WHERE post_id=:postid");
$stmt->bindValue(':postid', $postid);
$stmt->execute();
while($postRows = mysqli_fetch_assoc($stmt)){
$posts[] = $postRows;
}
The above code does not work.
Usually I'd do:
$postid = mysqli_real_escape_string($conn,$_GET['p']);
$result = mysqli_query($conn,"SELECT * FROM posts WHERE post_id='$postid'");
while($postRows = mysqli_fetch_assoc($result)){
$posts[] = $postRows;
}
which works for me.
I can't seem to get my head around this because online explanations do a poor job of actually explaining how to do these, so I have been using mysqli_real_escape_string instead but I understand it can be vulnerable.
Can anyone help me understand how to properly do these queries?
You can try this code
$stmt = $conn->prepare("SELECT * FROM posts WHERE post_id=:postid");
$stmt->bindValue(':postid', $postid, PDO::PARAM_INT);
$stmt->execute();
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
This could help you:Mysql prepare statement - Select
And an Example from PHP on using bindValue()website(http://php.net/manual/en/pdostatement.bindvalue.php example#2):
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->bindValue(1, $calories, PDO::PARAM_INT);
$sth->bindValue(2, $colour, PDO::PARAM_STR);
$sth->execute();
?>
In this example they are specifying parameter type in the bindValue() statement such as PDO::PARAM_STR and PDO::PARAM_INT. You too try specifying your parameter as such.
Or you can also prepare statements and bind values using bindParam(':placeholder',$variable_or_value); (http://www.w3schools.com/php/php_mysql_prepared_statements.asp)
Prepared statements are used for executing same query multiple times with different or changing values. It gives more efficiency. For simple or random queries there is no need to prepare statements infact it will only decrease the effificeny b creating overheads for preparations. And prepared statements are generally applied on INSERT and UPDATE statements
I guess what you want to do might be:
$stmt = $conn->prepare('SELECT * FROM posts WHERE post_id = ?');
//Use 's' for a string or 'i' for an integer
$stmt->bind_param('s', $postid);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc())
{ }
As I said in comments, you are mixing MySQL APIs (mysqli_ and PDO).
You need to use the same API from connecting to querying. Those different APIs do not intermix.
In order to use PDO, you need to:
Connect using PDO http://php.net/manual/en/pdo.connections.php
Query with PDO http://php.net/manual/en/pdo.query.php
Then if you want to use PDO with prepared statements:
http://php.net/pdo.prepared-statements
You cannot connect with mysqli_ then mix MySQL functions with PDO.
That's how it rolls.
Footnotes:
If you want to stick with mysqli_, then it too has prepared statements.
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
The choice is yours. Remember to use the same MySQL API.
Error checking:
http://php.net/manual/en/pdo.error-handling.php - if using all PDO
http://php.net/manual/en/mysqli.error.php - If using all MySQLi
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.

MySQLi prepared statements displaying error because of MySQLnd not installed

I am using this code to run a select statement in MySQLi
$stmt = $mysqli->prepare('SELECT * FROM admin WHERE forename = ? and surname = ? ');
$stmt->bind_param('vv', $forename, $surname);
$foremame = "Forename";
$surname = "Surname";
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row["sequence"];
}
$stmt -> close();
$mysqli -> close();
But I am getting a fatal error saying:
Fatal error: Call to undefined method mysqli_stmt::get_result()
Because I do not have MySQLnd installed but I cannot install it as I am using a shared web server and the host will not install it.
How can I use a MySQLi prepared statement without having to have MySQLnd installed as I want to prevent SQL injection attacks
You can use $stmt->bind_result() to bind the results to variables, then $stmt->fetch() to fetch the results into the bound variables.
$stmt->execute();
$stmt->bind_result($var1, $var2, $var3, ...); // Use more meaningful variable names
while ($stmt->fetch()) {
echo $var3; // to get the third column in the results
}
I strongly recommend listing the colum names explicitly in the SELECT clause, rather than *, since this method of accessing the results is dependent on the specific order of the columns.

how to use mysqli_fetch_array with prepared statements

so everyone told me to use prepared statements, but i have no idea what to do now.
$stmt = mysqli_prepare($con, "SELECT * FROM search WHERE `name2` LIKE '?' AND `approved`='approved'");
mysqli_stmt_bind_param($stmt, 's', $name);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
That is my code, how do i make an array from it like
while ($row=mysqli_fetch_array($result))
from non-prepared
Glad to see you are deciding to use PDO!
//using MySQL
//refer here for reference http://www.php.net/manual/en/ref.pdo-mysql.php
$pdo = new PDO('mysql:host=xxx;port=xxx;dbname=xxx', $username, $password)
//write query
$sql = "SELECT * FROM search WHERE `name2` LIKE '?' AND `approved`='approved'";
//tell query what to replace ? marks with
$fill_array = array($name); // one item in array for the one ? in $sql above
//send query to DB for preparation
$prepare = $pdo->prepare($sql);
//send variables to DB, DB will bind them to the proper place and execute query
$prepare->execute($fill_array);
//get your array. I personally recommend PDO::FETCH_ASSOC but you are using ARRAY
$result = $prepare->fetchAll(PDO::FETCH_ARRAY);
echo '<pre>'.print_r($result, true).'</pre>';
Voila!
Please not that you will have to write code to escape $name and check for things like % signs and underscores because if someone literally types in % then the LIKE statement will return all records where approved='approved'

How to use prepared statements with Postgres

I know that I need prepared statements because I make more than one call to my database during one script.
I would like to get concrete examples about the following sentence
Look at typecasting, validating and sanitizing variables and using PDO with prepared statements.
I know what he mean by validating and sanitizing variables. However, I am not completely sure about prepared statements. How do we prepare statements? By filters, that is by sanitizing? Or by some PDO layer? What is the definition of the layer?
What do prepared statements mean in the statement? Please, use concrete examples.
What do prepared statements mean in
the statement?
From the documentation:
This feature allows commands that will be used repeatedly to be parsed and planned just once, rather than each time they are executed.
See pg_prepare
Example from the page linked above:
<?php
// Connect to a database named "mary"
$dbconn = pg_connect("dbname=mary");
// Prepare a query for execution
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name = $1');
// Execute the prepared query. Note that it is not necessary to escape
// the string "Joe's Widgets" in any way
$result = pg_execute($dbconn, "my_query", array("Joe's Widgets"));
// Execute the same prepared query, this time with a different parameter
$result = pg_execute($dbconn, "my_query", array("Clothes Clothes Clothes"));
?>
The MySQL documentation for Prepared Statements nicely answers the following questions:
Why use prepared statements?
When should you use prepared
statements?
It means it will help you prevent SQL injection attacks by eliminating the need to manually quote the parameters.
Instead of placing a variable into the sql you use a named or question mark marker for which real values will be substituted when the statement is executed.
Definition of PDO from the PHP manual:
'The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP.'
See the php manual on PDO and PDO::prepare.
An example of a prepared statement with named markers:
<?php
$pdo = new PDO('pgsql:dbname=example;user=me;password=pass;host=localhost;port=5432');
$sql = "SELECT username, password
FROM users
WHERE username = :username
AND password = :pass";
$sth = $pdo->prepare($sql);
$sth->execute(array(':username' => $_POST['username'], ':pass' => $_POST['password']));
$result = $sth->fetchAll();
An example of a prepared statement with question mark markers:
<?php
$pdo = new PDO('pgsql:dbname=example;user=me;password=pass;host=localhost;port=5432');
$sql = "SELECT username, password
FROM users
WHERE username = ?
AND password = ?";
$sth = $pdo->prepare($sql);
$sth->execute(array($_POST['username'], $_POST['password']));
$result = $sth->fetchAll();
How do we prepare statements:
You define a query one time, and can called it as often as you like with different values. (eg. in a loop)
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name = $1');
$result = pg_execute($dbconn, "my_query", array("Joe's Widgets"));
$result = pg_execute($dbconn, "my_query", array("row two"));
$result = pg_execute($dbconn, "my_query", array("row three"));
see: http://us2.php.net/manual/en/function.pg-execute.php
Reply to Karim79's answer
This
$result = pg_prepare($dbconn, "query1", 'SELECT passhash_md5 FROM users WHERE email = $1');
seems to be the same as this
$result = pg_prepare($dbconn, "query1", 'SELECT passhash_md5 FROM users WHERE email = ?');
Conclusion: the use of pg_prepare and pg_execute makes PHP much more efficient, since you do not need to consider sanitizing. It also helps you in the use of PDO.

Categories