Форум программистов, компьютерный форум, киберфорум
Наши страницы
Apache, htaccess
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/254: Рейтинг темы: голосов - 254, средняя оценка - 4.64
Илья Федин
Бог живет в /root
884 / 350 / 1
Регистрация: 12.08.2012
Сообщений: 4,401
Записей в блоге: 5
1

Руководство по настройке ЧПУ (Rewrite)

16.09.2012, 15:48. Просмотров 46581. Ответов 7

В последнее время участились темы с проблемами по настройке ЧПУ (Rewrite)
Поэтому я решил написать это руководство
Для начала создайте файл .htaccess со следующим содержимым:
Код
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
Если не заработает то добавьте в .htaccess следующее:
Код
Options +FollowSymlinks
Теперь должно всё работать!
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.09.2012, 15:48
Ответы с готовыми решениями:

rewrite
Помогите разобраться в ошибке? использую мод rewrite, а сервер выдает error...

.htaccess Rewrite
На сервере есть html файлик. В нем подгружается скрипт по такому адресу....

rewrite Rule
Здравствуйте, помгите сделать ЧПУ. делаю так, но ничего не получается. ...

Mode Rewrite
Всем привет. Вот что в .htaccess RewriteEngine On RewriteBase / RewriteCond...

rewrite rules
Помогите разобраться с правилами: 1. Осуществить 301 редирект со страниц...

7
NoBodyIsPerfect
47 / 30 / 2
Регистрация: 11.06.2011
Сообщений: 206
23.09.2012, 00:48 2
а кириллические имена тут можно использовать?
1
Илья Федин
Бог живет в /root
884 / 350 / 1
Регистрация: 12.08.2012
Сообщений: 4,401
Записей в блоге: 5
23.09.2012, 11:46  [ТС] 3
Да. Может помочь: mod_rewrite. настройка .httasses на html - сайте
2
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16753 / 6644 / 864
Регистрация: 12.06.2012
Сообщений: 19,897
Завершенные тесты: 1
27.09.2012, 00:22 4
Несколько слов по поводу флагов, которые пишутся внутри квадратных скобок, стоящих после регулярного выражения. Основные и самые часто используемые это вот эти:

L останавливает процесс преобразования на этой строчке и не выполнять последующие за ней преобразования адреса
R= внешний редирект (после равно пишется адрес или цифра-статус). Если ничего не указать вылетит 302 "Временно перемещен"
QSA параметры ссылки ($_GET). Если его не указывать, они "потеряются"
NC регистронезависимо (т.е. CATEGORY и category одинаковы для правила)
F ошибка доступа (403 доступ запрещен)
S= пропустить правила (после равно количество правил)
G "умертвляет" URL-адрес (410 GONE)
N перезапускает заново правила преобразования, но уже работает с полученным в результате предыдущих действий адресом
E= присваивает переменным окружения значения (после равно пишут, вида переменная:значение)

Для преобразования самые полезные L, QSA и E, а также иногда NC (зависит от правил). Остальные полезны для перенаправлений/статусов и т.п.
P.S. это не все флаги, их еще раза в два или три больше) Здесь только основные на мой взгляд.

Можно также указывать несколько флагов через запятую. К примеру, как в сообщении выше:
[L,QSA]
или вот еще ситуация когда нужно несколько
[R=301,L] - если не остановить преобразования (L) то они будут продолжать выполняться дальше. А это уже лишнее

По поводу RewriteCond. Она используется для указания условий, при которых выполняется правила RewriteRule. К примеру эти две строчки означают
Bash
1
2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
что правила выполнятся только тогда, если нет этого файла или папки. Разберем буквы в конце

-d проверяет путь и является ли имя файла каталогом
-f проверяет, является ли файлом
-s аналогично -f, только еще проверяет чтобы размер файла был больше нуля
-l проверяет, является ли путь символической ссылкой
-F можно сказать, "аналог" -f, но проверяет внутренне (нехило ложит сервер)
-U проверяет URL на существование, также отправляя внутренний подзапрос - тоже здравствуй сервер))

Если вначале (перед дефисом) поставить восклицательный знак, то будет отрицание (т.е. наоборот)
Чаще всего используют только -f и -d (вернее, !-f и !-d)

