Настройка веб-сервера для скрытия index.php в адресах сайта
При использовании фреймворков (Laravel, CodeIgniter, Symfony) и CMS (WordPress, Drupal) в URL может присутствовать index.php, например, example.com/index.php/news. Это ухудшает читаемость адресов и SEO. Удаление index.php позволяет получить чистые ЧПУ-ссылки. Ниже рассмотрены способы настройки для основных веб-серверов.
Варианты конфигурации веб-сервера
Как настроить Apache с mod_rewrite для удаления index.php?
Самый распространённый метод - использование файла .htaccess в корне сайта.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
убираем index php (удаление index.php из url)
Пояснение: первая строка включает модуль rewrite, две проверки исключают реально существующие файлы и папки, последняя строка перенаправляет все остальные запросы на index.php с сохранением пути. Правило располагается до любых других директив.
Типичные ошибки:
- 500 Internal Server Error - модуль mod_rewrite не активирован (выполните
sudo a2enmod rewriteи перезагрузите Apache). - Не работает для вложенных путей - может потребоваться
RewriteBase /перед правилом. - Конфликт с кэширующими плагинами - проверьте порядок правил, кэш должен обрабатываться до редиректа.
Как настроить Nginx для удаления index.php?
В конфигурации сервера (обычно в блоке location) добавляется директива try_files.
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Пояснение: Nginx последовательно пытается отдать статический файл, затем директорию, и если ничего не найдено - передаёт управление index.php с передачей строки запроса. Это наиболее эффективный и безопасный способ.
- Статика не грузится - убедитесь, что для статических файлов (CSS, JS, картинки) есть отдельные блоки location, обрабатывающие их напрямую, и они расположены до этого правила.
- Ошибка 404 на папки - если папка существует, try_files вернёт её содержимое, что не всегда нужно; лучше использовать
try_files $uri $uri/ /index.php;без папки. - Проблемы с fastcgi_pass - убедитесь, что в блоке location ~ \.php$ настроена передача на PHP-FPM.
Как настроить IIS для удаления index.php?
Для IIS используется файл web.config с правилом переписывания URL.
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Remove index.php" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Пояснение: правило срабатывает, если запрашиваемый файл или папка не существует, и перезаписывает URL на index.php с сохранением пути. Требуется установленный модуль URL Rewrite.
- Ошибка 500.19 - модуль URL Rewrite не установлен. Скачайте и установите его через Web Platform Installer.
- Правило не применяется - проверьте, что файл web.config размещён в корне сайта, и в IIS включено переопределение конфигурации.
Как удалить index.php при использовании встроенного сервера PHP?
При запуске php -S localhost:8000 URL с index.php можно убрать с помощью скрипта-роутера.
// router.php
$uri = $_SERVER['REQUEST_URI'];
$path = parse_url($uri, PHP_URL_PATH);
if (file_exists(__DIR__ . $path)) {
return false; // отдаём статику
}
$_SERVER['SCRIPT_NAME'] = '/index.php';
$_SERVER['PHP_SELF'] = '/index.php';
require __DIR__ . '/index.php';
Запуск: php -S localhost:8000 router.php. Скрипт проверяет существование файла, и если его нет, подключает index.php, корректируя переменные сервера.
- 404 на существующий файл в подпапке - убедитесь, что путь формируется правильно, иногда требуется обработка пути без лидирующего слеша.
- Не работают POST-запросы - проверьте, что $uri не теряет тело запроса; встроенный сервер PHP корректен в этом плане.
Как использовать FallbackResource в Apache без mod_rewrite?
Директива FallbackResource доступна в Apache 2.4+ и не требует включения rewrite.
FallbackResource /index.php
Пояснение: все запросы к несуществующим файлам и папкам перенаправляются на указанный ресурс. Размещать директиву можно в .htaccess или в конфигурации виртуального хоста.
- Директива не работает - проверьте версию Apache (требуется 2.4.0+).
- Потеря пути - FallbackResource не передаёт остаток URL, его нужно обрабатывать через $_SERVER['REQUEST_URI'] в index.php.
Дополнительные примеры и нестандартные ситуации
Ниже приведены расширенные сценарии настройки, которые могут пригодиться при сложной конфигурации.
Автоматический редирект с index.php на чистый URL (Apache)
Данное правило не только скрывает index.php, но и перенаправляет пользователей, которые ввели URL с index.php, на версию без него (для SEO и единообразия).
RewriteEngine On
# Перенаправление запросов, содержащих index.php
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\s/index\.php(/[^\s]*)?\s [NC]
RewriteRule ^index\.php(.*)$ /$1 [R=301,L]
# Основное правило для внутреннего переписывания
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Пояснение: первая часть ловит HTTP-запрос, содержащий /index.php, и выдаёт постоянный редирект на адрес без index.php. Вторая часть обрабатывает все остальные ЧПУ.
Результат: запрос /index.php/news становится /news в адресной строке браузера.
Настройка для Laravel в поддиректории
Если приложение Laravel расположено в /subfolder, правила должны учитывать путь.
# .htaccess в /subfolder
RewriteEngine On
RewriteBase /subfolder/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Или для Nginx (в location /subfolder):
location /subfolder {
try_files $uri $uri/ /subfolder/index.php?$query_string;
}
Важно: в PHP используйте config('app.url') с учётом подпапки.
Комбинация с HTTPS и www редиректами (Apache)
Часто требуется одновременно перенаправить на HTTPS, убрать www и index.php.
RewriteEngine On
# Редирект на HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# Удаление www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# Удаление index.php из запроса
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\s/index\.php(/[^\s]*)?\s [NC]
RewriteRule ^index\.php(.*)$ /$1 [R=301,L]
# Основное правило
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Результат: http://www.example.com/index.php/page преобразуется в https://example.com/page.
Использование php.ini для встроенного сервера PHP с расширенным роутером
Можно задать роутер через конфигурацию php.ini, чтобы не указывать его в командной строке каждый раз.
; php.ini
cli_server.router = /path/to/router.php
Сам роутер для фреймворка (например, Slim):
// router.php
$uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
if (file_exists(__DIR__ . $uri) && !is_dir(__DIR__ . $uri)) {
return false;
}
// Имитация запуска index.php
$_SERVER['SCRIPT_NAME'] = '/index.php';
require __DIR__ . '/index.php';
Запуск: php -S localhost:8000 (роутер берётся из php.ini). Удобно для разработки.
Обработка index.php в URL для CodeIgniter 3
CodeIgniter имеет конфигурацию config['index_page'] = ''; в application/config/config.php. После этого достаточно настроить .htaccess.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Проблема: если в URL оставлен index.php, CodeIgniter его не убирает автоматически. Добавьте редирект:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\s/index\.php(/[^\s]*)?\s [NC]
RewriteRule ^index\.php(.*)$ /$1 [R=301,L]