Реализация просмотра статьи с помощью index.php
Основное решение: получение статьи из базы данных через PDO
Наиболее эффективный и безопасный способ просмотра статьи в PHP - использование базы данных (MySQL) с расширением PDO и подготовленными запросами. Это обеспечивает защиту от SQL-инъекций и гибкость выборки данных.
Цель: отобразить полное содержимое статьи по её уникальному идентификатору (ID). Случаи использования: любой сайт или блог, где статьи хранятся в БД.
// index.php
$id = (int)$_GET['id'] ?? 0;
if (!$id) { http_response_code(400); exit('Неверный запрос'); }
$pdo = new PDO('mysql:host=localhost;dbname=blog;charset=utf8', 'user', 'pass');
$stmt = $pdo->prepare('SELECT title, content, date FROM articles WHERE id = ?');
$stmt->execute([$id]);
$article = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$article) { http_response_code(404); exit('Статья не найдена'); }
?>
<!DOCTYPE html>
<html><head><title><?= htmlspecialchars($article['title']) ?></title></head>
<body><h1><?= htmlspecialchars($article['title']) ?></h1>
<div><?= nl2br(htmlspecialchars($article['content'])) ?></div>
<p>Дата: <?= $article['date'] ?></p></body></html>Article php page (статья на php)
Типичные проблемы:
- Отсутствие проверки наличия GET-параметра id - ведёт к ошибкам. Решение: использовать оператор ?? с приведением к int.
- Вывод данных без экранирования - XSS-уязвимости. Решение: всегда применять htmlspecialchars() с флагом ENT_QUOTES.
- Ошибки соединения с БД - обрабатывать через try-catch и логирование.
Варианты решений
Как сделать просмотр статьи по символьному идентификатору (slug)?
Slug (человеко-понятный URL) улучшает SEO и читаемость адреса. В БД добавляется поле slug. Запрос выполняется по нему.
$slug = $_GET['slug'] ?? '';
$slug = trim($slug);
if (!preg_match('/^[a-z0-9-]+$/', $slug)) { http_response_code(400); exit; }
$stmt = $pdo->prepare('SELECT * FROM articles WHERE slug = ?');
$stmt->execute([$slug]);
$article = $stmt->fetch();Index php view article (индекс php просмотр статьи)
Как реализовать просмотр статьи при хранении в файловой системе?
Если контент хранится в текстовых файлах (например, .md или .txt), index.php читает файл по имени.
$filename = basename($_GET['file'] ?? '');
$path = __DIR__ . '/articles/' . $filename . '.txt';
if (!file_exists($path)) { http_response_code(404); exit('Файл не найден'); }
$content = file_get_contents($path);
$lines = explode("\n", $content, 2);
$title = $lines[0];
$body = $lines[1] ?? '';Как использовать простую маршрутизацию без фреймворка?
Маршрутизация позволяет обрабатывать URL вида /article/42 или /article/my-slug. index.php анализирует REQUEST_URI.
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$path = trim($uri, '/');
$parts = explode('/', $path);
if ($parts[0] === 'article' && isset($parts[1])) {
$id = (int)$parts[1];
// далее получение статьи из БД
}Как отобразить статью с помощью шаблонизатора Twig?
Twig отделяет логику от представления. Устанавливается через Composer. В index.php подключается шаблон.
require 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader);
echo $twig->render('article.html', ['article' => $article]);Расширенные примеры реализации просмотра статьи
1. Класс Article с обработкой ошибок
class Article {
private PDO $pdo;
public function __construct(PDO $pdo) { $this->pdo = $pdo; }
public function getById(int $id): ?array {
$stmt = $this->pdo->prepare('SELECT * FROM articles WHERE id = ?');
$stmt->execute([$id]);
$article = $stmt->fetch(PDO::FETCH_ASSOC);
return $article ?: null;
}
public function getBySlug(string $slug): ?array {
$stmt = $this->pdo->prepare('SELECT * FROM articles WHERE slug = ?');
$stmt->execute([$slug]);
return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
}
}
// index.php
$article = new Article($pdo);
$data = $article->getById((int)($_GET['id'] ?? 0));
if (!$data) { http_response_code(404); exit; }Результат: объект класса Article инкапсулирует логику получения данных, код становится более читаемым и тестируемым.
2. Отправка заголовка 404 при отсутствии статьи
if (!$article) {
http_response_code(404);
header('Location: /404.php'); // или вывод кастомной страницы
exit;
}Браузер получает статус 404, что важно для SEO и аналитики.
3. Использование подготовленных запросов с именованными параметрами
$stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id');
$stmt->execute([':id' => $id]);
$article = $stmt->fetch();Удобно при множестве параметров - код легче читать.
4. Вывод статьи с Markdown (через Parsedown)
$parsedown = new Parsedown();
echo $parsedown->text(htmlspecialchars($article['content']));Контент преобразуется из Markdown в HTML, при этом экранирование предотвращает XSS.
5. Кэширование результата запроса (файловый кэш)
$cacheFile = __DIR__ . '/cache/article_' . $id . '.html';
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 3600)) {
echo file_get_contents($cacheFile);
exit;
}
ob_start();
// ... вывод статьи ...
$html = ob_get_clean();
file_put_contents($cacheFile, $html);
echo $html;Снижает нагрузку на базу данных при частых запросах. Время жизни кэша настраивается.
6. Обработка ошибок PDO с try-catch
try {
$pdo = new PDO(...);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare(...);
$stmt->execute(...);
} catch (PDOException $e) {
error_log('DB error: ' . $e->getMessage());
http_response_code(500);
exit('Внутренняя ошибка сервера');
}Безопасный способ обработки ошибок без раскрытия деталей пользователю.
7. Использование ORM RedBeanPHP для простоты
require 'rb.php';
R::setup('mysql:host=localhost;dbname=blog', 'user', 'pass');
$article = R::load('articles', $id);
if ($article->id === 0) { /* не найдена */ }Сокращает объём кода, но требует установки библиотеки. Подходит для небольших проектов.