Ну и немного об самих переменных сервера - сами они пишутся внутри фигурных скобок, а перед ними ставится знак процента. Вкратце о них:

REQUEST_FILENAME (или SCRIPT_FILENAME) полный путь к файлу или скрипту (или папке, и т.п.) соответствующему этому запросу
REQUEST_URI путь, который написан после имени сайта
THE_REQUEST строка с запросом к серверу от браузера (без заголовков браузера)
QUERY_STRING GET-параметры
API_VERSION версия API модуля APACHE
IS_SUBREQ содержит текст true, если запрос выполняется как подзапрос на данный момент или false в ином случае

Об остальных можете почитать в документации к серверу APACHE либо в документации к $_SERVER php.
Самые часто используемые - REQUEST_FILENAME, REQUEST_URI и QUERY_STRING

в RewriteCond тоже можно писать флаги - NC (уже знакомое), OR (либо следующее), NV (если заголовок HTTP используется в условиях, то этот заголовок добавляет к остальным, как то так)

Ну и последние две:
Bash
1
RewriteBase /
устанавливает базовый путь для преобразований. Не забудьте о том, что если в RewriteBase указан слэш, то из правил его стоит вычеркнуть (из начала) - он "съедается"))
ну и само
Bash
1
RewriteEngine On
включает (или отключает, если заменить On на Off преобразования URL-адреса (модуль mod_rewrite)

Ну.. Вроде все, если где то ошибся - прошу сообщить

Благодарю за внимание

Добавлено через 2 минуты
P.P.S. офф дока по модулю mod_rewrite: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html
15
MikleP
19 / 5 / 0
Регистрация: 20.05.2012
Сообщений: 6
28.09.2012, 00:13 5
Вот ещё может быть полезно:
Шпаргалка по mod_rewrite
Шпаргалка по регулярным выражениям

P.S. Всё в PDF
5
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16753 / 6644 / 864
Регистрация: 12.06.2012
Сообщений: 19,897
Завершенные тесты: 1
11.10.2012, 13:07 6
Решил еще немного написать по настройке ЧПУ. Простой пример: есть у нас ссылка вида
Код
site.ru/index.php?category=avto&type=buy&id=1
Мы, к примеру, хотим, чтобы она у нас выглядела вот так
Код
site.ru/avto/buy/1/
Или вот так
Код
site.ru/category/avto/buy/1/
Многие, кто читал про ЧПУ, почему то решили, что если прописать в .htaccess код - то этого достаточно, чтобы заходя на сайт, ссылки сами преобразовывались в "красивый ЧПУ". Так вот, это не совсем так. Необходимо сами ссылки сделать такими, как вы хотите сделать. Т.е., получается, что не из
Код
site.ru/index.php?category=avto&type=buy&id=1
преобразовывается
Код
site.ru/avto/buy/1/
а наоборот. Мы заходим по ЧПУ-шному адресу, а скрипт его видит как обычный (с передачей GET-параметров). Конечно, можно сделать и редирект со старых ссылок на новые - но, в основном, новички этого не делают.
ЧПУ можно делать как и с единой точкой входа - все запросы перенаправлять на один файл - а там уже разбирать пришедший запрос и показывать нужную информацию, так и "по обычному" - с передачей нескольких параметров.
Я коротко опишу оба, на процедурном подходе, без всяких паттернов и т.п. чтобы все смогли разобраться.

1 способ ("по обычному")

Итак, что же для этого всего необходимо.

Во-первых, конечно же сам код для перенаправления.
Для ссылки вида
Код
site.ru/avto/buy/1/
он будет выглядеть так:
Код
RewriteEngine On

#если запрошенного файла или папки не существует
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

#регулярим)
RewriteRule ^(.*)/(.*)/([0-9]+)/?$ index.php?category=$1&type=$2&id=$3 [L,QSA]
Здесь слева описывается регулярное выражение для захвата символа, справа - для $_GET. То есть, по русски можно прочитать ее как то так:
Левая часть:
Берем любые символы перед первым слэшем, берем любые символы перед вторым слэшем, берем цифры после второго слэша. Знак вопроса после последнего слэша означает его необязательное наличие.
Правая часть:
Перенаправляем запрос на файл index.php с GET-параметрами category - с тем что захватили в первой скобке левой части, type - то что захватили во второй скобке, и id - то, что захватили в третьей скобке.
Для ссылки вида
Код
site.ru/category/avto/buy/1/
регулярка поменяется на такую:
Код
RewriteRule ^category/(.*)/(.*)/([0-9]+)/?$ index.php?category=$1&type=$2&id=$3 [L,QSA]
Теперь запросы передаются на скрипт так, как будто мы вводили старый адрес. и если зайти на страницу с этим адресом, а в скрипте прописать к примеру вот так:
PHP
1
var_dump($_GET);
то мы как раз и увидим, что запросы успешно перенаправляются.

Теперь вторая важная часть. Необходимо поменять все ссылки на нужные нам - это раз.
т.е. вместо
HTML5
1
<a href="index.php?category=avto&type=buy&id=1">Avto buy full</a>
мы пишем так
HTML5
1
<a href="/category/avto/buy/1">Avto buy full</a>
или так
HTML5
1
<a href="/avto/buy/11">Avto buy full</a>
В зависимости от нашего правила преобразования.
Да, и еще. / - это путь от корневой директории, не забывайте.
Ну, тут вроде все, перейдем к единой точке входа.

2 способ (единая точка входа).

Код для .htaccess будет выглядеть уже как то так например
Код
ErrorDocument 404 /

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]
Вариантов много как писать, можно вот так еще
Код
RewriteRule ^(.*)$ index.php?route=%{REQUEST_URI} [QSA,L]
- но это будет от корневой директории.
Можно еще так
Код
RewriteRule . index.php [QSA,L]
Мне больше всего нравится первый и последний вариант - они понятнее и проще на мой взгляд.
Идем далее. В скрипте мы разбиваем полученную таким образом строку в $_GET['route'] (или $_SERVER['REQUEST_URI'])
Я буду разбивать $_GET
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
if(!empty($_GET['route'])) { #если есть "добавки к имени сайта" и это не ноль
 
    #разбиваем по слэшу строку, попутно удаляя лишние слэши
    $arr = explode( '/', trim($_GET['route'],'/') );
    #теперь в этом массиве у нас находится полученная строка запроса
    $count = count($arr); #смотрим сколько там всего записей
    #теперь проверяем, что ввели - сколько записей и т.п.
 
    if($count == 1) {
        
        #работаем с ним - извлекаем инфу из БД или подключаем нужный файл 
        #или просто выводим как я
        echo 'Параметр1: ', $arr[0]; 
 
    }
 
    else if($count == 2) {
        
        #работаем с ним - извлекаем инфу из БД или подключаем нужный файл 
        #или просто выводим как я
        echo 'Параметр1: ', $arr[0], '<br />Параметр2: ', $arr[1]; 
        
    }
    
    else if($count == 2) {
        
        #работаем с ним - извлекаем инфу из БД или подключаем нужный файл 
        #или просто выводим как я
        echo 'Параметр1: ', $arr[0], '<br />Параметр2: ', $arr[1], '<br />Параметр3: ', $arr[2]; 
        
    }
#можете дальше продолжать - только лучше тогда использовать switch-case
    else { 
        #неизвестная страница, делаем редирект куда то или отображаем свою страницу с ошибкой
        header('HTTP/1.0 404 Not Found'); #отправляем заголовок что страница не найдена
        #здесь можно подключить свою страницу 
        #например require_once 'error.html'; - и exit сделать так: exit();
        exit('<br /><br /><br /><center><b>404 Not Found</b></center>');
    }
 
}
else {
    #параметров нет - главная страница сайта.
}
для примера, т.к. это демка например на симфони - hello/username, то вот вариант с ним
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
function redirect() {
        #неизвестная страница, делаем редирект куда то или отображаем свою страницу с ошибкой
    header('HTTP/1.0 404 Not Found'); #отправляем заголовок что страница не найдена
        #здесь можно подключить свою страницу 
        #например require_once 'error.html'; - и exit сделать так: exit();
    exit('<br /><br /><br /><center><b>404 Not Found</b></center>');
}
 
