1. Главная
  2. Статьи
  3. Вопрос-Ответ
  4. Новости
  5. Форум
  6. Вики
Вход   Регистрация

Биржа комментариев

СМС рассылки

Партнерские программы

Бесплатное продвижение сайтов

VPS хостинг

Кабель оптом

Качественный контент

Офисная мебель Проспект

Htaccess. правило RewriteRule: просто, понятно, с примерами и объяснениями

Htaccess. правило RewriteRule: просто, понятно, с примерами и объяснениями
Мы, как веб программисты, часто сталкиваемся с файлом .htaccess и в частности с его модулем MOD_REWRITE и синтаксисом RewriteRule. И по началу трудно разобраться и понять принцип его работы, правила по которым он работает и механизм преобразования динамических ссылок в статические и наоборот. В этой статье я постараюсь максимально просто, максимально доступно, с объяснениями и примерами растолковать так, что бы у Вас не осталось каких либо вопросов.
За преобразование динамических ссылок в статические отвечает модуль mod_rewrite с синтаксисом RewriteRule, принцип работы и правило преобразования, которого я и буду объяснять.
Для примера возьмем динамическую ссылку, которую нам надо преобразовать:
site.ru/catalog/index.php?auto=BMW&model=X5&state=NEW&page=5
В этой ссылке мы включили максимально возможное количество передаваемых параметров на нашем сайте.
То есть, в каталоге выбрали авто BMW, модель X5, состояние – новое, страница 5.

В файле .htaccess, который мы разместим в корневой папке каталога catalog/ записываем (файл .htaccess действует только на каталог где он расположен и на его дочерние каталоги):
RewriteEngine on (включаем процесс преобразования ссылок)
RewriteRule ^([A-Za-z0-9-]+)/([^/]+)/(.*)/([0-9]+).html$ index.php?auto=$1&model=$2&state=$3&page=$4 [L]

Давайте подробней разберемся, что здесь написано:
^ Начало строки;
([A-Za-z0-9-]+) Скобки создают переменную, которую подставляем в динамическую ссылку $1. То есть
Переменная $1 = ([A-Za-z0-9-]+)
Переменная $2 = ([^/]+)
Переменная $3 = (.*)
Переменная $4 = ([0-9]+)
В скобках [A-Za-z0-9-] класс допустимых символов. В данном случае допустимыми символами являются A B C D…Z a b c…z 0 1 2 3…9 – Если мы хотим добавить символы, например, ? ; : то получим следующее [A-Za-z0-9-?;:] то есть просто дописали их.
+ означает что мы добавляем еще один символ для подстановки.
Выражение ([^/]+) означает любой символ кроме(^ означает кроме) слеша назад. + означает добавить еще символ.
Выражение (.*) Точка означает любой единичный символ, * означает как и плюс – добавить еще символ.
Выражение ([0-9]+) думаю, тут понятно.
.html – означает что статическая строка оканчивается на .html
Слеши / означают слеши в статической ссылке.

Следует отметить, что данный мод преобразовывает ссылки не с динамической в статические ссылки а НАОБОРОТ! То есть, на сайте мы пишем статические ссылки, а мод рерайт преобразовывает статическую ссылку с сайта на динамическую. То есть представленную выше ссылку мы должны записать на сайте в виде статической:
site.ru/catalog/ BMW/X5/NEW/5.html
А модуль RewriteRule эту ссылку преобразовывает в динамическую по правилу записанному в .htaccess и выдает сайту:

