Делаем чпу
![]() |
В своей первой статье про mod_rewrite я рассказал, как сделать замену url на одно ключевое слово. Теперь можно рассмотреть более сложны варианты. Начнём с url, которые имеют несколько параметров. На практике это обычно какой-либо предмет и его категория. |
Предположим наш сайт содержит огромное кол-во музыки. Которая распределена по жанрам, а жанры уже разбиты на группы.
Тогда замененная ссылка будет выглядеть примерно так:
http://mus_site.net/music/S1 /G1.html
А ссылка обработчика допустим вот так:
http://mus_site.net/show_music.php?style=1&group=1
Ну и правило оказывается не так и сложным, просто чуток длиннее.
RewriteRule ^music/S([0-9]*)/G([0-9]*)\.html$ /show_music.php?style=$1&group=$2
url получается хоть и привлекательный, но не совсем понятный. Надо бы добавить ключевых слов. Чтобы вышло примерно следующее:
http://mus_site.net/music/style/group.html
Но сделать это уже сложнее, так как явных идентификаторов в такой ссылке нету. Можно добавить в таблицу поле, которое будет связывать url с ключевиками и url, созданные обработчиком. А можно добавить идентификаторы к ключевым словам и получить вот такой url:
http://mus_site.net/music/style-s1/group-g1.html
Такая ссылка содержит ключевые слова и подогнать её под обработчик не составит труда.
RewriteRule ^.*-s([0-9]+)/.*-g([0-9]+)\.html$
/rewrite/index.php?style=$1&group=$2 [L]
Учтите, что в файле .htaccess писать правило надо в одну строчку.
Теперь смоделируем реальную ситуацию, в которой создание ссылок положим на плечи php. Представим, что у сайта есть бд в которой хранятся стили и музыкальные группы. Наша задача из всего этого сделать ссылку, которую поймет наше последнее правило mod_rewrite.
В одной умной книжке подобная задача уже была решена с помощью двух функций, которые мы сейчас и рассмотрим.
functions.php
//приводим url к нормальному виду
function clear_url($str)
{
$good_liters= '#[^-a-zA-Z0-9_]#';
//оставляем латиницу, подчеркивания, пробелы и дефисы.
$str = preg_replace($good_liters, '', $str);
//откусываем пробелы по сторонам
$str = trim($str);
//и всё подменяем дефисами
$str = preg_replace('#[-_ ]+#', '-', $str);
return $str;
}
//делаем ссылку с ключевиками
function create_url($cat_name,$cat_id,$group_name,$group_id)
{
$clear_cat_name = clear_url($cat_name);
$clear_group_name = clear_url($group_name);
$url = SITE.$clear_cat_name.'-s'.$cat_id .'/'.
$clear_group_name.'-g'.$group_id.'.html';
return $url;
}
?>
nav.html
index.php
include("nav.html");
echo 'стиль группы c номером '.$_REQUEST['style'].' а сама группа под номером '.$_REQUEST['group'];
?>
Как вы можете догадаться в строчку
create_url(”dance_music”,2,”pop group”,32)
нужно просто подставить значения при выводе из бд. И всё будет как надо
Читайте также:

