Вывод данных товара по идентификатору в PHP
Основные подходы к созданию страницы товара на PHP
Наиболее эффективное решение для получения товара по ID – использование PDO с подготовленными запросами. Это обеспечивает защиту от SQL-инъекций и удобную обработку ошибок.
// Получение ID из GET-параметра
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
// Обработка ошибки: неверный или отсутствующий ID
http_response_code(400);
echo 'Некорректный идентификатор товара.';
exit;
}
// Подключение к базе данных через PDO
try {
$pdo = new PDO('mysql:host=localhost;dbname=shop;charset=utf8', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT * FROM products WHERE id = :id');
$stmt->execute(['id' => $id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) {
http_response_code(404);
echo 'Товар не найден.';
exit;
}
// Вывод данных товара
echo 'Название: ' . htmlspecialchars($product['name']);
echo 'Цена: ' . htmlspecialchars($product['price']);
} catch (PDOException $e) {
// Логирование ошибки и вывод общего сообщения
error_log($e->getMessage());
http_response_code(500);
echo 'Внутренняя ошибка сервера.';
}Tags php tag list (список тегов в php)
В данном примере filter_input проверяет, что передан целочисленный ID. Затем PDO-запрос с плейсхолдером :id гарантирует безопасную вставку значения. После получения данных используется htmlspecialchars для предотвращения XSS-атак.
Как передать ID товара через POST-запрос?
Использование POST-формы подходит для внутренних действий (например, добавление в корзину), но для просмотра товара предпочтительнее GET. Пример:
// После отправки формы с method="post"
$id = filter_input(INPUT_POST, 'product_id', FILTER_VALIDATE_INT);
// ... аналогичная логика с PDOContent pages php page (страница контента на php)
Как реализовать ЧПУ (человеко-понятный URL) для страницы товара?
Можно использовать маршрутизацию через mod_rewrite или встроенный PHP-роутер. Пример с .htaccess:
RewriteEngine On
RewriteRule ^product/([0-9]+)$ /view_product.php?id=$1 [L,QSA]
Index php content id 9 (вывод контента по id в php)
Тогда URL /product/42 преобразуется в /view_product.php?id=42. В PHP ID извлекается как обычно из $_GET['id'].
Как получить ID товара из сессии (например, последний просмотренный товар)?
Это удобно для функционала "недавно просмотренные". После просмотра сохраняем ID в сессии:
session_start();
$_SESSION['last_viewed'] = $product['id'];
// На другой странице: $id = $_SESSION['last_viewed'] ?? null;Index php id cats (категории контента)
Как обработать случай, когда ID не передан или некорректен?
Важно проверять наличие и тип параметра. Используйте filter_input или is_numeric и проверку > 0. При ошибке возвращайте соответствующий HTTP-статус.
if (!isset($_GET['id']) || !is_numeric($_GET['id']) || $_GET['id'] <= 0) {
http_response_code(400);
exit('Неверный запрос.');
}Типичные ошибки и их решение:
- SQL-инъекция – возникает при вставке $_GET['id'] напрямую в запрос. Решение: использовать подготовленные выражения.
- Отсутствие товара – после fetch() результат может быть false. Обязательно проверять и выводить 404.
- Ошибка подключения к БД – исключение PDOException ловится и логируется, пользователю показывается общая ошибка.
- XSS при выводе – данные из БД могут содержать HTML. Используйте htmlspecialchars().
- Кэширование страницы – если данные редко меняются, можно установить заголовки кэширования или использовать файловый кэш.
Расширенная реализация с шаблонизатором и обработкой ошибок
// view_product.php
function renderTemplate($template, $data) {
extract($data);
ob_start();
include __DIR__ . '/templates/' . $template . '.php';
return ob_get_clean();
}
try {
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if ($id === false) throw new InvalidArgumentException('Invalid product ID.');
$pdo = new PDO('mysql:host=localhost;dbname=shop;charset=utf8', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT * FROM products WHERE id = ?');
$stmt->execute([$id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) throw new NotFoundException('Product not found.');
echo renderTemplate('product', ['product' => $product]);
} catch (InvalidArgumentException $e) {
http_response_code(400);
echo renderTemplate('error', ['message' => 'Некорректный идентификатор']);
} catch (NotFoundException $e) {
http_response_code(404);
echo renderTemplate('error', ['message' => 'Товар не найден']);
} catch (PDOException $e) {
error_log($e->getMessage());
http_response_code(500);
echo renderTemplate('error', ['message' => 'Внутренняя ошибка сервера']);
}Шаблон product.php:
<?= htmlspecialchars($product['name']) ?>
Цена: <?= htmlspecialchars($product['price']) ?> руб.
Описание: <?= nl2br(htmlspecialchars($product['description'])) ?>
Результат выполнения: страница с данными товара или страница ошибки.
Пример вывода связанных товаров
// После получения основного товара
$stmtRelated = $pdo->prepare('SELECT id, name, price FROM products WHERE category_id = ? AND id != ? LIMIT 4');
$stmtRelated->execute([$product['category_id'], $product['id']]);
$relatedProducts = $stmtRelated->fetchAll(PDO::FETCH_ASSOC);
// Затем данные передаются в шаблонРезультат: блок с четырьмя товарами из той же категории, исключая текущий.
Пример кэширования с APCu
$cacheKey = 'product_' . $id;
$product = apcu_fetch($cacheKey);
if ($product === false) {
// Запрос к БД и получение $product
apcu_store($cacheKey, $product, 300); // 5 минут
}
// Далее выводРезультат: ускорение загрузки при повторных запросах, кэш хранится 5 минут.