if(!empty($_GET['route'])) { #если есть "добавки к имени сайта" и это не ноль
 
    #разбиваем по слэшу строку, попутно удаляя лишние слэши
    $arr = explode( '/', trim($_GET['route'],'/') );
    #теперь в этом массиве у нас находится полученная строка запроса
    $count = count($arr); #смотрим сколько там всего записей
    #теперь проверяем, что ввели - сколько записей и т.п.
 
    if($count == 2) {
        
        #работаем с ним - извлекаем инфу из БД или подключаем нужный файл 
        #или просто выводим как я
        if($arr[0] != 'hello')
            redirect();
        else
            echo 'Приветствую,  ', $arr[1];
        
    }
 
#неизвестный запрос
    else
        redirect();
 
}
else {
    #параметров нет - главная страница сайта.
}


Добавлено через 10 минут
Совсем забыл. При использовании первого способа можно указывать для каждой страницы и для каждой ситуации свои правила, сервер будет обрабатывать именно ту, под регулярку которой попадает запрашиваемый адрес.
Если не писать название страницы в правой части - то под регулярку попадут все страницы вашего сайта
14
Илья Федин
Бог живет в /root
884 / 350 / 1
Регистрация: 12.08.2012
Сообщений: 4,401
Записей в блоге: 5
11.11.2012, 11:47  [ТС] 7
Решил написать предупреждение к моему посту http://www.cyberforum.ru/post3455450.html:
Данный код подходит для основных CMS (т. е. Joomla! и Wordpress)! Для других возможно вам надо будет делать что-то типа такого:
Код
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
А теперь по-размышляем чтобы вы могли сами составить код:
Код
RewriteEngine on # Эта дериктива включает Rewrite
RewriteCond %{REQUEST_FILENAME} !-f # Это чтобы если такой файл есть то он не ревратился
RewriteCond %{REQUEST_FILENAME} !-d # Это чтобы если такой каталог есть то он не ревратился
RewriteRule ^(.*)$ index.php [L,QSA] # Здесь реврайт на index.php, приведём пример другого реврайта на котором будет легче объяснить:
#RewriteRule ^(.*)\/(.*)\/(.*)$ index.php?p1=$1&p2=$2&p3=$3 [L,QSA] # Это пример нескольких параметров, приведём пример что делает эта строка со скриптом:
# Было index.php?p1=rati&p2=para&p3=lucky
# Стало rati/para/lucky
1
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16753 / 6644 / 864
Регистрация: 12.06.2012
Сообщений: 19,897
Завершенные тесты: 1
08.03.2013, 23:54 8
Иногда появляются вопросы, как сделать перенаправление с www.site.ru на site.ru или наоборот. На самом деле, ничего сложного нет, просто надо добавить нужный код в файле .htaccess (имя начинается с точки)