Июль 25th, 2008
Оппа. Сразу в закладки. Наконец-то толковая статья как преобразовать url’ы. А то есть одна CMS без чпу, а с mod_rewrite у меня дружба складываться не хочет)).
Июль 25th, 2008
Толково все расписал. А то в остальных статьях только теория, а как решить конкретную задачу получить из
человеческий url полдня приходится “догонять”. Респект!
Июль 25th, 2008
Прикольно, еадо будет обязательно попробовать
Июль 25th, 2008
Отлично написано, доходчиво, спасибо. А может есть че почитать в электронном виде по mod_rewrite и по созданию правил в htaccess? Можно на мыло, или ссылку на мыло, где можно скачать. Был бы благодарен.
Июль 25th, 2008
Фридл Дж. Регулярные выражения (2-е изд.)
Тока предупреждаю, книга сложна для восприятия
вот линк
2-е функции взял из книги поисковая оптимизация для профессионалов, только у меня она в бумажном виде
Июль 25th, 2008
Да книга действительно не из простых… Ну ничего, трудности нас не пугают. Спасибо за линк
Август 18th, 2008
Хорошо написано. Спасибо, понял)
Ноябрь 15th, 2008
Вообще лучше не городить много правил в htaccess, т.к. это сильно влияет на скорость. А подходить к этому вопросу с точки зрения mvc. т.е. ссылка всегда имеет вид
Тогда для этого нам понадобится всего то:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
поясняю: если файл не найден на сервере, то запрос будет отдан в index.php, где уже роутер будет парсить $_SERVER['REDIRECT_URL'] и загружать определённый контролёр и вызывать его нужный метод
Ноябрь 17th, 2008
Читал где-то, что много правил в .htaccess тормозят работу, но нигде подробных тестов так и не нашел. Рутер внутри php – это конечно более гибкая идея, согласен.
Декабрь 4th, 2008
“Рутер внутри php – это конечно более гибкая идея, согласен”
многие движки используют такой подход. Например Wordpress (этот блог), LiveStreet (движок аля Хабр)
Февраль 1st, 2009
Добавлю еще про “Рутер внутри php”. Этот подход используют пожалуй все известные php-фрэймворки (Zend, Symfony и др)
Февраль 19th, 2009
Спасибо за код, у меня почти все получилось. Но есть вопрос –
Как сделать, что бы параметр id по которому опреляется вывод результата, не выводился в адресной строке, к примеру у меня благодаря вашему примеру получается
а нужно
у меня без идентификатора не выводит нужный результат.
P.S. я новичек, поэтому просьба ответить на пальцах, заранее спасибо
Февраль 19th, 2009
В этом случае, если Вы не хотите передавать идентификатор через GET-запрос (чтобы его не было видно в адресной строке другими словами), есть два варианта: перед нажатием на ссылку записать идентификатор в сессию и считывать его оттуда. Второй вариант: передавать его через POST. В любом случае нужно как-то передать этот идентификатор скрипту, иначе получится волшебство
Февраль 19th, 2009
Что здесь нужно поправить?
1 страница
<?php
$result = mysql_query (”SELECT * FROM portfolio”, $database);
$myrow = mysql_fetch_array($result);
do {
printf (”
%s
“, create_url($myrow["product"], $myrow["page"]), $myrow["icon"], $myrow["date"]);
}
while ($myrow = mysql_fetch_array($result));
?>
2 страница
Февраль 19th, 2009
Непонятно, зачем здесь цикл do..while, если можно было обойтись просто while. И вместо printf можно использовать просто echo. Тут много чего я бы поправил
Февраль 26th, 2009
забыл выслать вторую страницу вывода, если не затруднит подскажите пожалуйста что надо исправить для того что бы работала функция без id
2. страница
Февраль 26th, 2009
Февраль 26th, 2009
$database = mysql_connect(…);
$result = mysql_query(”SELECT * FROM portfolio WHERE id=’$id’”, $database);
$myrow = mysql_fetch_array($result);
Март 5th, 2009
horser, цикл do…whilу необходим, иначе при выводе потеряешь одну строку.
Novice, скажи точно что ты хочешь получить? толи ты передаешь id другим путем, то ли ты вообще не хочешь передавать id. Что конкретно ты хочешь получить?
Март 5th, 2009
S.N.K, видимо ты перепутал меня с horser’ом
Август 22nd, 2009
Сразу начал делать сайт со ссылками вида “http://site.ru/index.php&p=1&id=4c7319c21570aeeca6c8774f216c6656&page=1″ типа для невозможности подбора цифр в “р”. Можно ли такие ссылки привести к виду “http://site.ru/news/page1/” ?
Август 24th, 2009
Можно, если переменную id будете передавать методом POST.