Создание системы категорий страниц с использованием index.php в PHP
Организация категорий страниц через index.php
Наиболее эффективное решение основано на разборе URI и динамическом подключении файлов из каталогов, соответствующих категориям. При таком подходе структура сайта повторяет файловую систему: каждая категория - это папка, а страница - файл внутри неё.
<?php
$uri = $_SERVER['REQUEST_URI'];
$uri = parse_url($uri, PHP_URL_PATH);
$uri = trim($uri, '/');
$segments = explode('/', $uri);
$category = $segments[0] ?? 'home';
$page = $segments[1] ?? 'index';
$allowedCategories = ['home', 'news', 'blog', 'shop'];
if (!in_array($category, $allowedCategories)) {
http_response_code(404);
include 'pages/404.php';
exit;
}
$file = __DIR__ . '/pages/' . $category . '/' . $page . '.php';
if (file_exists($file)) {
include $file;
} else {
http_response_code(404);
include 'pages/404.php';
}
?>
Home php table (таблица home в php)
Пояснение шагов:
- Получение пути из
$_SERVER['REQUEST_URI']и удаление GET-параметров. - Разделение строки на сегменты (первый - категория, второй - страница).
- Проверка категории по белому списку во избежание directory traversal.
- Конструирование пути к файлу и его подключение при успехе.
- Отдача 404 при отсутствии категории или страницы.
Типичные ошибки и решения:
- Атака через
../- использование белого списка категорий илиbasenameдля каждого сегмента. - Конфликт с кешированием - добавление в .htaccess директив для отключения кеша для index.php.
- Проблемы с вложенными категориями - для глубокой вложенности потребуется регулярное выражение или цикл.
Как организовать категории через GET-параметры?
Классический подход с параметрами в строке запроса: index.php?category=news&page=article.
<?php
$category = $_GET['category'] ?? 'home';
$page = $_GET['page'] ?? 'index';
// фильтрация
$category = preg_replace('/[^a-zA-Z0-9_-]/', '', $category);
$page = preg_replace('/[^a-zA-Z0-9_-]/', '', $page);
$file = __DIR__ . '/pages/' . $category . '/' . $page . '.php';
if (file_exists($file)) {
include $file;
} else {
echo '404';
}
?>
Home member php (участник home в php)
Цели: простота реализации, понятные URL для человека и поисковиков, хотя последние предпочитают ЧПУ.
Проблемы: незащищённые параметры, необходимость фильтрации; сложность с SEO; возможность дублирования контента (один и тот же контент на разных URL).
Как перенаправить все запросы на index.php с помощью .htaccess?
Для полностью дружественных URL используется mod_rewrite. Все запросы направляются в index.php, а сам PHP обрабатывает путь.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Home php product (продукт home в php)
В index.php:
<?php
$uri = $_SERVER['REQUEST_URI'];
$uri = trim(parse_url($uri, PHP_URL_PATH), '/');
// разбор и подключение
$parts = explode('/', $uri);
$category = $parts[0] ?? 'home';
$page = $parts[1] ?? 'index';
// ... проверки и include
?>
Index php page category (категория страницы в php)
Цели: максимально красивые URL, единая точка входа для всех страниц.
Ошибки: забытый RewriteBase при размещении в подкаталоге; циклические редиректы, если не исключены существующие файлы; необходимость настройки сервера.
Как реализовать категории через автозагрузку классов (MVC)?
Каждая страница - это класс с методом render(). Автозагрузка подключает файл класса по именам категорий и страниц.
<?php
spl_autoload_register(function ($class) {
$parts = explode('\\', $class);
$path = __DIR__ . '/classes/' . implode('/', $parts) . '.php';
if (file_exists($path)) {
require $path;
}
});
$uri = $_SERVER['REQUEST_URI'];
$uri = trim(parse_url($uri, PHP_URL_PATH), '/');
$segments = explode('/', $uri);
$category = ucfirst($segments[0] ?? 'Home');
$page = ucfirst($segments[1] ?? 'Index');
$className = "Pages\\{$category}\\{$page}";
if (class_exists($className)) {
$obj = new $className();
$obj->render();
} else {
echo 'Страница не найдена';
}
?>
Html home php content (контент home в php)
Цели: чистая архитектура, возможность легко добавлять новое поведение, тестирование.
Проблемы: сложность для простых сайтов, необходимость поддерживать структуру классов, возможное замедление автозагрузки при большом количестве классов.
Как хранить категории в БД и динамически загружать страницы?
Используется таблица categories и pages. По URL (slug) выбирается страница и выводится её содержимое.
<?php
$uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
$parts = explode('/', $uri);
$catSlug = $parts[0] ?? '';
$pageSlug = $parts[1] ?? '';
$stmt = $pdo->prepare('
SELECT p.* FROM pages p
JOIN categories c ON c.id = p.category_id
WHERE c.slug = ? AND p.slug = ?
');
$stmt->execute([$catSlug, $pageSlug]);
$page = $stmt->fetch();
if ($page) {
echo $page['content'];
} else {
http_response_code(404);
echo 'Страница не найдена';
}
?>
Цели: гибкое управление контентом, возможность менять содержимое без изменения файлов, поддержка множества языков.
Проблемы: нагрузка на базу данных при каждом запросе (решается кешированием), сложность первоначальной настройки, необходимость индексации slug.
Расширенные примеры для системы категорий через index.php
Ниже приведены более полные реализации, охватывающие дополнительные аспекты.
Пример 1: Маршрутизатор с поддержкой вложенных категорий (любой уровень вложенности)
<?php
// index.php - универсальный маршрутизатор
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$path = trim($path, '/');
$segments = explode('/', $path);
// Удаляем из сегментов пустые строки
$segments = array_values(array_filter($segments, function($v) { return $v !== ''; }));
// Последний сегмент - это имя страницы (без расширения)
$pageName = array_pop($segments) ?: 'index';
// Остальные сегменты - путь к категории
$categoryPath = implode('/', $segments);
$baseDir = __DIR__ . '/pages';
$fullPath = $baseDir . '/' . $categoryPath . '/' . $pageName . '.php';
// Безопасность: проверяем, что путь ведёт внутрь pages
$realBase = realpath($baseDir);
$realFile = realpath($fullPath);
if ($realFile === false || strpos($realFile, $realBase) !== 0) {
http_response_code(404);
echo 'Файл не найден';
exit;
}
if (file_exists($fullPath)) {
include $fullPath;
} else {
http_response_code(404);
include $baseDir . '/404.php';
}
?>
Результат: при запросе /news/2024/march/article будет подключён файл pages/news/2024/march/article.php.
Пример 2: Маршрутизатор с использованием регулярных выражений (роутинг)
<?php
$routes = [
'news/(\d+)/(\d+)/([a-z-]+)' => 'news/article.php',
'blog/([a-z-]+)' => 'blog/post.php',
'page/([a-z-]+)' => 'pages/custom.php',
];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$matched = false;
foreach ($routes as $pattern => $file) {
if (preg_match('#^' . $pattern . '$#', trim($uri, '/'), $matches)) {
$matched = true;
$params = array_slice($matches, 1);
$_GET['params'] = $params;
include __DIR__ . '/' . $file;
break;
}
}
if (!$matched) {
http_response_code(404);
echo 'Страница не найдена';
}
?>
Результат: вызов /news/2024/03/some-article передаёт параметры в news/article.php.
Пример 3: Использование .htaccess для чистой маршрутизации (с исключениями)
RewriteEngine On
# Не перенаправлять реально существующие файлы и директории
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Не перенаправлять папки assets, uploads и т.п.
RewriteCond %{REQUEST_URI} !^/assets/ [NC]
RewriteCond %{REQUEST_URI} !^/uploads/ [NC]
RewriteRule ^(.*)$ index.php [QSA,L]
В index.php - любой из описанных выше обработчиков. Результат: URL типа /blog/post-name обрабатываются без суффикса .php.
Пример 4: Автозагрузка классов с пространствами имён и конфигурацией маршрутов
<?php
// autoload.php
spl_autoload_register(function ($class) {
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relativeClass = substr($class, $len);
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
});
// index.php
require 'autoload.php';
use App\Router;
$router = new Router();
$router->add('/category/{slug}/page/{id}', 'Controller@show');
$router->dispatch($_SERVER['REQUEST_URI']);
?>
Результат: чистая архитектура, легко добавлять новые маршруты в конфигурационном файле.
Пример 5: Категории на основе базы данных с кешированием (Redis)
<?php
// index.php
$cache = new Redis();
$cache->connect('127.0.0.1', 6379);
$uriKey = 'page_' . md5($_SERVER['REQUEST_URI']);
$cachedContent = $cache->get($uriKey);
if ($cachedContent !== false) {
echo $cachedContent;
exit;
}
// Разбираем URL, делаем запрос к БД, получаем контент
// ... (код аналогичен представленному в основном варианте)
$content = $page['content'];
$cache->setex($uriKey, 3600, $content); // кеш на час
echo $content;
?>
Результат: снижение нагрузки на БД, быстрая отдача контента.