Правила RewriteRule для перенаправления на index.php в конфигурации сервера

Раздел: Администрирование серверов -> Серверная конфигурация

Основные подходы к использованию RewriteRule для index.php

Как обеспечить единую точку входа через index.php для всех запросов, кроме реальных файлов и папок?

Наиболее надёжное и универсальное решение - правило с проверкой %{REQUEST_FILENAME} в RewriteCond. Оно перенаправляет все запросы на index.php, если запрашиваемый файл или директория физически не существуют на сервере. Это предотвращает лишние перенаправления для статических ресурсов (css, js, изображения) и снижает нагрузку.


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

Rewriterule index php l (правила rewriterule для index.php)

Пояснение:

  • RewriteEngine On - включает модуль mod_rewrite.
  • RewriteCond %{REQUEST_FILENAME} !-f - условие: запрашиваемый путь не является существующим файлом.
  • RewriteCond %{REQUEST_FILENAME} !-d - условие: запрашиваемый путь не является существующей директорией.
  • RewriteRule ^(.*)$ index.php?/$1 [QSA,L] - перенаправляет весь путь (захваченный группой (.*)) в качестве параметра /$1 к index.php. Флаги QSA (Query String Append) добавляет существующую строку запроса, L (Last) останавливает обработку правил.

Цель использования: типичная реализация фронт-контроллера в MVC-фреймворках (Laravel, Symfony, CodeIgniter).

Типичные ошибки:

  • Бесконечный цикл перенаправления (500 Internal Server Error). Возникает, если не проверять существование файлов или когда RewriteRule не содержит условие исключения index.php. Решение: добавить проверку !-f и !-d, либо явно запретить перенаправление для index.php: RewriteCond %{REQUEST_URI} !^/index\.php$.
  • Параметры запроса не передаются. Забытый флаг QSA приведёт к потере строки запроса. Исправление: всегда добавлять QSA.
  • Правила не работают. Убедитесь, что файл .htaccess доступен для чтения, а модуль mod_rewrite включен (sudo a2enmod rewrite в Debian/Ubuntu).

Как перенаправить все запросы, включая существующие файлы, на index.php?

Иногда требуется жёсткое перенаправление без проверки на существование файла. Такой подход используется, если все ресурсы должны обслуживаться через скрипт (например, кэширование через PHP).


RewriteEngine On
RewriteRule ^(.*)$ index.php?/$1 [QSA,L]
  

Проблемы: Статические файлы (изображения, CSS) будут обрабатываться PHP, что замедляет работу. Решение: исключить конкретные расширения через RewriteCond.

Как перенаправить только запросы к определённой поддиректории?

Если приложение расположено не в корне, а в подпапке /app/, правила нужно скорректировать.


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

RewriteBase задаёт базовый путь для относительных RewriteRule. Если его не указать, правило может работать некорректно при нахождении в поддиректории.

Ошибка: 404 при запросе к /app/anything. Необходимо убедиться, что .htaccess лежит внутри /app/ или используется RewriteBase.

Как использовать RewriteRule с параметрами маршрутизации (например, /controller/action)?

Часто требуется передать путь как строку запроса, а PHP-фреймворк сам разбирает его.


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

Теперь $_GET['route'] будет содержать, например, home/about. Это полезно, когда фреймворк ожидает определённый параметр.

Путаница с index.php в корне. Если сам index.php запрашивается как /index.php, условие !-f пропустит его. Однако если нужно всё равно перенаправлять, можно добавить RewriteCond %{REQUEST_URI} !^/index\.php$.

Как обрабатывать ошибку 404 через index.php?

Можно перенаправлять несуществующие страницы на index.php с кодом ошибки.


RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php [L,R=404]
  

Флаг R=404 вызывает внешнее перенаправление (редирект) с кодом 404. Однако это не истинный 404, а редирект. Лучше использовать ErrorDocument.

Как комбинировать RewriteRule с проверкой HTTP_HOST для поддоменов?

Если для каждого поддомена нужна своя точка входа.


RewriteEngine On
RewriteCond %{HTTP_HOST} ^api\.example\.com$ [NC]
RewriteRule ^(.*)$ api/index.php?/$1 [QSA,L]
  

Условие %{HTTP_HOST} проверяет домен. Флаг NC игнорирует регистр.


Каждый из вариантов имеет свою область применения: от простого фронт-контроллера до сложной маршрутизации по поддоменам. Выбор зависит от архитектуры приложения.

Расширенные примеры использования RewriteRule для index.php

Ниже приведены подробные примеры с кодом и ожидаемым результатом.

Пример 1: Перенаправление с параметрами строки запроса

Задача: все запросы вида /users?id=5 должны попадать в index.php как index.php?/users&id=5.

Пример

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1&%{QUERY_STRING} [QSA,L]

Результат: при запросе /users?id=5 PHP получит $_GET['route'] = 'users' и $_GET['id'] = 5. Без QSA флаг не нужен, так как явно передаётся %{QUERY_STRING}. Но лучше всегда использовать QSA.

Пример 2: Исключение нескольких расширений файлов

Хочется перенаправлять всё, кроме .css, .js, .png, .jpg.

Пример

RewriteEngine On
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpg)$ [NC]
RewriteRule ^(.*)$ index.php?/$1 [QSA,L]

Результат: запрос к /style.css вернёт файл напрямую (если существует), а /about будет перенаправлен. Обратите внимание: это не проверяет существование файла, только расширение. Можно комбинировать с !-f.

Пример 3: Использование RewriteRule внутри VirtualHost

Для выделенного сервера часто настраивают правила в httpd.conf.

Пример

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html
    <Directory /var/www/html>
        AllowOverride All
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.php?/$1 [QSA,L]
    </Directory>
</VirtualHost>

Результат: правила применяются ко всем запросам к данному виртуальному хосту. Преимущество - централизованное управление, не нужно хранить .htaccess.

Пример 4: Комбинирование с защитой от индексации

Одновременно запретить просмотр содержимого директорий.

Пример

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

Результат: при попытке зайти в /uploads/ без конкретного файла будет вызван index.php, а не список файлов.

Пример 5: Перенаправление с помощью RewriteMap (требуется mod_rewrite advanced)

Если нужно динамически преобразовывать URL по словарю, можно использовать RewriteMap (настраивается в httpd.conf).

Сначала создаётся текстовый файл map.txt:

Пример

old-page  index.php?page=old
about-us  index.php?page=about

Затем в конфигурации:

Пример

RewriteMap urlmap txt:/path/to/map.txt
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ${urlmap:$1|index.php?/$1} [QSA,L]

Результат: если запрашивается /old-page, происходит подстановка в index.php?page=old. Если ключа нет, используется шаблон по умолчанию index.php?/$1.

Пример 6: Проверка правил с помощью curl

Для отладки можно использовать curl:

Пример

curl -I http://localhost/test

Результат: ожидается ответ 200 OK (если index.php существует) или 301/302 при внешнем редиректе. Команда -L позволяет следовать редиректам.

Использование нестандартных решений, таких как RewriteMap, оправдано при большом количестве статических перенаправлений или интеграции с CMS.

Правила RewriteRule для index.php - comments

En
Rewriterule index php l (php)