На выходе получается ссылка: site.ru/catalog/index.php?auto=BMW&model=X5&state=NEW&page=5
Которая и понятно нашим php скриптам и страницам сайта.
Так же к выше изложенному правилу преобразования следует добавить правила для ссылки без переменной номера страницы page, а так же возможных вариантов с отсутствием переменных.
RewriteRule ^([A-Za-z0-9-]+)/([^/]+)/(.*).html$ index.php?auto=$1&model=$2&state=$3 [L]
RewriteRule ^([A-Za-z0-9-]+)/([^/]+).html$ index.php?auto=$1&model=$2 [L]
RewriteRule ^([A-Za-z0-9-]+).html$ index.php?auto=$1 [L]
Ниже приведу возможные обозначения и символы используемые в модуле MOD_REWRITE:
. Любой одиночный символ. Если нам в круглых скобках нужна именно точка а не любой одиночный символ ее нужно экранировать . Обратный слеш экранирует какой либо символ [ ] ( ) ? > и т.п. и передает его истинное значение.
[chars] Класс симвлолв: Один из символов например [A-Za-z0-9] {2,5}- фигурные скобки означают диапозон количества символов, в данном случае допускается от 2 до 5 символов.
[^chars] Класс симвлолв: Ни один из символов. [^fg57] – символы f g 5 7 запрещены.
text1|text2 Альтернатива: text1 или text2. например [a|b|c] означает или a или b или c
Кванторы (символы для обозначения количественных отношений):
? 0 или 1 из предшествующего текста Означает либо есть символ или какое-то значение символов или их может не быть.
* 0 или N из предшествующего текста (N > 0)
+ 1 или N из предшествующего текста (N > 1)
макрос "$1" обозначает ту часть исходного пути, которая расположена внутри первой пары скобок "RewriteRule ^(.*)....." , $2 – внутри второй пары и так далее.
Маркеры:
^ Маркер начала строки
$ Маркер конца строки

Пример RewriteRule с пояснениями:
Допустим, у нас на сайте есть статьи, которые имеют динамические страницы:
http://www.site.ru/articles?id=( id статьи)
Сделаем, чтобы ссылка на наши статьи была более красива, например:
http://www.site.ru/nazvanie-stati/ или
http://www.site.ru/nazvanie-stati.html
Для этого, в нашей MySQL таблице, добавляем дополнительную строку, в которой будем хранить уникальное название статьи латинскими буквами без пробелов, слешов и специальных символов, недопустимых в ссылках. Например: Moya-pervaya-statya ну и по такому принципу. Назавем строку в нашей таблице, например eng_name_stati
Динамическая ссылка теперь будет иметь вид:
http://www.site.ru/articles?eng_name_stati=(Moya-pervaya-statya и т.д.)
Главный момент, который нужно понять, файл .htaccess, как я говорил выше, не преобразует динамические ссылки в статические, а наоборот, статические преобразовывает в динамические.
Правило преобразования RewriteRule будет иметь вид:
RewriteRule ^(.*)/$ articles?eng_name_stati=$1 [L] для вида статической ссылки: http://www.site.ru/nazvanie-stati/ или
RewriteRule ^(.*).html$ articles?eng_name_stati=$1 [L] для вида http://www.site.ru/nazvanie-stati.html
Теперь, когда мы введем ссылку http://www.site.ru/nazvanie-stati.html в браузере, мы попадем на нашу статью http://www.site.ru/articles?eng_name_stati=nazvanie-stati и эти обе ссылки будут рабочими. На нашем сайте мы просто ставим ссылки в статическом виде для поисковых систем. И когда люди заходят по статической ссылке, наш файл .htaccess преобразовывает ее в динамическую, понятную для нашего сайта и видную только ему.

Дополнение:

Бывает так, нужно сначала проверить, не является ли это ссылка на существующий файл на нашем сервере, например /catalog/webmaster/index.html может оказаться существующим файлом, но если эта ссылка попадет под соответствующее правило RewriteRule она согласно этому правилу преобразуется. Поэтому, если нам сначала нужно проверить, не является ли этот файл или директория прямая, нужно пред правилом RewriteRule написать условие если:

Если нет такой папки
Если нет такого файла
Выполнить преобразование

Выглядеть это будет так:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/([^/]+).html$ index.php?catalog=$1&webmaster=$2&file=$3 [L]

Где, RewriteCond – условие если, %{REQUEST_FILENAME} – полный системный путь к запрашиваемому файлу или директории, Восклицательный знак ! означает отрицание не, -d – дериктория, -f – файл.

Теперь, прежде чем применить правило RewriteRule, будет проверено условие RewriteCond

P.S.: Так же по теме, может Вам будет интересно: Как сделать русскую URL как в Википедии

