.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_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), доступ запретить, больше никаких правил преобразования не применять»
- $0 полностью включает результат регулярного выражения [в нашем случае оно одно .*]
- $1 включает результат регулярного выражения в первых скобках
- $N (1<=N<=9), по очереди включает результат выражения в каждой из N скобок
RewriteRule ^/([a-z]+)/(.*)$ /home?page=$1&id=$2
# /album/123 → /home?page=album&id=123 ($N=1, $N=2)
Итого
.htaccess является мощным инструментом локальной настройки Apache для отдельных директорий вашего проекта. С его помощью можно настроить редиректы на сайте, создать красивые URL, запретить доступ к системным каталогам. Про создание красивых адресов для страниц сайта доступно написано в этой статье.