Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use prepared statements in PHP Mysqli? - User form search input vs select queries

I am trying to understand when I should use prepared statements in php/mysqli. Should every php/mysqli query use prepared statements or just queries and instances where user input is involved ... such as an html form that asks a user to enter data to search within a database?

I am migrating my old php5/mysql code to php7/mysqli. I have many php files that query a mysql db. I would like clarification if I need to use prepared statements for every php file that connects to a mysql db ... for example php files that are referenced via "php require" and include simple sql select statements to render images and links to a html page?

<?php

//establish connection

$con = new mysqli('localhost','uid','pw','db');

//check connection

if ($con->connect_error) {
die("Connection failed: " . $con->connect_error);  
}

//search variable that stores user input

$search = "%{$_POST['search']}%";

//prepare, bind and fetch

$stmt = $con->prepare("SELECT image, caption FROM `tblimages`
WHERE catid = 3 AND caption LIKE ? order by caption ASC");
$stmt->bind_param("s", $search);
$stmt->execute();
$stmt->bind_result($image,$caption);

while ($stmt->fetch()) {
echo "{$image} <br> {$caption} <br>";    
}

$stmt->close();

//close database connection

mysqli_close($con);

?>

The code above works and is the first I've ever used prepared statements. It takes user input from a form (blank box to enter a search term - POST) and searches a db ... then renders results to an html page. This seems like a logical use of prepared statements. However ... I have other php files where users select data from a drop down box in a form to render a result (the user does not enter data into a search box like above). Do I use prepared statements for that instance as well? Plus do I use prepared statements for php files that are referenced via "php require" and include simple sql select statements to render images and links to a html page? I've yet to find clarification of the specific instances to use prepared statements to prevent sql injections. Any clarification or references welcome.

like image 418
obcbeatle Avatar asked Jun 28 '19 21:06

obcbeatle


1 Answers

Short answer: Always use prepared statements.

Long answer:

Prepared statements separate your data from SQL commands. They are provided by PDO or by MySQLi. Their biggest advantage is that it is impossible to have SQL injection if your data is treated as data. Another advantage is that you can execute the same query over and over again with different set of data, which might be better for your performance and often keeps your code cleaner.

However, there are times when you would like to have some kind of dynamic query based on user's selection or actions. As you probably know table and column names are not data, but part of SQL query, therefore you can't keep them separated. The alternative to prepared statements then is to have a white list of possible values and only allow user input validated against the white list.

You might ask what are query, real_query, multi_query and PDO::exec good for?
As the PHP Manual shows they are good at times when you only need to execute constant query without any variables or when you have a query which can't be prepared. e.g.

$mysqli->query('SELECT Name FROM City LIMIT 10');
$pdo->exec('DELETE FROM fruit');
$mysqli->multi_query('DELETE FROM fruit; DELETE FROM pets;');

What if you know the type and values of your data? Should you also prepare/bind?
Yes! Get into a habit of binding all data going with SQL query. There is no reason to make exceptions. It is much more difficult to trace those exceptions in your code and always be sure you do not overwrite the "safe" value with some unknown input.

If you are still not sure how to use prepared statements or you think that they are too complicated (they are not) you can take a look at an amazing PHP tutorial at https://phpdelusions.net

like image 114
Dharman Avatar answered Oct 23 '22 10:10

Dharman