Настройка веб-сервера для скрытия index.php в адресах сайта

Раздел: Веб-сервер -> ЧПУ URL

При использовании фреймворков (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]

Удаление index.php из URL - comments

En
убираем index php (php)