Категория статьи: Веб-программирование | Просмотров: 106992 | Добавлена: 24.10.2012

Почему Вы еще не прокомментировали?
Оставьте свой комментарий! Весь Интернет уже заждался!

Ваше Имя Муж. Жен. Как Вас величать?
Антиспам защита

– Напишите название этого сайта по-русски
(если Вы не в курсе, сайт называется "РапидАп")

Текст комментария

Вывод комментарий:

Сударь Дядька говорит:

Здрастье
Есть такая задачка
Есть несколько субоменов вида host1.domen.ru, host2.domen.ru, host3.domen.ru проассоцииованные с соответствующими виртуалхостами в апаче
Есть главная страничка, открывающаяся по www.domen.ru
Нужно, что бы при открытии www.domen.ru/host1 перебрасывало на host1.domen.ru, ну и так далее по списку..
Причем сама адресная строчка http://www.domen.ru/host1 при этом меняться не должна.

Как это сделать? Подскажите, пожалуйста, граждане судари!

Yevgeniy говорит:

Здравстыуйте.
Помогите сделать правильное преобразование статических ссылок в динамические.

Например есть страница mysite.ru/tovars.php
на ней перечень товаров. При нажатии на любой из них появляется ссылка вида:
mysite.ru/tovars.php?t=name-tovara

Нужно чтобы эта страница открывалась по запросу:
mysite.ru/tovars/name-tovara.php

Спосибо.

Руслан говорит:

Первую часть вопроса решил вот таким правилом
RewriteRule ^(.*)/component/tag/(.*)$ http://www.site.com.ua/$1/tags/$2 [R=301,L]

Но как теперь сделать что
если переходишь по ссылке которой нет по адресу
http://www.site.com.ua/tags/имя2
http://www.site.com.ua/tags/имя3
http://www.site.com.ua/tags/имя4
и т.д.
шло бы перенаправление на
http://www.site.com.ua/tags/

Руслан говорит:

Подскажите как сделать следующее правило
необходимо чтоб при обращении по адресу
www.site.com.ua/ru/component/tag/имя
переходил на www.site.com.ua/ru/component/tag/имя www.cultura.kh.ua/tags/ru/имя
вместо /ru/ есть еще /en/ /uk/

и чтоб при вводе адресов которых нет имя2 и т.д.
http://www.site.com.ua/tags/имя2
переходили все запросы на
http://www.site.com.ua/tags/

Сергей говорит:

Добрый день! Помогите, пожалуйста! Как сделать чтобы вместо САЙТ/component/content/article/9-news/24-shedule-price было САЙТ/9-news/24-shedule-price, т.е. убрать /component/content/article . Заранее спасибо!

Ответ: Ели у Вас уже есть (действующий) сайт с ссылками: САЙТ/component/content/article/9-news/24-shedule-price а Вы хотите что бы была ссылка: САЙТ/9-news/24-shedule-price то очевидно Вам нужно заменить на всем сайте ссылки САЙТ/component/content/article/9-news/24-shedule-price на САЙТ/9-news/24-shedule-price и редиректом перенаправлять со старых ссылок на соответствующие новые. То есть:
RewriteRule ^component/content/article/9-news/(.*)$ 9-news/$1 [R=301,L]

Евгений говорит:

Если знаете, подскажите пожалуйста.
Есть статик файл лежащий на фтп в виде
/flfg/ShowArticle.asp-ArticleID=84.php
Как сделать чтобы этот файл открывался по ссылке
site.ru/flfg/ShowArticle.asp?ArticleID=84

Т.е. банально нужно заменить - на ?

Если бы статик файл лежал не в папке /flfg/, то прекрасно все работало бы в таком виде:
RewriteCond %{QUERY_STRING} ^ArticleID=(.*)$
RewriteRule ^ShowArticle.asp$ ShowArticle.asp-ArticleID=%1.php [L,QSA]

Александр говорит:

Надо сделать 301 редирект

Исходный URL site.com/?id=1
Конечный URL site.com/index.php?id=1

По сути, нужно найти /? и заменить на /index.php?

