Реализация публичной страницы PHP используя идентификатор
При разработке веб-приложений на PHP часто возникает задача отображения информации на отдельной странице в зависимости от переданного идентификатора (ID). Например, страница статьи, товара или пользователя. В данной статье рассматриваются различные способы реализации такой страницы, начиная от простейших и заканчивая профессиональными подходами с использованием маршрутизации и безопасности.
Основные подходы к созданию публичной страницы по ID
Наиболее эффективное решение: использование единого точки входа (front controller) с обработкой параметра ID через подготовленные запросы PDO. Этот подход обеспечивает безопасность, гибкость и поддержку.
Пример реализации:
// index.php - точка входа
require 'config.php';
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
http_response_code(400);
exit('Некорректный ID');
}
$stmt = $pdo->prepare('SELECT * FROM pages WHERE id = :id');
$stmt->execute(['id' => $id]);
$page = $stmt->fetch();
if (!$page) {
http_response_code(404);
exit('Страница не найдена');
}
echo '' . htmlspecialchars($page['title']) . '
';
echo '' . htmlspecialchars($page['content']) . '';Public php id (публичная страница php по id)
(Вывод: заголовок и содержимое страницы из базы данных, экранированные для защиты от XSS)
Пояснение: filter_input проверяет, что ID является целым числом. Используется подготовленный запрос для защиты от SQL-инъекций. htmlspecialchars предотвращает XSS-атаки. Код обрабатывает случаи отсутствия ID (400) и отсутствия записи (404).
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);.Как сделать чистые URL (ЧПУ) для страниц по ID?
Для создания ссылок вида /page/123 используется Apache mod_rewrite. В файле .htaccess правила преобразуют ЧПУ в параметры GET.
RewriteEngine On
RewriteRule ^page/(\d+)$ index.php?id=$1 [L,QSA]// index.php
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
// ... остальная логика как в основном примереПояснение: правило RewriteRule захватывает числовую часть URL и передаёт её в index.php как параметр id. Флаг L останавливает обработку, QSA добавляет существующие параметры.
Как использовать готовый роутер для обработки ID?
Библиотека FastRoute позволяет гибко определять маршруты. Устанавливается через Composer.
// index.php
require 'vendor/autoload.php';
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/page/{id:\d+}', 'pageHandler');
});
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
$handler($vars['id']);
break;
case FastRoute\Dispatcher::NOT_FOUND:
http_response_code(404);
break;
}
function pageHandler($id) {
// аналогичная логика с БД
}Пояснение: роутер избавляет от ручного разбора URL, поддерживает REST и различные методы HTTP. Номер ID валидируется регулярным выражением \d+.
Как обработать страницы разных типов (новости, товары) через один скрипт?
Можно добавить параметр типа: page.php?type=news&id=5 и использовать switch.
$type = filter_input(INPUT_GET, 'type', FILTER_SANITIZE_STRING);
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if (!$id) { /* 400 */ }
switch ($type) {
case 'news':
$table = 'news';
break;
case 'product':
$table = 'products';
break;
default:
http_response_code(404);
exit;
}
$stmt = $pdo->prepare("SELECT * FROM $table WHERE id = :id");
$stmt->execute(['id' => $id]);Пояснение: использование switch с белым списком таблиц предотвращает SQL-инъекции. Нельзя подставлять переменную напрямую в запрос, но в данном случае таблица выбирается из ограниченного набора.
Далее представлены расширенные примеры реализации публичной страницы по ID с полным кодом и отображением результатов.
Пример 1: Полный скрипт с обработкой ошибок
<?php
// config.php
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8mb4';
$user = 'root';
$pass = '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
http_response_code(500);
exit('Ошибка подключения к БД');
}
// index.php
require 'config.php';
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if ($id === false || $id === null) {
http_response_code(400);
exit('Неверный ID. Используйте положительное целое число.');
}
try {
$stmt = $pdo->prepare('SELECT * FROM pages WHERE id = ?');
$stmt->execute([$id]);
$page = $stmt->fetch();
} catch (PDOException $e) {
http_response_code(500);
exit('Ошибка запроса к БД');
}
if (!$page) {
http_response_code(404);
exit('Страница не найдена');
}
?>
<!DOCTYPE html>
<html>
<head><title><?= htmlspecialchars($page['title']) ?></title></head>
<body>
<h1><?= htmlspecialchars($page['title']) ?></h1>
<div><?= nl2br(htmlspecialchars($page['content'])) ?></div>
</body>
</html>При вызове index.php?id=1 (существующий ID) выводится HTML страница с заголовком и содержимым. При вызове index.php?id=abc - возвращается 400 с сообщением об ошибке. При вызове index.php?id=999 - возвращается 404 с сообщением.
Пример 2: Использование .htaccess для ЧПУ и обработка в index.php
# .htaccess в корне
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^page/(\d+)$ index.php?id=$1 [L,QSA]
# index.php (сокращённо)
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if (!$id) {
http_response_code(404);
exit('Страница не найдена');
}
// ... запрос к БДURL: /page/5 -> index.php?id=5 -> отображается страница с ID=5. URL: /page/text -> не соответствует правилу (только цифры) и может привести к 404.
Пример 3: Использование FastRoute с разделением на контроллеры
// index.php
require 'vendor/autoload.php';
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/', 'HomeController@index');
$r->addRoute('GET', '/page/{id:\d+}', 'PageController@show');
});
$routeInfo = $dispatcher->dispatch($_SERVER['REQUEST_METHOD'], parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
list($class, $method) = explode('@', $handler, 2);
$controller = new $class($pdo);
echo $controller->$method($vars['id']);
break;
case FastRoute\Dispatcher::NOT_FOUND:
http_response_code(404);
echo '404 Not Found';
break;
}При запросе /page/42 вызывается метод show контроллера PageController с параметром id=42. Возвращается сгенерированный HTML.
Пример 4: Обработка пагинации и дополнительных параметров
// URL: /page?category=news&id=123&page=2
$category = filter_input(INPUT_GET, 'category', FILTER_SANITIZE_STRING);
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
$pageNum = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, ['options' => ['default' => 1, 'min_range' => 1]]);
$allowedCategories = ['news', 'blog', 'article'];
if (!in_array($category, $allowedCategories)) {
http_response_code(404);
exit('Неверная категория');
}
// запрос с LIMIT и OFFSET, используя $pageNumТот же принцип, но с дополнительными параметрами для фильтрации и пагинации.