Информация о форуме через index.php: практические примеры

Раздел: Веб-приложения -> Форумные движки

Вывод информации о форуме через index.php: обзор решений

Основной подход - фронт-контроллер с маршрутизацией

Наиболее эффективное решение для вывода информации о форуме через единую точку входа index.php - реализация шаблона «Фронт-контроллер» (Front Controller). Весь трафик направляется на index.php, который анализирует URL (через $_GET или серверные переменные) и подключает нужный обработчик. Это централизует логику, упрощает безопасность (например, единая точка подключения к БД) и позволяет легко добавлять новые страницы.

Ниже приведён минимальный работоспособный пример.


// index.php - начало
// Подключение к базе данных (PDO)
try {
    $pdo = new PDO('mysql:host=localhost;dbname=forum;charset=utf8', 'user', 'pass');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die('Ошибка подключения к БД: ' . $e->getMessage());
}

// Определение запрашиваемой страницы (по умолчанию - главная)
$page = isset($_GET['page']) ? $_GET['page'] : 'home';

// Загрузка данных в зависимости от страницы
switch ($page) {
    case 'home':
        // Получение информации о форуме
        $stmt = $pdo->query('SELECT name, description FROM forum_info LIMIT 1');
        $forum = $stmt->fetch(PDO::FETCH_ASSOC);
        include 'templates/header.php';
        echo '<h1>' . htmlspecialchars($forum['name']) . '</h1>';
        echo '<p>' . htmlspecialchars($forum['description']) . '</p>';
        include 'templates/footer.php';
        break;
    case 'categories':
        // Вывод категорий
        // ...
        break;
    default:
        header('HTTP/1.0 404 Not Found');
        echo 'Страница не найдена';
        break;
}
    

Index php forum info (вывод информации о форуме через index.php)

Этот пример иллюстрирует базовый принцип. В реальном проекте обработку лучше вынести в отдельные классы, а switch заменить на роутер.

Вариант 1: Как сделать простой index.php с условиями без роутера?

Самый простой случай - использовать $_GET['page'] и набор if/else или switch. Подходит для небольших форумов с 3–5 страницами. Недостаток - код разрастается, сложно поддерживать.


$page = $_GET['page'] ?? 'home';
if ($page === 'home') {
    // вывод главной
} elseif ($page === 'contact') {
    // контакты
} else {
    // 404
}
    

Типичная ошибка:

Отсутствие фильтрации $_GET['page'] может привести к включению произвольных файлов (Local File Inclusion).

Решение: использовать белый список разрешённых страниц:


$allowed = ['home','categories','contact'];
$page = in_array($_GET['page'] ?? '', $allowed) ? $_GET['page'] : 'home';
        

Вариант 2: Как организовать ЧПУ-ссылки через index.php?

Для красивых URL (например, /forum/categories/1) используется файл .htaccess (Apache) или конфигурация nginx, который перенаправляет все запросы на index.php. Внутри index.php разбирается $_SERVER['REQUEST_URI'].


// .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
    

// index.php - разбор URL
$uri = trim($_SERVER['REQUEST_URI'], '/');
$parts = explode('/', $uri);
// $parts[0] - секция, $parts[1] - ID и т.д.
    

Вариант 3: Как вывести информацию о форуме с использованием шаблонизатора?

Вместо прямого echo в контроллере логику разделяют: контроллер собирает данные и передаёт их шаблону. Пример с простым PHP-шаблоном:


// index.php
$template = __DIR__ . '/templates/forum_info.php';
$forum = ['name' => 'Мой форум', 'description' => 'Описание форума'];
if (file_exists($template)) {
    extract(['forum' => $forum]);
    ob_start();
    include $template;
    echo ob_get_clean();
}
    


<h1><?= htmlspecialchars($forum['name']) ?></h1>
<p><?= htmlspecialchars($forum['description']) ?></p>
    

Вариант 4: Как организовать вывод через отдельные контроллеры-классы?

Для масштабируемости используется автозагрузка и роутер. Пример простейшего роутера:


class Router {
    private array $routes = [];

    public function add(string $pattern, callable $handler): void {
        $this->routes[$pattern] = $handler;
    }

    public function dispatch(string $uri): void {
        foreach ($this->routes as $pattern => $handler) {
            if (preg_match($pattern, $uri, $matches)) {
                array_shift($matches);
                call_user_func_array($handler, $matches);
                return;
            }
        }
        header('HTTP/1.0 404');
        echo '404';
    }
}

// Использование
$router = new Router();
$router->add('#^forum/info$#', function () use ($pdo) {
    // получение данных и вывод
});
$router->dispatch($_SERVER['REQUEST_URI']);
    

Вариант 5: Как вывести информацию с учётом прав доступа?

Добавление проверки авторизации перед показом данных. Пример:


session_start();
if (!isset($_SESSION['user_id'])) {
    header('Location: /login.php');
    exit;
}
// далее вывод информации
    

Проблема: информация о форуме может быть публичной, но проверка всё равно нужна для других разделов.

Решение: разделять маршруты на публичные и защищённые, вызывая middleware.

Расширенные примеры реализации

Пример 1. Полный рабочий index.php с PDO и безопасным выводом данных форума

Пример

<?php
// index.php
// Конфигурация
define('DB_HOST', 'localhost');
define('DB_NAME', 'forum');
define('DB_USER', 'root');
define('DB_PASS', '');