Редирект с site.ru на www.site.ru:
Код
RewriteEngine On
RewriteCond %{HTTP_HOST} ^site\.ru$ [NC]
RewriteRule ^(.*)$ http://www.site.ru/$1 [L,R=301]
Редирект с www.site.ru на site.ru
Код
RewriteEngine On
RewriteCond %{HTTP_HOST} !^site\.ru$ [NC]
RewriteRule ^(.*)$ http://site.ru/$1 [L,R=301]
Соответственно, site.ru заменяете на свой адрес

Также, иногда возникают вопросы, как "убрать" index.php из ссылки на главной странице. Это можно сделать следующим образом:
Код
RewriteEngine On
RewriteRule ^index\.php$ / [R=301,L,QSA]
Добавлено через 5 минут
Как вариант, для редиректа с "сайт с www" на "сайт без www", чтобы не писать имя нужного сайта, можно сделать таким образом:
Код
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [L,R=301]
И аналогичное действие для обратного:
Код
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\..+)$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [L,R=301]
8
08.03.2013, 23:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.03.2013, 23:54

rewrite правила
подскажите пожалуйста как из ссылок: http://www.&lt;site&gt;.ru/send/index.php...

Mod rewrite
Здраствуйте только начал заниматься rewite-ом. И сразу сталкнулся с...

Rewrite Rule
Нужно чтобы при переходе на страницу /topic1#post3555 открывалась страница...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Закрытая тема Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru