I have a web application with lots of data, and a search/filter function with several fields, such as name, status, date, and so on. I have been using parameterized queries like this for the regular (non-search) queries:
$id = $_POST['itemID'];
$db = mysqli_connect($host, $username, $password, $database);
$sql_query = "SELECT * FROM tbl_data WHERE ID = ?";
$stmt_query = mysqli_prepare($db, $sql_query);
mysqli_stmt_bind_params($stmt_query, "i", $id);
mysqli_stmt_execute($stmt_query);
//and so on..
How would I protect agains SQL-injection with multiple, optional parameters? There can be up to 10 separate parameters that might or might not be set.
Edit as the question seems unclear:
My example was with one parameter, which is not optional. I know this protects against sql-injection. How would I go about doing this with 10 parameters, where one or several could be set at the same time? E.g. a query such as this:
SELECT * FROM tbl_data
WHERE NAME = ?
AND STATUS = ?
AND DATE = ?
AND PARAM4 = ?
AND PARAM5 = ?
where the user only wants to search on name and date. How would I do the binding? It's not a good idea to check for each of the 100 possible combinations of search terms.
You are already protected against sql injection, as you are using the mysqli_stmt_bind_params which will escape properly for you.
Edit. You could switch to some database framework to have a clean and beautiful code.
Otherwise... this is so old spaghetti style... but I love it :D
It's quite easy to expand your code to work with an unknown number of parameters. You should just loop on your parameters and at the same time 1. build your query string with the question mark notation, and add your parameters to an array, which you will be passing to maxdb_stmt_bind_param ( resource $stmt , string $types , array &$var ).
So it would look like this. It assumes at least ONE parameter is there (but it's trivial to avoid this).
$sql = "SELECT * FROM tbl_data WHERE ";
$and = '';
$types = '';
$parameters = array();
foreach($_POST as $k => $v) {
// check that $k is on your whitelist, if not, skip to the next item
$sql .= "$and $k = ?";
$and = " AND ";
$parameters[] = $v;
$types .= 's';
}
$stmt_query = mysqli_prepare($db, $sql);
mysqli_stmt_bind_params($stmt_query, $types, $parameters);
I recommend switching to PDO. It's built into PHP like the mysqli extension, but has a cleaner syntax and allows you to pass in your parameter values as an array, which you can easily construct dynamically with as many elements as needed.
来源:https://stackoverflow.com/questions/4447629/parameterized-query-with-several-optional-search-terms