// Подключение к БД через PDO
try {
    $dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4';
    $pdo = new PDO($dsn, DB_USER, DB_PASS, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
} catch (PDOException $e) {
    http_response_code(500);
    exit('Ошибка подключения к базе данных.');
}

// Простой роутер на основе $_GET['action']
$action = $_GET['action'] ?? 'home';
$allowed = ['home', 'info', 'categories', 'topics', 'post'];
if (!in_array($action, $allowed)) {
    $action = 'home';
}

switch ($action) {
    case 'home':
        // Вывод приветствия и общей информации
        $stmt = $pdo->prepare('SELECT name, description, creation_date FROM forum_info WHERE id = 1');
        $stmt->execute();
        $forum = $stmt->fetch();
        if (!$forum) {
            $forum = ['name' => 'Форум', 'description' => 'Описание отсутствует', 'creation_date' => 'неизвестно'];
        }
        // Экранируем для безопасного вывода
        $name = htmlspecialchars($forum['name'], ENT_QUOTES, 'UTF-8');
        $desc = htmlspecialchars($forum['description'], ENT_QUOTES, 'UTF-8');
        $date = htmlspecialchars($forum['creation_date'], ENT_QUOTES, 'UTF-8');
        echo "<h1>{$name}</h1>\n";
        echo "<p class=\"desc\">{$desc}</p>\n";
        echo "<p>Форум создан: {$date}</p>\n";
        break;

    case 'info':
        // Дополнительная информация (количество тем, сообщений)
        $stats = $pdo->query('SELECT COUNT(*) as topics FROM topics')->fetch();
        $topicsCount = $stats['topics'] ?? 0;
        $stats = $pdo->query('SELECT COUNT(*) as posts FROM posts')->fetch();
        $postsCount = $stats['posts'] ?? 0;
        echo "<p>Тем: {$topicsCount}</p>\n";
        echo "<p>Сообщений: {$postsCount}</p>\n";
        break;

    default:
        header('HTTP/1.0 404 Not Found');
        echo '<h2>404 - Страница не найдена</h2>';
        break;
}
?>

Результат выполнения (при заходе на index.php?action=home с существующей записью в БД):

<h1>Мой форум</h1>
<p class="desc">Добро пожаловать на наш форум!</p>
<p>Форум создан: 2023-05-10</p>

Пример 2. Использование .htaccess и разбор REQUEST_URI для ЧПУ

Пример

# .htaccess (в корневой директории)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Пример

<?php
// index.php
$uri = $_GET['q'] ?? '';
$parts = explode('/', $uri);
$section = $parts[0] ?? 'home';
$id = $parts[1] ?? null;

// Пример: /categories/2 -> section=categories, id=2
if ($section === 'categories' && $id) {
    echo "Вывод категории с ID: " . htmlspecialchars($id);
} elseif ($section === 'home') {
    echo "Главная страница форума";
} else {
    header('HTTP/1.0 404');
    echo "404";
}
?>

Результат при открытии /categories/3:

Вывод категории с ID: 3

Пример 3. Вывод информации о форуме с использованием JSON-API (для AJAX)

Пример

<?php
// index.php?action=api&type=forum
if (isset($_GET['action']) && $_GET['action'] === 'api') {
    header('Content-Type: application/json');
    $pdo = new PDO('mysql:host=localhost;dbname=forum;charset=utf8', 'user', 'pass');
    $stmt = $pdo->query('SELECT name, description FROM forum_info LIMIT 1');
    $data = $stmt->fetch(PDO::FETCH_ASSOC);
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}
// Далее обычный вывод HTML
?>

Результат запроса к index.php?action=api&type=forum:

{"name":"Мой форум","description":"Описание форума"}

Пример 4. Интеграция с простым шаблонизатором (Twig через Composer)

Пример

// composer.json
{
    "require": {
        "twig/twig": "^3.0"
    }
}
// После composer install

// index.php
require_once 'vendor/autoload.php';

$loader = new \Twig\Loader\FilesystemLoader(__DIR__ . '/templates');
$twig = new \Twig\Environment($loader, ['cache' => false]);

$pdo = new PDO(...);
$stmt = $pdo->query('SELECT name, description FROM forum_info LIMIT 1');
$forum = $stmt->fetch();

echo $twig->render('forum.html.twig', [
    'forum_name' => $forum['name'],
    'forum_desc' => $forum['description']
]);
Пример

{# templates/forum.html.twig #}
<h1>{{ forum_name }}</h1>
<p>{{ forum_desc }}</p>

Результат - полностью сформированный HTML с экранированными данными.

Пример 5. Обработка ошибок в index.php

Пример

<?php
// index.php
set_error_handler(function ($severity, $message, $file, $line) {
    if (error_reporting() & $severity) {
        throw new ErrorException($message, 0, $severity, $file, $line);
    }
});
register_shutdown_function(function () {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        http_response_code(500);
        echo '<h2>Внутренняя ошибка сервера</h2>';
    }
});
// ... дальнейший код
?>

Эта конструкция превращает большинство ошибок в исключения и обрабатывает фатальные ошибки в shutdown-функции, что позволяет index.php корректно завершить вывод.

Вывод информации о форуме через index.php - comments

En
Index php forum info (php)