Parametrized queries in PHP - 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.

Related

What is the difference between PDO and MySQLi prepared statements?

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.

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'

Writing this MySQLi query as a prepared statement

I have an existing MySQLi query:
$conn = dbConnect('query');
$galNumb = "SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project = {$project}";
$gNumb = $conn->query($galNumb);
$row = $gNumb->fetch_row();
$galTotal = $row[0];
This counts the number of galleries per project that match the value in the query string contained in $project.
It works perfect but is not secure compared to a prepared statement. I have been researching this for two days and can not learn how to write this statement as a prepared statement. Any and all help will be insanely appreciated.
UPDATE:
I am flying by the seat of my pants here. I simply need to be shown how to code the above as a prepared statement. This sort of thing isn't resonating with my brain like learning PHP did and I'm just not getting any of this. The PHP manual is confusing and seems to be written for people who already understand PHP.
In short, I need a prepared statement version of the above code so that I can echo the result on the page. Currently, with what is in my DB, the number should be 3, and it consistently returns 1.
I wish I knew more so that I could better phrase my questions, but alas, I'm still learning. My apologies.
UPDATE 2:
Based on suggestions and research, I have this query written, but it ALWAYS returns the value 1, regardless of what's actually in the database:
$galNumb = "SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project_part = ?";
$stmt = $conn->prepare($galNumb);
$stmt->bind_param('i', $project);
$gNumb = $stmt->execute();
Again, All I want to do is COUNT how many galleries are in each project. I know this should be simple but it isn't for me. There is currently 1 project in the DB with 3 galleries. The query should return 3.
This is as simple as it gets. This will prepare a sql statement, execute it and fetch the first row.
<?php
// create the prepared statement
$stmt = $conn->prepare('SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project = ?');
// bind a variable to the statment
// the character denotes the type of the variable
// 's' for string
// 'i' for integer
$stmt->bind_param('i', $project);
// execute the query
$stmt->execute();
// get the result variable
$result = $stmt->get_result();
// fetch the row
$row = $result->fetch_row();
if ($row) {
echo "The count is " . $row[0];
}
?>
The documentation is pretty straightforward. You have a code example at the bottom.
http://php.net/manual/en/mysqli.prepare.php
$stmt = $dbConnection->prepare('SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project = ?');
$stmt->bind_param('s', $project);
$stmt->execute();

Doing an SQL query in PHP that depends on a variable

I´m trying to do the following query in PHP
$sqlstr = mysql_query("SELECT * FROM sales where passport = $row['passport']");
if (mysql_numrows($sqlstr) != 0) {
while ($row = mysql_fetch_array($sqlstr)) {
echo $row['firstname'];
}}
How can I incorporate the value of $row['passport'] into my query?
First of all you forgot the single-quotes. sAc corrected this already in his answer. But I would consider to also use an escaping function due to security-issues:
$sqlstr = mysql_query("
SELECT
*
FROM
sales
WHERE
passport = '" . mysql_real_escape_string($row['passport']) . "'");
You are missing quotes:
$sqlstr = mysql_query("SELECT * FROM sales where passport = '{$row['passport']}'");
I would avoid manually escaping/sanitizing your variables and just use prepared statements. This was something I didn't learn until much later in my web development career, and I wish I'd known about it sooner. It will save you a lot of trouble and is just safer all around.
You can use the mysqli_stmt class to perform MySQL queries using prepared statements, or you could use the PHP Data Objects (PDO) extension, which works with MySQL, PostgreSQL and other RDBMSes.
Just to show you what it looks like, here's the first example from the PDOStatement->bindParam doc page:
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>

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