How to create a WHERE clause for PDO dynamically
This is quite a common task when we need to create a search query based on the arbitrary number of parameters.
The main problem here is that we cannot create a query beforehand (well, actually we can and it will be shown later) and therefore we don't know which parameters to bind.
Create the query dynamically
PDO doesn't have a functionality for this out of the box, but it can ease the task significantly, thanks again to its ability to bind the arbitrary number of parameters in the form of array passed to execute()
. So we can use a conditional statement which will add a condition to the query and also a parameter to bind:
// always initialize a variable before use!
$conditions = [];
$parameters = [];
// conditional statements
if (!empty($_GET['name']))
{
// here we are using LIKE with wildcard search
// use it ONLY if really need it
$conditions[] = 'name LIKE ?';
$parameters[] = '%'.$_GET['name']."%";
}
if (!empty($_GET['sex']))
{
// here we are using equality
$conditions[] = 'sex = ?';
$parameters[] = $_GET['sex'];
}
if (!empty($_GET['car']))
{
// here we are using not equality
$conditions[] = 'car != ?';
$parameters[] = $_GET['car'];
}
if (!empty($_GET['date_start']) && $_GET['date_end'])
{
// BETWEEN
$conditions[] = 'date BETWEEN ? AND ?';
$parameters[] = $_GET['date_start'];
$parameters[] = $_GET['date_end'];
}
// the main query
$sql = "SELECT * FROM users";
// a smart code to add all conditions, if any
if ($conditions)
{
$sql .= " WHERE ".implode(" AND ", $conditions);
}
// the usual prepare/execute/fetch routine
$stmt = $pdo->prepare($sql);
$stmt->execute($parameters);
$data = $stmt->fetchAll();
Create a static query with all conditions at once
We can actually use a conditional statement right in the query. A condition like (name = :name or :name is null)
will return true
if either the value matches the field's contents or if the value is null. It means that if we want the query to bypass a condition, we just have to pass null
for the value. ong story short, here it goes:
$parameters['name'] = !empty($_GET['name']) ? "%".$_GET['name']."%" : null;
$parameters['sex'] = !empty($_GET['sex']) ? $_GET['sex'] : null;
$parameters['car'] = !empty($_GET['car']) ? $_GET['car'] : null;
$sql = "SELECT * FROM users
WHERE (:name is null or name LIKE :name)
AND (:sex is null or sex = :sex)
AND (:car is null or car != :car)";
$stmt = $pdo->prepare($sql);
$stmt->execute($parameters);
$data = $stmt->fetchAll();
The only drawback here is that this code will work only if emulation is turned off. So, to make it universal, we have to make it a little bit more verbose
$param['name'] = $param['name1'] = !empty($_GET['name']) ? "%".$_GET['name']."%" : null;
$param['sex'] = $param['sex1'] = !empty($_GET['sex']) ? $_GET['sex'] : null;
$param['car'] = $param['car1'] = !empty($_GET['car']) ? $_GET['car'] : null;
$sql = "SELECT * FROM users
WHERE (name LIKE :name or :name1 is null)
AND (sex = :sex or :sex1 is null)
AND (car != :car or :car1 is null)";
$stmt = $pdo->prepare($sql);
$stmt->execute($param);
$data = $stmt->fetchAll();
Related articles:
- SELECT query with PDO
- INSERT query using PDO
- UPDATE query using PDO
- How to connect to MySQL using PDO
- PDO Examples
- Authenticating a user using PDO and password_verify()
- How to check if email exists in the database?
- Select the number of rows using PDO
- DELETE query using PDO
- How to create a prepared statement for UPDATE query
- Getting a nested array when multiple rows are linked to a single entry
- How to execute 1000s INSERT/UPDATE queries with PDO?
- Adding a field name in the ORDER BY clause based on the user's choice
- INSERT helper function for PDO Mysql
- PDO Examples
- PDO Examples
Add a comment
Please refrain from sending spam or advertising of any sort.
Messages with hyperlinks will be pending for moderator's review.
Markdown is now supported:
>
before and an empty line after for a quote