Никак не могу реализовать, только на вас надежда)

Влад говорит:

Спасибо. Я сперва так и сделал без http_host, но меня стало редиректить к адресу прямо от корня веб-сервера -/home/site/public/ тра-ля-ля и так далее. Еще раз спасибо за статью. Без нее не разобрался бы.

Влад говорит:

Спасибо за статью.
Я ничего не понимаю в Rewrite. Но глядя на Ваши записи - немножко смог что-то написать.
Посмотрите, пожалуйста, мой пример:
Цель - 301 исправить лишь одно слово mashine на machine;
Например site.ru/catalog/mashine_1/ => site.ru/catalog/machine_1/ или
Например site.ru/catalog/mashine_mers_1/ => site.ru/catalog/machine_mers_1/

Расположение .htaccess - в корне веб-сайта;
Пример получился весьма длинный - уверен есть возможность сделать короче:
RewriteRule ^catalog/mashine_([A-Za-z0-9_] )/$ http://%{HTTP_HOST}/catalog/machine_$1/ [R=301,L]

Сейчас все работает, но не сделал ли я ничего лишнего, не перегнул ли палку. Или его как то можно упростить? Пожалуйста, критикуйте, если что-то не правильно. Заранее благодарен.

Ответ: Если Вы редиректите на этот же домен, %{HTTP_HOST} можно опустить:
RewriteRule ^catalog/mashine_([A-Za-z0-9_]+)/$ /catalog/machine_$1/ [R=301,L]

Shem говорит:

Здравствуйте! отличная статья - открывает глаза новичкам. Прописал правило:

RewriteRule ^([A-Za-z0-9-_] )/([A-Za-z0-9-_] )/([A-Za-z0-9-_] )$ svp.php?pn=$1

Князь Васин говорит:

Подскажите пожалуйста, как вот сюда еще редирект запихнуть?
RewriteRule ^(.*?)(.*?)/(.*)$ $1catalogue/$2?$3
Через [R] как то никак не получается

Ответ: Желательно написать реальный пример, откуда куда редиректить

Дмитрий говорит:

Не совсем)Там я большое сообщение написал, но отобразилась только часть его. В любом случае проблема уже решена, еще раз спасибо за статью.

Vlad говорит:

Класс, реально спасибо.
Оччень помогло в тяжелых буднях

Сергей говорит:

Спасибо огромное за статью!
Но я, все же, не могу справиться со своей задачей.
Заменить группу правил:
RewriteCond %{QUERY_STRING} ^firma_kond=11$
RewriteRule ^split_systems_daikin.php /split_systems_daikin.php? [R=301,L]
RewriteCond %{QUERY_STRING} ^firma_kond=11$
RewriteRule ^cassette_conditioners_daikin.php /cassette_conditioners_daikin.php? [R=301,L]
RewriteCond %{QUERY_STRING} ^firma_kond=11$
RewriteRule ^channel_conditioners_daikin.php /channel_conditioners_daikin.php? [R=301,L]

на одно с использованием регулярных выражений:
RewriteCond %{QUERY_STRING} ^firma_kond=11$
RewriteRule ^(.*).php?(.*)$ /$1.php? [R=301,L]

Подскажите, пожалуйста, в чем ошибка.

Ответ: А так?
RewriteRule ^(.*)\.php /$1.php? [R=301,L]

Вообще, суть данного у тебя редиректа заключается в отлавливании GET переменной firma_kond=11 (и только! То есть на firma_kond=11&page=2 условие не сработает, я думаю ты понимаешь почему). При обнаружении: split_systems_daikin.php?firma_kond=11 срабатывает правило:
RewriteRule ^split_systems_daikin.php(обрати внимание знака конца строки $ нет, а это значит что может быть что угодно, в том числе и ?firma_kond=11) /split_systems_daikin.php?(так же обрати внимание, вопросительный знак в конце означает не передавать никаких GET переменных, то есть, ?firma_kond=11 отрубается) [R=301,L]

Принц Игорь говорит:

