Как настроить модуль mod_rewrite для обработки всех запросов через index.php
Базовая конфигурация: перенаправление всех запросов на index.php
Основной способ заставить веб-сервер Apache передавать все входящие URL на один файл-обработчик (фронт-контроллер) использует правила mod_rewrite в файле .htaccess или в конфигурации виртуального хоста. Типичная структура:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Mod rewrite index php (настройка mod_rewrite для index.php)
Пояснение:
- RewriteEngine On - включает механизм перезаписи.
- RewriteCond - проверяет, что запрошенный файл или директория не существуют на диске.
- RewriteRule - если условия выполнены, весь путь (^.*$) перенаправляется на
index.phpс сохранением строки запроса (QSA) и остановкой последующих правил (L).
Типичные ошибки:
- 500 Internal Server Error - возникает, если модуль rewrite не включён, или синтаксис .htaccess неверен. Проверяется команда
a2enmod rewrite(Debian/Ubuntu) или строкаLoadModule rewrite_module modules/mod_rewrite.soв httpd.conf (CentOS/RHEL). - Бесконечный цикл - если правило не содержит условия на существующий файл, Apache пытается переписать
index.phpсам на себя. Обязательно добавляютсяRewriteCond %{REQUEST_FILENAME} !-fи для директорий. - Статические файлы (CSS/JS/картинки) не отображаются - проверяется, что пути к ним относительные от корня документа, и они физически существуют. Правило выше пропускает реальные файлы.
Как перенаправлять запросы на index.php, если сайт находится в подкаталоге?
Если проект размещён в подкаталоге (например, /myapp/), необходимо указать RewriteBase:
RewriteEngine On
RewriteBase /myapp/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Upstream php fpm (настройка upstream для php-fpm в nginx)
Без RewriteBase путь вычисляется относительно корня домена, что может привести к 404.
Проблема: При смене подкаталога нужно менять RewriteBase. Альтернатива - использование абсолютного пути в RewriteRule, например RewriteRule ^(.*)$ /myapp/index.php [QSA,L], но возможны проблемы с параметрами.
Как исключить определённые маршруты из перенаправления (например, для админ-панели)?
Иногда требуется отдельный обработчик для определённого префикса. Добавляются дополнительные условия:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/admin
RewriteRule ^(.*)$ index.php [QSA,L]
запустить локальный сервер php (запуск локального сервера php)
Этот код пропускает запросы, начинающиеся с /admin, чтобы, например, отдельный admin.php мог обрабатывать их (нужно отдельное правило).
Ошибка: Если забыть правило для /admin, запросы упадут в 404. Добавляется правило для исключённых путей.
Как настроить перенаправление на index.php с учётом протокола (HTTP/HTTPS)?
Принудительное использование HTTPS перед перенаправлением:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Php non thread safe (php non-thread-safe (не потокобезопасная версия))
Первый блок перенаправляет HTTP на HTTPS, затем применяется основное правило.
Проблема: Если HTTPS настроен некорректно, возникает бесконечное перенаправление. Проверяется установка сертификата и настройка виртуального хоста для порта 443.
Как использовать несколько файлов front-controller (например, api.php для API и index.php для веба)?
Разветвление правил по префиксу:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/(.*)$ api.php?route=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Все запросы, начинающиеся с /api/, направляются в api.php, остальные - в index.php.
Ошибка: Порядок правил важен: сначала более специфичные, потом общие. Если поменять местами, api.php не срабатывает, так как сначала срабатывает общее правило.
Расширенные примеры настройки mod_rewrite
Пример 1. Отладка правил с помощью временного RewriteRule, добавляющего GET-параметр.
RewriteEngine On
# Временно: все запросы перенаправляются с параметром debug=1
RewriteRule ^(.*)$ index.php?url=$1&debug=1 [QSA,L]
Результат: После включения этого правила каждый запрос (например, /products/123) будет передан в index.php как index.php?url=products/123&debug=1. После отладки правило удаляется.
Пример 2. Перенаправление запросов в зависимости от HTTP-метода (например, только POST для API).
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_METHOD} ^(POST|PUT)$
RewriteRule ^api/(.*)$ api.php?route=$1 [QSA,L]
# Для остальных методов - стандартное правило
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Результат: POST-запрос к /api/users попадает в api.php?route=users, а GET-запрос к /page/about - в index.php.
Пример 3. Использование RewriteRule с флагом PT (passthrough) для внутреннего перенаправления через другие модули (например, PHP-FPM через модуль proxy).
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [PT,L]
Результат: Флаг PT позволяет передать изменённый URL дальше по цепочке обработки (например, для дальнейшей обработки через ProxyPassMatch без потери пути).
Пример 4. Перенаправление на index.php с проверкой IP-адреса для разделения окружений разработки и продакшена.
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^192\.168\.
RewriteRule ^(.*)$ dev-index.php?route=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Результат: Запросы из локальной сети (192.168.x.x) обрабатываются dev-index.php, остальные - основным index.php.
Пример 5. Использование RewriteRule с модификатором NE (noescape) для сохранения специальных символов в URL.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,NE,L]
Результат: Символы, такие как %2F, %3F, остаются в исходном виде в параметре url, что полезно для передачи закодированных значений.
Пример 6. Комбинирование с правилом удаления index.php из URL (обратный случай, когда index.php уже есть в запросе).
RewriteEngine On
# Удаление index.php из URL и перенаправление с кодом 301
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\?url=([^&\ ]+)
RewriteRule ^index\.php$ /%1? [R=301,L]
# Стандартное перенаправление на index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Результат: Запрос /index.php?url=home перенаправляется на /home с кодом 301, а затем снова направляется в index.php уже без видимого index.php.