Делаем чпу

В своей первой статье про 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

define('SITE', 'http://localhost/rewrite/');
//приводим 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("functions.php");
include("nav.html");
echo 'стиль группы c номером  '.$_REQUEST['style'].' а сама группа под номером '.$_REQUEST['group'];
?>

Как вы можете догадаться в строчку
create_url(”dance_music”,2,”pop group”,32)
нужно просто подставить значения при выводе из бд. И всё будет как надо ;)




Читайте также:



 #  #  #  #  #  #  #  #  #  #

22 Ответов на “Делаем чпу”

  1. Denis
    Июль 25th, 2008

    Оппа. Сразу в закладки. Наконец-то толковая статья как преобразовать url’ы. А то есть одна CMS без чпу, а с mod_rewrite у меня дружба складываться не хочет)).

  2. Eugeo
    Июль 25th, 2008

    Толково все расписал. А то в остальных статьях только теория, а как решить конкретную задачу получить из
    http://i-novice.net/gout/DkIQRQgcSxcMRFJLRUYaCA1SVExNRF1IBlhUFg9ZVlhXEAVYQggHBRENBkNWXkVaClIMBQ==/ человеческий url полдня приходится “догонять”. Респект!

  3. Константин
    Июль 25th, 2008

    Прикольно, еадо будет обязательно попробовать

  4. Skill00
    Июль 25th, 2008

    Отлично написано, доходчиво, спасибо. А может есть че почитать в электронном виде по mod_rewrite и по созданию правил в htaccess? Можно на мыло, или ссылку на мыло, где можно скачать. Был бы благодарен.

  5. novice
    Июль 25th, 2008

    Фридл Дж. Регулярные выражения (2-е изд.)
    Тока предупреждаю, книга сложна для восприятия :)
    вот линк http://i-novice.net/gout/DkIQRQgcSxMSRxkWWFVBFQpbVBoRQRpRV19YTQBEUQEKGBRdQg==/
    2-е функции взял из книги поисковая оптимизация для профессионалов, только у меня она в бумажном виде :)

  6. Skill00
    Июль 25th, 2008

    Да книга действительно не из простых… Ну ничего, трудности нас не пугают. Спасибо за линк :)

  7. ant
    Август 18th, 2008

    Хорошо написано. Спасибо, понял)

  8. bibendi
    Ноябрь 15th, 2008

    Вообще лучше не городить много правил в htaccess, т.к. это сильно влияет на скорость. А подходить к этому вопросу с точки зрения mvc. т.е. ссылка всегда имеет вид http://i-novice.net/gout/DkIQRQgcSxcMRFJKVFxbFRFZXVgGRhpZWk1eDQgZSAQUVwkEHUMFFgRdBUpSR1Y=/

    Тогда для этого нам понадобится всего то:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule .* index.php

    поясняю: если файл не найден на сервере, то запрос будет отдан в index.php, где уже роутер будет парсить $_SERVER['REDIRECT_URL'] и загружать определённый контролёр и вызывать его нужный метод

  9. cryptus
    Ноябрь 17th, 2008

    Читал где-то, что много правил в .htaccess тормозят работу, но нигде подробных тестов так и не нашел. Рутер внутри php – это конечно более гибкая идея, согласен.

  10. ekim
    Декабрь 4th, 2008

    “Рутер внутри php – это конечно более гибкая идея, согласен”
    многие движки используют такой подход. Например Wordpress (этот блог), LiveStreet (движок аля Хабр)

  11. ekim
    Февраль 1st, 2009

    Добавлю еще про “Рутер внутри php”. Этот подход используют пожалуй все известные php-фрэймворки (Zend, Symfony и др)

  12. horser
    Февраль 19th, 2009

    Спасибо за код, у меня почти все получилось. Но есть вопрос –
    Как сделать, что бы параметр id по которому опреляется вывод результата, не выводился в адресной строке, к примеру у меня благодаря вашему примеру получается

    http://i-novice.net/gout/DkIQRQgcSwkQQ2gWXkdQTw1TRRtSBxpfS1ZCEklFTBwKUw==/
    а нужно
    http://i-novice.net/gout/DkIQRQgcSwkQQ2gWXkdQTw1TRRsERlpNSRZEFh9aXQ==/

    у меня без идентификатора не выводит нужный результат.

    P.S. я новичек, поэтому просьба ответить на пальцах, заранее спасибо

  13. novice
    Февраль 19th, 2009

    В этом случае, если Вы не хотите передавать идентификатор через GET-запрос (чтобы его не было видно в адресной строке другими словами), есть два варианта: перед нажатием на ссылку записать идентификатор в сессию и считывать его оттуда. Второй вариант: передавать его через POST. В любом случае нужно как-то передать этот идентификатор скрипту, иначе получится волшебство :)

  14. horser
    Февраль 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 страница

  15. novice
    Февраль 19th, 2009

    Непонятно, зачем здесь цикл do..while, если можно было обойтись просто while. И вместо printf можно использовать просто echo. Тут много чего я бы поправил

  16. horser
    Февраль 26th, 2009

    забыл выслать вторую страницу вывода, если не затруднит подскажите пожалуйста что надо исправить для того что бы работала функция без id

    2. страница

  17. horser
    Февраль 26th, 2009
  18. horser
    Февраль 26th, 2009

    $database = mysql_connect(…);

    $result = mysql_query(”SELECT * FROM portfolio WHERE id=’$id’”, $database);
    $myrow = mysql_fetch_array($result);

  19. S.N.K
    Март 5th, 2009

    horser, цикл do…whilу необходим, иначе при выводе потеряешь одну строку.
    Novice, скажи точно что ты хочешь получить? толи ты передаешь id другим путем, то ли ты вообще не хочешь передавать id. Что конкретно ты хочешь получить?

  20. novice
    Март 5th, 2009

    S.N.K, видимо ты перепутал меня с horser’ом ;)

  21. Alexx
    Август 22nd, 2009

    Сразу начал делать сайт со ссылками вида “http://site.ru/index.php&p=1&id=4c7319c21570aeeca6c8774f216c6656&page=1″ типа для невозможности подбора цифр в “р”. Можно ли такие ссылки привести к виду “http://site.ru/news/page1/” ?

  22. novice
    Август 24th, 2009

    Можно, если переменную id будете передавать методом POST.

Оставить комментарий


© 2008 - 2010 i-novice.net | Все права защищены.