Делаем чпу
В своей первой статье про mod_rewrite я рассказал, как сделать замену url на одно ключевое слово. Теперь можно рассмотреть более сложны варианты. Начнём с url, которые имеют несколько параметров. На практике это обычно какой-либо предмет и его категория. |
Предположим наш сайт содержит огромное кол-во музыки. Которая распределена по жанрам, а жанры уже разбиты на группы.
Тогда замененная ссылка будет выглядеть примерно так:
https://mus_site.net/music/S1 /G1.html
А ссылка обработчика допустим вот так:
https://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 получается хоть и привлекательный, но не совсем понятный. Надо бы добавить ключевых слов. Чтобы вышло примерно следующее:
https://mus_site.net/music/style/group.html
Но сделать это уже сложнее, так как явных идентификаторов в такой ссылке нету. Можно добавить в таблицу поле, которое будет связывать url с ключевиками и url, созданные обработчиком. А можно добавить идентификаторы к ключевым словам и получить вот такой url:
https://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)
нужно просто подставить значения при выводе из бд. И всё будет как надо 😉
Читайте также:
Оппа. Сразу в закладки. Наконец-то толковая статья как преобразовать url’ы. А то есть одна CMS без чпу, а с mod_rewrite у меня дружба складываться не хочет)).
Толково все расписал. А то в остальных статьях только теория, а как решить конкретную задачу получить из
[ссылка] человеческий url полдня приходится “догонять”. Респект!
Прикольно, еадо будет обязательно попробовать
Отлично написано, доходчиво, спасибо. А может есть че почитать в электронном виде по mod_rewrite и по созданию правил в htaccess? Можно на мыло, или ссылку на мыло, где можно скачать. Был бы благодарен.
Фридл Дж. Регулярные выражения (2-е изд.)
Тока предупреждаю, книга сложна для восприятия
вот линк [ссылка]
2-е функции взял из книги поисковая оптимизация для профессионалов, только у меня она в бумажном виде
Да книга действительно не из простых… Ну ничего, трудности нас не пугают. Спасибо за линк
Хорошо написано. Спасибо, понял)
Вообще лучше не городить много правил в htaccess, т.к. это сильно влияет на скорость. А подходить к этому вопросу с точки зрения mvc. т.е. ссылка всегда имеет вид [ссылка]
Тогда для этого нам понадобится всего то:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
поясняю: если файл не найден на сервере, то запрос будет отдан в index.php, где уже роутер будет парсить $_SERVER[‘REDIRECT_URL’] и загружать определённый контролёр и вызывать его нужный метод
Читал где-то, что много правил в .htaccess тормозят работу, но нигде подробных тестов так и не нашел. Рутер внутри php - это конечно более гибкая идея, согласен.
“Рутер внутри php - это конечно более гибкая идея, согласен”
многие движки используют такой подход. Например WordPress (этот блог), LiveStreet (движок аля Хабр)
Добавлю еще про “Рутер внутри php”. Этот подход используют пожалуй все известные php-фрэймворки (Zend, Symfony и др)
Спасибо за код, у меня почти все получилось. Но есть вопрос –
Как сделать, что бы параметр id по которому опреляется вывод результата, не выводился в адресной строке, к примеру у меня благодаря вашему примеру получается
[ссылка]
а нужно
[ссылка]
у меня без идентификатора не выводит нужный результат.
P.S. я новичек, поэтому просьба ответить на пальцах, заранее спасибо
В этом случае, если Вы не хотите передавать идентификатор через GET-запрос (чтобы его не было видно в адресной строке другими словами), есть два варианта: перед нажатием на ссылку записать идентификатор в сессию и считывать его оттуда. Второй вариант: передавать его через POST. В любом случае нужно как-то передать этот идентификатор скрипту, иначе получится волшебство
Что здесь нужно поправить?
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 страница
Непонятно, зачем здесь цикл do..while, если можно было обойтись просто while. И вместо printf можно использовать просто echo. Тут много чего я бы поправил
забыл выслать вторую страницу вывода, если не затруднит подскажите пожалуйста что надо исправить для того что бы работала функция без id
2. страница
$database = mysql_connect(…);
$result = mysql_query(“SELECT * FROM portfolio WHERE id=’$id'”, $database);
$myrow = mysql_fetch_array($result);
horser, цикл do…whilу необходим, иначе при выводе потеряешь одну строку.
Novice, скажи точно что ты хочешь получить? толи ты передаешь id другим путем, то ли ты вообще не хочешь передавать id. Что конкретно ты хочешь получить?
S.N.K, видимо ты перепутал меня с horser’ом 😉
Сразу начал делать сайт со ссылками вида “https://site.ru/index.php&p=1&id=4c7319c21570aeeca6c8774f216c6656&page=1″ типа для невозможности подбора цифр в “р”. Можно ли такие ссылки привести к виду “https://site.ru/news/page1/” ?
Можно, если переменную id будете передавать методом POST.
очень интересно написано, ну у меня ни чего не получилось (((
Как все запутано, я ничего не понял.