Спасибо за отличный материал. У меня вопрос. Есть сайт - (site.com), есть страница - (site.com/stranica.html), есть необходимость вывести эту страницу двумя ссылками, 1-вышеуказанной, 2-с добавлением преффикса (prefiks.site.com/stranica.html). Создал поддомен prefiks.site.com (папку почистил, что-бы не занимать место той-же инфой). Как сделать редирект, что-бы при открытии (в поисковиках) ссылки prefiks.site.com, переходило на prefiks.site.com/stranica.html

Ответ: Уточните вопрос, мне кажеться Вы хотите перенаправлять с site.com на prefiks.site.com ?

Дмитрий говорит:

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

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9] )/([A-Za-z0-9] ).html$ index.php?category=$1

Ответ: RewriteRule ^([A-Za-z0-9]+)/([A-Za-z0-9]+)\.html$ index.php?category=$1 [L]
Так?

Алексей говорит:

Спасибо за понятное разъяснение. Уже сколько лет занимаюсь сайтодельней, но с перенаправлениями приходится работать впервые. Ваша статья - лучшая!

rni говорит:

Вроде нашел решение
RewriteCond %{REQUEST_URI} ^/wp/
RewriteRule ^wp/$ http://raikovstudio.ru/%1 [L,R=301]

rni говорит:

У меня раньше сайт был в директории wp, потом был перемещен в корень... (глупость сделал конечно)
вот сейчас надо получается сделать так чтобы люди со старых ссылок http://mysite.ru/wp/?p=1 попадал на http://mysite.ru/?p=1
Не подскажете как сделать?

Ответ: Можно простым редиректом: RewriteRule ^wp/(.*)$ /$1 [R=301,L]

Артём говорит:

Спасибо за статью! Подскажите, как сделать чтоб ссылка НЕ заканчивалась расширением (.html) или слэшем?
То есть не так: nazvanie-stati.html
А так: nazvanie-stati

Dark говорит:

Спасибо, отличная статья, возник только вопрос по:
.html – означает что статическая строка оканчивается на .html
если "." - означает любой символ, выходит что .html - означает что строка оканчивается на [любой символ]html ?

Ответ: Совершенно верно. Спасибо за то, что указали на этот недочет.
Разумно будет закомментировать точку, что бы она была не "любым символом", а именно точкой: \.html

Слава говорит:

Здравствуйте!
Может не по теме, у меня вопрос по RewriteRule но чуть другой...
shop - поддомен

поддомен находится здесь:
/public_html/shop

что изменить в коде что бы можно было разместить папку так
/shop

/shop - когда файлы тут, так на данный момент не работает


RewriteRule ^shop/ - [last]
RewriteCond %{HTTP_HOST} (www.)?shop.мойсайт.com [nocase]
RewriteRule (.*) shop/$1 [last]

Княгиня chooch говорит:

спасибо, самая подробно и понятно написанная статья по теме

Александр говорит:

Блин не входят большие комментарии

Александр говорит:

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

RewriteRule ^([a-zA-Z0-9_-] )/([a-zA-Z0-9_-] )/([a-zA-Z0-9_-] )$ $1/index.php?adl=$2

Администратор: Александр, для того, что бы не сбивались пути к файлам, всегда указывайте путь от корня сайта (начинайте ссылку со слеш): href="/css/index.css"

Король Леонид говорит:

Огромное спасибо, три раза уже пытался разобратся с ЧПУ. Все форумы переситал но ничего не смог понять, птому как вся проблема в том что данный мод преобразовывает ссылки не с динамической в статические ссылки а НАОБОРОТ! А об этом никто ничего не пишет. Спасибо за разъяснение!

Diego говорит:

Огромнейшее спасибо за статью, всё то что нужно и понятно!

Князь великий сия земель Ветроподувайко говорит:

и 1 за величать в коментах) очень симпотно

Князь Ветроподувайко говорит:

Дякую! Змістовно і зрозуміло пояснено.

Сударь Александр говорит:

Спасибо за статью) все максимально просто и подробно расписано)

  • Купить часы Tommy Hilfiger у нас

    Подробное описание купить часы Tommy Hilfiger у нас.

    timeshop.com.ua

 
О сайте ⋅  Контакты