Добро пожаловать в школу магии и волшебства
В virtualHost указываем для дебага всех действий с реврайтами:
RewriteLog "/var/www/rewrite.log" RewriteLogLevel 9
Если сам mod_rewrite не включен, то включаем:
/etc/apache2# cat mods-available/rewrite.load LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so cp mods-available/rewrite.load mods-enabled/ в VirtualHost должно быть: AllowOverride all
site.ru/?text=Hello
TO
site.ru/Hello
Создаем тестовый php файл:
<?php echo $_GET["text"]; ?>
Путь запроса site.ru/?text=Hello
Создаем правила в .htaccess:
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php\?text=$1 [L]
И можем использоваться site.ru/Hello
(3) [perdir /var/www/] strip per-dir prefix: /var/www/Hello -> Hello #Сначался удалился префикс дирикторий и получили название файла к которому обращаемся (3) [perdir /var/www/] applying pattern '^(.*)$' to uri 'Hello' #Прошла проверка, что в RewriteRule, в первом значение разрешается использоваться url Hello (4) [perdir /var/www/] RewriteCond: input='/var/www/Hello' pattern='!-f' => matched #Проверка на отсутствие файла - пройдена (4) [perdir /var/www/] RewriteCond: input='/var/www/Hello' pattern='!-d' => matched #Проверка на отсутствие директории - пройдена (2) [perdir /var/www/] rewrite 'Hello' -> '/index.php?text=Hello' #Применяется правило реврайта (3) split uri=/index.php?text=Hello -> uri=/index.php, args=text=Hello #Парсится строка -> определяется файл и GET аргументы TODO:Кто просил? (1) [perdir /var/www/] internal redirect with /index.php [INTERNAL REDIRECT] #TODO: Указывается внутренний редирект. Почему? Из за парсинга? Или из за нового обращения в RewriteRule? (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.php -> index.php (3) [perdir /var/www/] applying pattern '^(.*)$' to uri 'index.php' (4) [perdir /var/www/] RewriteCond: input='/var/www/index.php' pattern='!-f' => not-matched #Парсится на придмет присутствия index.php, находит и более не редиректит. Если бы этого небыло, получили бы ошибку. (1) [perdir /var/www/] pass through /var/www/index.php
TO http://192.168.0.102/2013/07/hello-world/
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # не упустить символ "-" который обозначает преобразование к корню сайта RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]
В админ панели указано:
Month and name http://192.168.0.102/2013/07/sample-post/
Следовательно, все ссылки на сайте такого вида site.ru/2013/07/hello-world/
Запрос: http://192.168.0.102/2013/07/hello-world/
(3) [perdir /var/www/] add path info postfix: /var/www/2013 -> /var/www/2013/07/hello-world/ #TODO: И зачем это действие? (3) [perdir /var/www/] strip per-dir prefix: /var/www/2013/07/hello-world/ -> 2013/07/hello-world/ # убераем базу, оставляя только запрос (3) [perdir /var/www/] applying pattern '^index\.php$' to uri '2013/07/hello-world/' (3) [perdir /var/www/] add path info postfix: /var/www/2013 -> /var/www/2013/07/hello-world/ (3) [perdir /var/www/] strip per-dir prefix: /var/www/2013/07/hello-world/ -> 2013/07/hello-world/ (3) [perdir /var/www/] applying pattern '.' to uri '2013/07/hello-world/' (4) [perdir /var/www/] RewriteCond: input='/var/www/2013' pattern='!-f' => matched (4) [perdir /var/www/] RewriteCond: input='/var/www/2013' pattern='!-d' => matched (2) [perdir /var/www/] rewrite '2013/07/hello-world/' -> '/index.php' (2) [perdir /var/www/] trying to replace prefix /var/www/ with / (1) [perdir /var/www/] internal redirect with /index.php [INTERNAL REDIRECT] (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.php -> index.php (3) [perdir /var/www/] applying pattern '^index\.php$' to uri 'index.php' (1) [perdir /var/www/] pass through /var/www/index.php
Запрос http://192.168.0.102/index.php
(3) [perdir /var/www/] strip per-dir prefix: /var/www/ -> (3) [perdir /var/www/] applying pattern '^index\.php$' to uri '' (3) [perdir /var/www/] strip per-dir prefix: /var/www/ -> (3) [perdir /var/www/] applying pattern '.' to uri '' (1) [perdir /var/www/] pass through /var/www/ # В запросе выше, после прохождения правил создался запрос на корень сайта, а приоритетно идет index.html которого нет в корне сайта (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.html -> index.html (3) [perdir /var/www/] applying pattern '^index\.php$' to uri 'index.html' (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.html -> index.html (3) [perdir /var/www/] applying pattern '.' to uri 'index.html' (4) [perdir /var/www/] RewriteCond: input='/var/www/index.html' pattern='!-f' => matched (4) [perdir /var/www/] RewriteCond: input='/var/www/index.html' pattern='!-d' => matched (2) [perdir /var/www/] rewrite 'index.html' -> '/index.php' (2) [perdir /var/www/] trying to replace prefix /var/www/ with / (1) [perdir /var/www/] internal redirect with /index.php [INTERNAL REDIRECT] (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.cgi -> index.cgi (3) [perdir /var/www/] applying pattern '^index\.php$' to uri 'index.cgi' (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.cgi -> index.cgi (3) [perdir /var/www/] applying pattern '.' to uri 'index.cgi' (4) [perdir /var/www/] RewriteCond: input='/var/www/index.cgi' pattern='!-f' => matched (4) [perdir /var/www/] RewriteCond: input='/var/www/index.cgi' pattern='!-d' => matched (2) [perdir /var/www/] rewrite 'index.cgi' -> '/index.php' (2) [perdir /var/www/] trying to replace prefix /var/www/ with / (1) [perdir /var/www/] internal redirect with /index.php [INTERNAL REDIRECT] (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.pl -> index.pl (3) [perdir /var/www/] applying pattern '^index\.php$' to uri 'index.pl' (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.pl -> index.pl (3) [perdir /var/www/] applying pattern '.' to uri 'index.pl' (4) [perdir /var/www/] RewriteCond: input='/var/www/index.pl' pattern='!-f' => matched (4) [perdir /var/www/] RewriteCond: input='/var/www/index.pl' pattern='!-d' => matched (2) [perdir /var/www/] rewrite 'index.pl' -> '/index.php' (2) [perdir /var/www/] trying to replace prefix /var/www/ with / (1) [perdir /var/www/] internal redirect with /index.php [INTERNAL REDIRECT] (3) [perdir /var/www/] strip per-dir prefix: /var/www/index.php -> index.php (3) [perdir /var/www/] applying pattern '^index\.php$' to uri 'index.php' (1) [perdir /var/www/] pass through /var/www/index.php
RewriteEngine on|off Включаем|Выключаем mod_rewrite
Включаем логирование
RewriteLog "/usr/local/var/apache/logs/rewrite.log" # Указываем полный путь. RewriteLog "logs/rewrite.log" # Указывыем относительный путь.
Уровень журналирования. Доступно от 0 до 9
RewriteLogLevel 3
устанавливает конкретный, базовый URL для преобразований в контексте каталога. Пример:
RewriteEngine On RewriteBase /xyz RewriteRule ^oldstuff\.html$ newstuff.html Запрос на /xyz/oldstuff.html приводит к /abc/def/newstuff.html
Проверка условия (соответствие правой и левой части) после которого идет действия (Грубо говоря “IF”)
Поддерживает большое количество переменный и т.д.
Синтаксис:
RewriteCond [String] [String2] [NC,OR]
OR → Проверяет несколько правил для одного действия и если одно из них верно, выполняет действие.
NC → Не чувствительно к регистру
Примеры:
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.* RewriteRule ^/$ /homepage.max.html [L]
RewriteCond %{HTTP_USER_AGENT} ^Lynx.* RewriteRule ^/$ /homepage.min.html [L]
RewriteRule ^/$ /homepage.std.html [L]
Завершить обработку mod_rewrite
Цикл хоть и прекращается, но в оригинали описана опасность повторного входа в цикл. Подробнее в оригинале
Для полного завершения всех циклов, можно использовать [END]
Не обращать внимание на регистр.
Запрещаем преобразование спец символов в hexcode
RewriteRule ^/anchor/(.+) /bigpage.html#$1 [NE,R]
/anchor/xyz будет преобразовано в /bigpage.html#xyz
без [NE] это будет преобразовано в /bigpage.html%23xyz
Запрещаем подзапросы.
Подзапросом являютяся:
Что не является подзапросом:
Позволяет работать другим URL обработчиками. К примеру, для возможности работы mod_alias после mod_rewrite
используется QUERY_STRING
RewriteCond %{REQUEST_URI} ^/test.php [NC] RewriteCond %{QUERY_STRING} ^u=(.*)&id=(.*)&img=(.*) RewriteRule (.*) http://app.foo.com/%2-%1-%3.test? [R=301,L] Now it give me that link : http://app.foo.com/12345-s1-12.test?u=s1&id=12345&img=12 Instead of : http://app.foo.com/12345-s1-12.test
http://habrahabr.ru/post/75885/
RewriteCond %{ENV:REDIRECT_FINISH} !^$ // Проверка переменной RewriteRule ^ - [L] // Если переменная установлена, то изменить исходный на исходных url, тем самым завершив их обработку. AddDefaultCharset utf-8 RewriteCond %{QUERY_STRING} ^p=(.*)$ RewriteRule .* - [R=404,L,E=FINISH:1] //Тут E=FINISH:1 установит переменную в следствии которой все завершится.
Только одна интерация для всего
RewriteCond %{ENV:REDIRECT_STATUS} !^$ RewriteRule .* — [L]
RewriteRule .* - [E=AWESOME_VAR:%{HTTP_USER_AGENT},L]
RewriteRule .* - [E=AWESOME_VAR:True,L]
RewriteRule ^dir/file$ index.php [R=301]
RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.mshopping\.ru [NC] RewriteRule ^(.*)$ http://mshopping.ru/$1 [L,R=301]
RewriteEngine On RewriteCond %{HTTP_HOST} ^volgo-rielt.ru RewriteRule (.*) http://www.volgo-rielt.ru/$1 [R=301,L]
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://site.ru/$1 [L,R=301]
Альтернатива: (не всегда работает)
RewriteEngine On RewriteCond %{HTTP:SSL} !=on RewriteRule ^(.*)$ https://www.site.ru/$1 [R=301]
RewriteBase / RewriteCond /home/u113509/conovaloffru/rewrite/%{REQUEST_FILENAME} !-f RewriteRule ^(.+) http://ya.ru/
RewriteEngine On RewriteCond %{HTTP_HOST} ^test\.site\.ru [NC] RewriteCond %{REQUEST_URI} !^/test/(.*)?$ [NC] RewriteRule ^(.*)$ /test/$1 [L]
RewriteEngine On RewriteBase / RewriteRule index.html / [R=301,L]
Просят сделать с http://site.ru/ скрытый редирект на http://site.ru/index.php?post_type=tribe_events [L]
RewriteEngine On RewriteCond %{REQUEST_URI} ^/$ #Если нет обращений к файлам RewriteCond %{QUERY_STRING} ^$ #Если не передаются GET параметры RewriteRule ^(.*)$ /index.php?post_type=tribe_events [L]
RewriteRule ^(.*)$ - [E=PROTOCOL:http] RewriteCond %{HTTPS} ^on$ [NC] RewriteRule ^(.*)$ - [E=PROTOCOL:https]
RewriteCond %{HTTP_COOKIE} !login=mylogin [NC] #Если такой куки нет, то forbiden RewriteRule .* - [F]
RewriteEngine On RewriteCond %{HTTP_USER_AGENT} "Mozilla/4\.0 \(Windows 98; US\) Opera 10\.00 \[en\]" RewriteRule .* - [F,L]
RewriteRule ^pmma - [L] #В самом начале .htaccess
Пример использования
tester.site.ru -> site.ru/users/tester tester.site.ru/somedir/ -> site.ru/users/tester/somedir/ paul.site.ru -> site.ru/users/paul
Пример реализации
RewriteCond %{ENV:REDIRECT_STATUS} !^$ RewriteRule .* - [L] RewriteCond %{HTTP_HOST} !www\.site\.ru$ [NC] RewriteCond %{HTTP_HOST} ^(www.)?([a-z0-9-]+).site\.ru [NC] RewriteRule (.*) /users/%2/$1/ [L]
Discussion
Пример бесконечного редиректа
http://conovaloff.com/redirect_loop_example