Включаем Apache Mod Rewrite

06.03.2022, 00:06

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

Включаем мод

Если бы всё работало как описано, то при открытии любой ссылки этого сайта в корневой директории должен был бы существовать файл или скрипт с одноименным именем из адресной строки. Но это не так. При запросе этой 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, а также как всё это работает и как искать ошибки.