Применение фильтра WHERE в PHP для баз данных
Основные подходы к использованию WHERE в PHP
Наиболее эффективное решение: подготовленные запросы PDO
Использование PDO (PHP Data Objects) с подготовленными запросами и параметрами является самым безопасным и гибким способом работы с условием WHERE в SQL-запросах из PHP. Этот подход предотвращает SQL-инъекции и упрощает работу с разными типами данных.
Как выполнить запрос с WHERE, используя PDO?
Пример: выборка пользователей по email.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$email = 'user@example.com';
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute([':email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
?>
Php class sql (класс для работы с sql в php)
Пояснение: метод prepare создает подготовленный запрос с плейсхолдером :email. Метод execute передает значение параметра. Драйвер автоматически экранирует данные, защищая от инъекций.
Типичные проблемы и ошибки:
- Забыли передать параметры в execute - запрос выполняться не будет.
- Использование неправильного типа плейсхолдера (например,
?вместо именованного) - требует правильного порядка параметров. - Передача массива с неверными ключами - вызывает ошибку выполнения.
Как использовать WHERE с помощью mysqli?
В расширении mysqli также доступны подготовленные запросы. Пример:
<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email);
$email = 'user@example.com';
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
?>
Php sql insert (insert в php)
Пояснение: символ ? является позиционным плейсхолдером. Метод bind_param связывает переменные: первый аргумент - строка типов (s для строки, i для целого и т.д.).
Проблемы:
- Несоответствие количества плейсхолдеров и переданных переменных.
- Неправильный тип в строке типов (например, указание
iдля строки).
Как применить WHERE с экранированием строк (устаревший метод)?
Раньше часто использовали функции mysqli_real_escape_string:
<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$email = $mysqli->real_escape_string('user@example.com');
$sql = "SELECT * FROM users WHERE email = '$email'";
$result = $mysqli->query($sql);
?>
Php ms sql (работа с ms sql в php)
Этот метод устарел и не рекомендуется, так как легко забыть экранировать одно поле или пропустить его.
Ошибки:
- SQL-инъекция, если экранирование не применено ко всем внешним данным.
- Проблемы с кодировками - если не установлена корректная кодировка соединения.
Как собрать WHERE с конкатенацией строк? (опасный способ)
Начинающие часто пишут:
<?php
$email = $_GET['email'];
$sql = "SELECT * FROM users WHERE email = '$email'";
$result = $mysqli->query($sql);
?>
Это крайне опасно: злоумышленник может передать email=admin' OR '1'='1 и получить все строки.
Последствия:
- Полная уязвимость к SQL-инъекциям.
- Потеря данных или несанкционированный доступ.
Расширенные примеры использования WHERE в PHP
Пример 1. Несколько условий (AND, OR)
Поиск активных пользователей старше 18 лет с именем, начинающимся на 'А':
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('
SELECT * FROM users
WHERE active = :active
AND age > :age
AND name LIKE :name_pattern
');
$stmt->execute([
':active' => 1,
':age' => 18,
':name_pattern' => 'А%'
]);
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($users);
?>
array(
[0] => array( [id] => 5, [name] => Александр, [age] => 25, [active] => 1 ),
[1] => array( [id] => 12, [name] => Анна, [age] => 30, [active] => 1 )
)
Пример 2. Использование IN
Выборка пользователей с определенными ID:
<?php
$ids = [1, 3, 7, 10];
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$stmt = $pdo->prepare("SELECT * FROM users WHERE id IN ($placeholders)");
$stmt->execute($ids);
$users = $stmt->fetchAll();
?>
array(
[0] => array( [id] => 1, [name] => Иван ),
[1] => array( [id] => 3, [name] => Мария ),
[2] => array( [id] => 7, [name] => Петр ),
[3] => array( [id] => 10, [name] => Елена )
)
Пример 3. BETWEEN и сравнение дат
Запрос заказов за последний месяц:
<?php
$stmt = $pdo->prepare('
SELECT * FROM orders
WHERE order_date BETWEEN :start AND :end
');
$stmt->execute([
':start' => '2025-02-01',
':end' => '2025-02-28'
]);
$orders = $stmt->fetchAll();
?>
Пример 4. Обработка NULL
Поиск пользователей, у которых не заполнен телефон:
<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE phone IS NULL');
$stmt->execute();
$users = $stmt->fetchAll();
?>
Пример 5. Именованные плейсхолдеры и повторное использование
Проверка существования пользователя с заданным email, исключая текущего:
<?php
$email = 'new@mail.com';
$currentId = 5;
$stmt = $pdo->prepare('
SELECT COUNT(*) FROM users
WHERE email = :email AND id != :current_id
');
$stmt->execute([':email' => $email, ':current_id' => $currentId]);
$count = $stmt->fetchColumn();
?>
Пример 6. Использование WHERE с ORDER BY и LIMIT
Получение 10 последних активных пользователей:
<?php
$stmt = $pdo->prepare('
SELECT * FROM users
WHERE active = 1
ORDER BY created_at DESC
LIMIT :limit
');
$stmt->bindValue(':limit', 10, PDO::PARAM_INT);
$stmt->execute();
$recentUsers = $stmt->fetchAll();
?>