Обработка ID записей в PHP-скриптах: от простых решений к безопасным
Раздел: Программирование -> Работа с базой данных
Принципы обработки идентификатора записи в PHP
Как обеспечить безопасное получение ID из URL?
Наиболее эффективный способ - использование подготовленных запросов (prepared statements) с PDO. Это предотвращает SQL-инъекции и упрощает код. Пример проверки ID через filter_input и последующего запроса:
// Получение ID из GET-параметра с проверкой
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
// Обработка отсутствия или некорректного ID
echo "ID не указан или не является числом.";
exit;
}
// Подключение к БД (пример)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id');
$stmt->execute(['id' => $id]);
$article = $stmt->fetch();
if ($article) {
echo "Запись найдена: " . htmlspecialchars($article['title']);
} else {
echo "Запись с таким ID не существует.";
}
Типичные проблемы
- Использование непроверенного $_GET['id'] в SQL запросе - уязвимость к инъекциям.
- Отсутствие проверки на существование записи приводит к ошибкам или пустому выводу.
- Неправильная обработка типов (строка вместо числа) может вызвать ошибку запроса.
Решение: всегда проверять ID, использовать подготовленные запросы и обрабатывать случай отсутствия записи.
Вариант 1: использование intval() для приведения к целому
Простой способ, если не требуется защита от инъекций (например, при работе с уже экранированными данными).
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$sql = "SELECT * FROM articles WHERE id = $id"; // всё равно опасно
Не защищает от SQL-инъекций, если значение используется в строке запроса без кавычек.
Вариант 2: mysqli с экранированием
Использование mysqli_real_escape_string и приведения к числу.
$id = intval($_GET['id'] ?? 0);
$mysqli = new mysqli(...);
$id = $mysqli->real_escape_string($id); // избыточно для integer
$result = $mysqli->query("SELECT * FROM articles WHERE id = $id");
Вариант 3: проверка с помощью регулярного выражения
Когда ID может быть не только числом, но и строкой определённого формата.
$id = $_GET['id'] ?? '';
if (preg_match('/^[1-9]\d*$/', $id)) {
// безопасно использовать в запросе после экранирования
}
Расширенные примеры работы с ID
Пример с использованием named placeholders и обработкой ошибок PDO
Полный скрипт с проверкой существования записи и выводом.
Пример
<?php
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if ($id === false || $id === null) {
throw new InvalidArgumentException('Некорректный ID');
}
$stmt = $pdo->prepare('SELECT title, content FROM articles WHERE id = :id');
$stmt->execute(['id' => $id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) {
throw new Exception('Запись не найдена');
}
echo '<h1>' . htmlspecialchars($row['title']) . '</h1>';
echo '<p>' . nl2br(htmlspecialchars($row['content'])) . '</p>';
} catch (Exception $e) {
echo 'Ошибка: ' . $e->getMessage();
}
?>
Вывод: заголовок и содержимое статьи, если ID корректен и запись существует, иначе сообщение об ошибке.
Пример с передачей массива ID (IN конструкция)
Как получить несколько записей по списку ID из URL (id=1,2,3).
Пример
$ids = $_GET['id'] ?? '';
$idsArray = array_map('intval', explode(',', $ids));
$placeholders = implode(',', array_fill(0, count($idsArray), '?'));
$stmt = $pdo->prepare("SELECT * FROM articles WHERE id IN ($placeholders)");
$stmt->execute($idsArray);
$articles = $stmt->fetchAll();
Массив записей, соответствующих перечисленным ID.
Пример использования фильтрации с FILTER_VALIDATE_INT и опциями
Ограничение диапазона ID от 1 до 1000.
Пример
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 1000]
]);
if ($id) {
// безопасное использование
}
Переменная $id содержит целое число в заданном диапазоне или false/null при несоответствии.
Работа с ID записей - comments
En
Index php id 5 (php)