Контентные страницы в PHP: построение и шаблонизация

Раздел: Веб-программирование на 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;
  });
  

Результат: защита страниц контента от неавторизованного доступа.

Страница контента на PHP - comments

En
Content pages php page (php)