Что вам нужно знать об .htaccess

6 min read

.htaccess — это дополнительный конфигурационный файл Apache, который позволяет настраивать работу веб-сервера для каждой отдельной директории, не влияя на глобальные настройки Apache. Локальная аналогия httpd.conf. Обычно он отвечает за редиректы и управление доступом к директориям.

Название начинается с точки. Можно сказать, это файл без названия с расширением htaccess. 

Настройки .htaccess действуют на каталог, в котором он расположен, и на все дочерние каталоги. Создайте файл и поместите в нужную вам директорию. Например, в корень проекта.

Теперь нужно его наполнить. Посмотрим, что вообще умеет .htaccess, но для начала изучим пример простейшего редиректа.

mod_rewrite и редиректы

Убедитесь, что в конфигурационном файле Apache httpd.conf активирован mod_rewrite. То есть, раскомментирована соответствующая строка:

LoadModule rewrite_module modules/mod_rewrite.so

Или, если не хотите открывать в текстовом редакторе файл, можно воспользоваться командой в терминале:

sudo a2enmod rewrite

mod_rewrite — это модуль Apache, предназначенный для преобразования URL-ов. Рассмотрим на примере, как он работает. Допустим, пользователь вводит следующий адрес:

http://www.example.com/page.html

C помощью mod_rewrite можно отправить содержание с другого URL, например такого:

http://www.example.com/public/src/view/page.html

Зачем это нам? Легко догадаться, что писать полный путь до страницы долго и просто неудобно. Посетителям сайта не нужно думать о внутренней структуре сайта — им важно максимально быстро попасть на искомую страницу.

В адресной строке пользователь будет всё также видеть введенное им:

http://www.example.com/page.html

Это пример самого простого редиректа.

Сразу к практике

Разберем конфигурационный файл, используемый в одном из наших проектов. Так мы будем понимать, какую строчку править в случае возникновения проблем.

php_value short_open_tag 1 php_value upload_max_filesize 10M php_value post_max_size 10M RewriteEngine On RewriteBase / RewriteRule ^(application|modules|system) - [F,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule .* index.php/$0 [PT,L]

Общий синтаксис директив

php_value/php_flag имя_директивы_php flag/value

Директива short_open_tag разрешает использование короткого синтаксиса для оформления PHP-кода:

php_value short_open_tag 1

upload_max_filesize определяет максимальный размер загружаемого файла.

php_value upload_max_filesize 10M

А post_max_size устанавливает максимально допустимый размер данных, отправляемых методом POST. 

php_value post_max_size 10M

RewriteEngine

Включает/выключает механизм mod_rewrite.

RewriteEngine On

RewriteRule

RewriteRule просто преобразовывает строку в соответствии с регулярными выражениями. 

Синтаксис: RewriteRule regular_expression

# На входе RewriteRule "index.php" RewriteRule ^index.php main.php [R] # На выходе: "index.php" -> "main.php"

Мы преобразовали index.php в main.php и выполнили редирект.

Важно: RewriteRule обычно принимает два аргумента: что нужно заменить и на что нужно заменить. Если нам не нужно выполнять замену то можно записать в виде:

RewriteRule *regular expression here* -

Символ «-» означает «не преобразовывать»

RewriteBase

После всех RewriteRule, в силу вступает RewriteBase. Если получившийся после преобразований запрос является относительным и отличается от исходного, RewriteBase восстановит его, сделав абсолютным. RewriteBase просто допишет себя к запросу слева. Потому что значение RewriteBase — путь от корня сайта до .htaccess. В нашем случае .htaccess лежит прямо в корне, поэтому:

RewriteBase /

Синтаксис:  RewriteBase URL-path-from-.htaccess-file-to-site-root

Например:

# .htaccess находится в /dir/ # Путь от корня сайта до .htaccess /dir/ RewriteBase /dir/ # Запрос http://example.com/dir/logo.gif # На вход RewriteRule попадает "logo.gif" RewriteRule ^logo.gif$ logo-orange.gif # После RewriteRule: "logo.gif" -> "logo-orange.gif" # После RewriteBase: "logo-orange.gif" -> "/dir/logo-orange.gif"

Regular expressions

Регулярные выражения, которые вам могут встретиться в .htaccess.

Символ Значение Пример
. Один любой символ c.t это cat, cot, cut, и т. д.
+ Один или несколько одинаковых символов a+ это a, aa, aaa, и т. д.
* Ноль или несколько одинаковых символов a* работает также как и a+ но в случае a* условию удовлетворит и пустая строка
? Совпадение опционально colou?r подойдет как color, так и colour.
^ Символ, с которого начинается строка ^a соответствует строка, которая начинается с a
$ Символ, которым заканчивается строка a$ соответствует строка, которая заканчивается a.
( ) Находит и запоминает соответствие группы символов.

Также может быть использовано для Back-Reference (смотри пример)
(ab)+ удовлетворит ababab

Back-Reference example:

RewriteRule    ^/([a-z]+)/(.*)$     /home?page=$1&id=$2

/album/123   →   /home?page=album&id=123
[ ] Один из возможных символов c[uoa]t подойдет cut, cot или cat.

Больше regular expressions

Флаги

Синтаксис: RewriteRule regular_expression [флаг1,флаг2,флаг3]

Флаг Описание
[F] Forbidden — возвращает ошибку 403 Forbidden (запрещено).
[L] Last — остановить процесс преобразования на этом месте и не применять больше никаких правил преобразований.
[QSA] Query String Append — этот флаг указывает механизму преобразований на добавление, а не замену, строки запроса из URL к существующей, в строке подстановки.
[PT] PassThrough — останавливает процесс преобразования и передает полученную новую ссылку дальше по цепочке.
[R] Redirect — останавливает процесс преобразования и возвращает результат браузеру клиента как редирект на новую страницу.
[S] Skip — пропускает следующее правило, если текущее правило сработало. Можно указать количество последующих игнорируемых правил [S=2].

Больше флагов здесь

Итак, следующая строка в нашем конфигурационном файле 

RewriteRule ^(application|modules|system) - [F,L]

переводится как:

«Строку, начинающуюся с application или modules или system не преобразовывать, доступ запретить»

А последние три строки можно интерпретировать как

RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule .* index.php/$0 [PT,L]

«Если запрос не является файлом (!-f) или директорией (!-d), то любое количество любых символов (.*) редиректить по адресу index.php/ после слэша идет полностью результат.* (условие $0), доступ запретить, больше никаких правил преобразования не применять»

RewriteRule ^/([a-z]+)/(.*)$ /home?page=$1&id=$2 # /album/123 → /home?page=album&id=123 ($N=1, $N=2)

Итого

.htaccess является мощным инструментом локальной настройки Apache для отдельных директорий вашего проекта. С его помощью можно настроить редиректы на сайте, создать красивые URL, запретить доступ к системным каталогам. Про создание красивых адресов для страниц сайта доступно написано в этой статье.

Полезные ссылки