Отображение деталей записи с помощью GET-параметра

Раздел: Веб-разработка -> Работа с 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}}

Случаи использования: Одностраничные приложения, подгрузка данных без перезагрузки.

Вывод деталей по ID - comments

En
Index php details id (php)