Отображение деталей записи с помощью GET-параметра
Вывод данных по идентификатору из GET-параметра
При разработке веб-приложений часто требуется показать детали конкретного объекта (товара, статьи, пользователя) на отдельной странице. Для передачи идентификатора объекта обычно используется GET-параметр в URL, например: index.php?details=42. В этой статье рассматриваются способы получения, проверки и использования этого параметра для вывода информации.
Основной способ: извлечение и валидация через $_GET
Самый распространённый вариант - обратиться к суперглобальному массиву $_GET, проверить наличие ключа details, привести значение к целому числу и выполнить запрос к базе данных (или поиск в массиве). Ниже приведён пример с использованием PDO.
<?php
// index.php
$id = isset($_GET['details']) ? (int)$_GET['details'] : 0;
if ($id <= 0) {
echo 'Идентификатор не указан или некорректен';
exit;
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM products WHERE id = :id');
$stmt->execute(['id' => $id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) {
echo 'Товар не найден';
exit;
}
echo '<h1>' . htmlspecialchars($product['name']) . '</h1>';
echo '<p>Цена: ' . htmlspecialchars($product['price']) . '</p>';
} catch (PDOException $e) {
echo 'Ошибка базы данных';
}
?>
Index php details id (вывод деталей по id)
Пояснение шагов:
- Проверка существования ключа
detailsчерезisset(). - Приведение к целому числу через
(int)- отсекает нечисловые символы. - Если
$idменьше или равен 0, вывод сообщения об ошибке. - Подготовленный запрос PDO предотвращает SQL-инъекции.
- Для вывода используется
htmlspecialchars()- защита от XSS.
Типичные ошибки и их решения:
- Проблема: Параметр отсутствует или пуст. Решение: Всегда проверять
isset()и!empty()для строк. - Проблема: SQL-инъекция при конкатенации. Решение: Использовать только подготовленные запросы.
- Проблема: Некорректный тип данных (строка вместо числа). Решение: Приводить к
intили использоватьctype_digit(). - Проблема: Ошибка базы данных. Решение: Оборачивать в try-catch и показывать пользователю общее сообщение.
Вариант 1: значение по умолчанию через тернарный оператор
Как сделать так, чтобы при отсутствии параметра страница не падала, а показывала список всех элементов?
$id = isset($_GET['details']) ? (int)$_GET['details'] : null;
if ($id === null) {
// показать список всех товаров
} else {
// показать детали одного товара
}
Вариант 2: фильтрация через filter_input()
Как извлечь id с автоматической валидацией и без ручного приведения типа?
$id = filter_input(INPUT_GET, 'details', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
echo 'Некорректный идентификатор';
exit;
}
Цель: Уменьшить количество проверок в коде. Случай использования: Когда нужно строго целое число без дополнительной обработки.
Вариант 3: проверка через регулярное выражение
Как убедиться, что параметр состоит только из цифр, прежде чем использовать его в запросе?
$raw = $_GET['details'] ?? '';
if (!preg_match('/^\d+$/', $raw)) {
echo 'Идентификатор должен быть числом';
exit;
}
$id = (int)$raw;
Цель: Гибкая валидация, если нужны дополнительные ограничения (например, только положительные числа).
Вариант 4: маршрутизация через ЧПУ (Человекопонятный URL)
Как реализовать вывод деталей по id, когда URL имеет вид /product/42?
Требуется файл .htaccess для Apache:
RewriteEngine On
RewriteRule ^product/(\d+)$ index.php?details=$1 [L,QSA]
В index.php параметр details уже будет доступен. Цель: Красивые URL, улучшение SEO.
Вариант 5: несколько GET-параметров (details + action)
Как обработать запрос вида index.php?details=42&action=edit для разных операций?
$id = filter_input(INPUT_GET, 'details', FILTER_VALIDATE_INT);
$action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING);
if ($id && $action === 'edit') {
// форма редактирования
} elseif ($id) {
// просмотр
}
Случаи использования: CRUD-интерфейсы, где один скрипт обрабатывает разные действия.
Расширенные примеры с пояснениями и результатами
Пример 1: PDO с обработкой ошибок и выводом в HTML
Код получает id из GET, проверяет, запрашивает товар из MySQL и выводит его название и цену.
<?php
// index.php
$id = filter_input(INPUT_GET, 'details', FILTER_VALIDATE_INT);
if (!$id) {
echo '<p>Укажите корректный идентификатор товара.</p>';
exit;
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=shop;charset=utf8mb4', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT name, price, description FROM products WHERE id = :id AND active = 1');
$stmt->execute(['id' => $id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) {
echo '<p>Товар не найден или неактивен.</p>';
exit;
}
echo '<div class="product">';
echo '<h2>' . htmlspecialchars($product['name']) . '</h2>';
echo '<p class="price">Цена: ' . htmlspecialchars($product['price']) . ' руб.</p>';
echo '<div>' . nl2br(htmlspecialchars($product['description'])) . '</div>';
echo '</div>';
} catch (PDOException $e) {
error_log($e->getMessage());
echo '<p>Произошла ошибка при загрузке данных.</p>';
}
?>
Результат (если id=42 существует):
<div class="product"> <h2>Смартфон X100</h2> <p class="price">Цена: 25000 руб.</p> <div>Отличный смартфон с 128 ГБ памяти.\nКамера 48 МП.</div> </div>
Пояснение
- Используется
filter_inputс валидацией целого числа. - Проверка на
!$id- если id не число или не задан, выводится сообщение. - Запрос включает условие
active = 1для отображения только активных товаров. htmlspecialcharsэкранирует вывод,nl2brпреобразует переносы строк в <br>.- Ошибки PDO логируются в журнал сервера, пользователю показывается общее сообщение.
Пример 2: Поиск в массиве (без базы данных)
Если данные хранятся в PHP-массиве (например, конфигурация или тестовые данные).
<?php
$products = [
1 => ['name' => 'Книга «PHP для начинающих»', 'price' => 1200],
2 => ['name' => 'Курс «Веб-разработка»', 'price' => 4500],
];
$id = filter_input(INPUT_GET, 'details', FILTER_VALIDATE_INT);
if (!$id || !isset($products[$id])) {
echo '<p>Товар не найден.</p>';
exit;
}
$product = $products[$id];
echo '<h2>' . htmlspecialchars($product['name']) . '</h2>';
echo '<p>Цена: ' . (int)$product['price'] . ' руб.</p>';
?>
Результат для id=2:
<h2>Курс «Веб-разработка»</h2> <p>Цена: 4500 руб.</p>
Пример 3: Использование filter_input с маской фильтрации
Допустим, параметр может быть строкой, но мы хотим разрешить только буквы, цифры и дефис (например, для слага).
$slug = filter_input(INPUT_GET, 'details', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
// Более надёжно: самостоятельно проверить через регулярное выражение
if (!preg_match('/^[a-zA-Z0-9-]+$/', $slug)) {
echo 'Недопустимые символы в идентификаторе';
exit;
}
// Далее используем $slug в запросе, но обязательно экранируем или используем prepared statement
Цель: Обработка параметров, которые не являются числом (например, название товара в URL).
Пример 4: Кеширование результата для одного id
Чтобы не загружать базу данных при каждом запросе, можно сохранить результат в файловый кеш.
<?php
$id = filter_input(INPUT_GET, 'details', FILTER_VALIDATE_INT);
if (!$id) { /* ... */ }
$cacheFile = 'cache/product_' . $id . '.html';
$cacheTime = 3600; // 1 час
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheTime)) {
readfile($cacheFile);
exit;
}
// Генерация HTML из БД
ob_start();
// ... код вывода ...
$html = ob_get_clean();
file_put_contents($cacheFile, $html);
echo $html;
?>
Пояснение: Кеш ускоряет повторные запросы, но требует очистки при изменении данных.
Пример 5: Обработка JSON-ответа для AJAX
Если страница деталей вызывается через fetch, удобно возвращать JSON.
<?php
header('Content-Type: application/json; charset=utf-8');
$id = filter_input(INPUT_GET, 'details', FILTER_VALIDATE_INT);
if (!$id) {
echo json_encode(['error' => 'Неверный id']);
exit;
}
// Запрос к БД ...
if ($product) {
echo json_encode(['success' => true, 'data' => $product]);
} else {
echo json_encode(['success' => false, 'message' => 'Товар не найден']);
}
?>
Результат при успехе:
{"success":true,"data":{"id":42,"name":"Смартфон X100","price":25000}}
Случаи использования: Одностраничные приложения, подгрузка данных без перезагрузки.