Контентные страницы в PHP: построение и шаблонизация
Создание страниц контента на PHP
Основным эффективным решением для создания страниц контента на PHP является использование роутера, связывающего URL с контроллером, и шаблонизатора, отделяющего логику от представления. Такой подход позволяет легко управлять контентом, хранить его в базе данных и менять внешний вид без изменения кода. Рассмотрим реализацию с помощью библиотеки Twig и простого роутинга.
Пример структуры:
// index.php - точка входа
require 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader, ['cache' => 'cache', 'debug' => true]);
$route = $_GET['page'] ?? 'home';
$pages = ['home', 'about', 'contact'];
if (in_array($route, $pages)) {
$content = file_get_contents('content/' . $route . '.html');
echo $twig->render('page.twig', ['title' => $route, 'content' => $content]);
} else {
http_response_code(404);
echo $twig->render('404.twig');
}
Tags php tag list (список тегов в php)
Здесь файлы контента хранятся в папке content как HTML-фрагменты. Шаблон page.twig выводит переданный контент.
Типичные ошибки:
- Неправильные пути к шаблонам и контенту - нужно использовать абсолютные пути или константы.
- Отсутствие кэша Twig в продакшене - снижает производительность.
- XSS-уязвимости при выводе неэкранированного контента - использовать
| rawтолько для доверенного контента.
Как сделать статическую страницу контента через include?
Простейший вариант - использовать оператор include для подключения HTML-файла в зависимости от параметра. Недостаток - отсутствие гибкости и безопасности, но для маленьких проектов подходит.
$page = $_GET['p'] ?? 'home';
$allowed = ['home', 'about', 'contact'];
if (in_array($page, $allowed)) {
include 'pages/' . $page . '.php';
} else {
include 'pages/404.php';
}
Content pages php page (страница контента на php)
Проблемы:
- Прямой доступ к файлам через URL - требуется защита.
- Смешивание логики и представления.
Как реализовать страницу контента с использованием собственного шаблонизатора?
Можно написать простой класс, заменяющий метки вида {{ переменная }} на значения. Это даёт больше контроля, но требует дополнительного кода.
class SimpleTemplate {
private $vars = [];
public function assign($name, $value) { $this->vars[$name] = $value; }
public function render($template) {
$content = file_get_contents('templates/' . $template . '.html');
foreach ($this->vars as $key => $val) {
$content = str_replace('{{ ' . $key . ' }}', $val, $content);
}
return $content;
}
}
// Использование
$tpl = new SimpleTemplate();
$tpl->assign('title', 'О нас');
$tpl->assign('body', 'Текст о компании
');
echo $tpl->render('page');
Index php content id 9 (вывод контента по id в php)
Недостатки:
- Нет автоматического экранирования - нужно экранировать вручную.
- Поддержка циклов и условий усложняет реализацию.
Как создать страницу контента с использованием микрофреймворка Slim?
Slim предоставляет роутинг, middleware и встроенную поддержку шаблонов (через Twig или Plain). Пример маршрута для отображения страницы контента из БД:
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require 'vendor/autoload.php';
$app = AppFactory::create();
$app->get('/page/{slug}', function (Request $request, Response $response, $args) {
$slug = $args['slug'];
// получаем контент из БД по slug
$content = getContentFromDatabase($slug);
if (!$content) {
$response->getBody()->write('Page not found');
return $response->withStatus(404);
}
$response->getBody()->write($content);
return $response;
});
$app->run();
Типичные ошибки:
- Не настроен .htaccess для маршрутизации всех запросов на index.php.
- Отсутствие валидации slug - возможны SQL-инъекции.
Расширенные примеры
Пример 1. Вывод контента из базы данных с использованием Twig и PDO
В этом примере используется подготовленный запрос для безопасного получения контента по слагу. Затем данные передаются в шаблон Twig.
// index.php
require 'vendor/autoload.php';
$dsn = 'mysql:host=localhost;dbname=mydb;charset=utf8';
$pdo = new PDO($dsn, 'user', 'pass');
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader, ['cache' => 'cache']);
$slug = $_GET['slug'] ?? 'home';
$stmt = $pdo->prepare('SELECT title, body FROM pages WHERE slug = :slug AND active = 1');
$stmt->execute([':slug' => $slug]);
$page = $stmt->fetch(PDO::FETCH_ASSOC);
if ($page) {
echo $twig->render('content.twig', [
'title' => $page['title'],
'body' => $page['body']
]);
} else {
http_response_code(404);
echo $twig->render('404.twig', ['message' => 'Страница не найдена']);
}
Результат: страница отображается с заголовком и телом, взятыми из БД. Если страница неактивна или не существует - 404.
Пример 2. Кэширование сгенерированных страниц
Для ускорения работы можно кэшировать HTML-вывод в файлы. Код проверяет наличие кэша и время его жизни.
$cacheDir = __DIR__ . '/cache/pages/';
$cacheKey = md5($slug) . '.html';
$cacheFile = $cacheDir . $cacheKey;
$ttl = 3600; // 1 час
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $ttl)) {
echo file_get_contents($cacheFile);
exit;
}
ob_start();
// обычный вывод страницы
echo $twig->render(...);
$html = ob_get_clean();
file_put_contents($cacheFile, $html);
echo $html;
Результат: при повторном запросе в течение часа файл отдаётся без обращения к БД.
Пример 3. REST API для управления контентом (CRUD)
Создадим простой API на чистом PHP (без фреймворков) для создания, чтения, обновления и удаления страниц. Используется метод запроса.
// api.php
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
$pdo = new PDO(...);
switch ($method) {
case 'GET':
$stmt = $pdo->query('SELECT id, title, slug FROM pages');
echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));
break;
case 'POST':
$input = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare('INSERT INTO pages (title, slug, body) VALUES (?, ?, ?)');
$stmt->execute([$input['title'], $input['slug'], $input['body']]);
echo json_encode(['id' => $pdo->lastInsertId()]);
break;
// PUT, DELETE аналогично
}
Результат: можно управлять контентом через HTTP-запросы (например, с помощью Postman).
Пример 4. Использование Middleware для проверки доступа
В Slim можно добавить middleware, проверяющий, авторизован ли пользователь для просмотра контента.
$app->add(function ($request, $handler) {
$response = $handler->handle($request);
// дополнительная логика
return $response;
});
Результат: защита страниц контента от неавторизованного доступа.