iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

MySQL WHERE

Filtering rows is the most common reason to bind parameters. Never interpolate user input — that's how SQL injection happens.

Single filter

PHP
$stmt = $pdo->prepare('SELECT * FROM customers WHERE country = ?');
$stmt->execute(['AU']);

foreach ($stmt as $row) {
    echo $row['name'], PHP_EOL;
}

Multiple filters

PHP
$stmt = $pdo->prepare(
    'SELECT id, name FROM customers WHERE active = ? AND country = ?'
);
$stmt->execute([1, 'AU']);

Named placeholders

PHP
$stmt = $pdo->prepare(
    'SELECT id, name FROM customers WHERE country = :country AND active = :active'
);
$stmt->execute([
    ':country' => 'AU',
    ':active'  => 1,
]);

Named are easier to read; positional are less typing. Pick a style and stay consistent.

LIKE patterns

PHP
$stmt = $pdo->prepare("SELECT * FROM customers WHERE email LIKE ?");
$stmt->execute(['%@example.com']);   // wildcards in the BIND, not the SQL

IN (...) — dynamic list

Placeholders don't expand a list — generate one per value:

PHP
$countries = ['AU', 'NZ', 'US'];
$marks = implode(',', array_fill(0, count($countries), '?'));

$stmt = $pdo->prepare("SELECT * FROM customers WHERE country IN ($marks)");
$stmt->execute($countries);

Range conditions

PHP
$stmt = $pdo->prepare(
    'SELECT * FROM orders WHERE created_at >= ? AND created_at < ?'
);
$stmt->execute(['2026-01-01', '2026-02-01']);
Tip: Never put column or table names in placeholders — only values bind. If a column name is user-input (e.g. dynamic sort), allow-list it: $col = in_array($_GET['sort'], ['name','age']) ? $_GET['sort'] : 'id';.

Example

Example
<?php
$stmt = $pdo->prepare('SELECT * FROM customers WHERE country = ?');
$stmt->execute(['AU']);
print_r($stmt->fetchAll());
Try it Yourself »

Exercise

Positional placeholder character.

WHERE country =

Test yourself

Q1. Placeholders bind…
Q2. IN list with a dynamic count needs…
Q3. Sort by a user-supplied column safely needs…

Discussion

Loading…