Включаем Apache Mod Rewrite

06.03.2022, 00:06

Когда пользователь в браузере вводит определённый URL и нажимает Enter, веб-сервер, получивший этот запрос, пытается раздобыть файл на сервере по пути, указанному в URL. Если по пути ничего не указано, открывается индексный файл, например index.html или index.php. в том случае, когда ничего не обнаружено, происходит возврат ошибки 404. Мы бы не имели красивых и удобных для восприятия URL, если бы все работало не так как сейчас. Эти адреса используются на многих сайтах. Модуль apache mod rewrite предназначен для решения этой задачи В данной инструкции рассмотрим как его включить.

Включаем мод

Если бы всё работало как описано, то при открытии любой ссылки этого сайта в корневой директории должен был бы существовать файл или скрипт с одноименным именем из адресной строки. Но это не так. При запросе этой URL веб-сервер предпринимает попытки найти такой файл, но если его не находит, вместо возвращения ошибки 404 передается управление модулю mod_rewrite, который для всех таких URL выполняет скрипт index.php передавая уже ему строку запроса после домена. После чего PHP на основе этих данных находит и возвращает необходимую пользователю страницу.

Для включения mod rewrite выполните простую команду:

$ sudo a2enmod rewrite

После перезапустить веб-сервер:

$ sudo systemctl restart apache

На что модуль включён на уровне веб-сервера Apache не значит, что он будет работать для веб-сайта. Для этого его надо настроить в файле .htaccess, указать на какому скрипту передавать запросы к несуществующим страницам. Для того чтобы файл .htaccess работал, в секцию Directory виртуального хоста надо добавить директиву AllowOwerride: All

В качестве примера:

Далее, например, в WordPress надо добавить такие строки в файл .htaccess:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Весь код помещен в директиву IfModule, позволяющую выполнять код внутри неё только когда модуль mod_rewrite включён, иначе эти строки просто игнорируются. Директива RewriteEngine On включает модуль для текущего каталога. Затем при помощи RewriteBase указывается, что необходимо передавать скрипту всю строку после домена. Дальше идут правила RwriteRule с условиями для них RewriteCond, выполняющееся строго последовательно..

Одно из правил RewriteRule ^index\.php$ - [L] сообщает, что в том случае, если в URL содержится index.php, следует переписать URL на /. В этом регулярном выражении указана вся строка, а точка экранирована обратным слешем. Флаг [L] означает то, что URL совпала с этим правилом, то следующие правила проверять не стоит. После выполнения этого правила URL перепишется и веб-сервер будет считать, что получил запрос /, анализ правил начнётся сначала и на этот раз совпадёт с последним правилом.

Условия RewriteCond распространяются на все последующие правила. То есть мы имеем RewriteCond %{REQUEST_FILENAME} !-f и RewriteCond %{REQUEST_FILENAME} !-d позволяют последнему правилу выполнится только если URL - это не файл и не папка. Заключительное правило перенаправляет всё на скрипт ./index.php.

Если вы не можете разобраться в настройках mod_rewrite стоит посмотреть что происходит внутри веб-сервера во время ваших редиректов. Для этого в конфигурацию виртуального хоста сайта, надо добавить такую строчку.

Например:

$ sudo vi /etc/apache2/sites-available/001-texts.conf

LogLevel warn rewrite:trace4

Затем в лог файле, который приведен в директиве ErrorLog, вы увидите все попытки веб-сервера преобразовать URL по вашим правилам и сможете понять что вы делаете не так. В этой инструкции мы рассмотрели как включить mod rewrite Apache, а также как всё это работает и как искать ошибки.