Моя реализация ЧПУ
Нашёл на одном из блогов реализацию ЧПУ и решил внести свою лепту. ЧПУ - человеко понятный урл. На аглийском наиболее популярное название User Friendly URL. С какого-то перепугу разработчики решили, что стандартный урл с гет переменными непонятен и покатилось. Сначала сравним варианты для вывода списка новостей категории test отсортированного по date:
news.php?category=test&sort=date - стандартный подход, вроде всё понятно ключ=значение
news/category/test/sort/date/ - если убрать выделение, то не понятно где ключ, а где значение
news/test/date/ кратко, но довольно путано, обязательный порадок, трудно изменять
news/category:test/sort:date/ - этот вариант хорош, так же нагляден как класика и даже чуть короче
news.test.date - краткий, но не информативный, есть один плюс - такие страницы без тайтла сохраняются с нормальным названием.
Теперь рассмотрим классический разбор: через mod_rewrite apache пересылаем запрос на index.php, а там уже разбираем с помощью php. Разбор в самом mode_rewrite не очень хорошая идея, так как постоянно нужно модифицировать .htaccess. Самое популярное правило:
.htaccess ложится в корень сайта и прописывается (код из wordpress)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Сразу проверка есть ли модуль, а дальше если нет файла или директории с указаным адрессом, то пересылаем на index.php, а там разбираем $_SERVER["REQUEST_URI"]. У правила есть один огромный недостаток - разработчики постоянно забывают, что браузер запрашивает кроме страницы favicon.ico - для маленькой иконки в названии сайта. И если такого файла нету, то на index.php посылается и этот запрос, тем самым нагрузка удваивается. Вторая проблема - создал папку с названием модуля и всё, накрылся реврайт.
Я учёл эти проблемы и запихнул всё что должно быть доступно из вне в папку public, а затем для неё и favicon.ico отключил реврайт.
RewriteEngine on
RewriteRule !^(public/|favicon.ico) index.php [L]
Ну а дальше по отработанной схеме. Из недостатков - ограничение на название public. Из плюсов - теперь только в публик можно не придерживаться ЧПУ фреймворка, например, tinymce в папке public может использовать урлы с гет переменными, а если перенести за пределы, то всё будет работать через единую точку входа.
Похожие posts:
Нет обратных ссылок на эту запись.
Январь 15th, 2010 - 19:30
Это чтоб дописывал слеш в конце (для унификации урлов)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)([^/]{1})$ http://%{HTTP_HOST}/$1$2/ [R=301,L]
А это разбирает урл на папочки
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]*)$ index.php?mode=url&node[]=$1 [QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/([^/]+)/$ $1/?node[]=$2 [NE,QSA]
И все, htaccess модифицировать не придется, а гибкость больше (легче делать редиректы неправильных урлов на правильные). Да и по быстродействию этот способ побыстрее на коротких урлах (если считать верификацию маски пути)
Условия на папку/файл можно убрать, просто я считаю что реальный файл должен быть приоритетней виртуального
Январь 30th, 2010 - 22:03
по мне так лучше mod rewrite
переписывать придется стольео же раз, сколько пришлось бы править php, да и нагрузки меньше + можно отфильтровать get данные прямо сервером не доходя до скрипта, а это дополнительная безопасность. т.е напимер в isers/id/
вместо id не смогут подставить что-то кроме цифр.
Январь 31st, 2010 - 01:24
так php код вовсе не придётся править.
$r = new Request(‘news/list/sort:date/’);
$r->getController() – news
$r->getAction() – list
$r->getParam(’sort’) – date
$r = new Request(‘news/list/page:2/sort:date/’);
$->getParam(’sort’) – sort
$r->getParamInd(‘page’) – 2
а регулярку бы каждый раз пришлось переписывать, а так же следить за форматом.
Февраль 4th, 2010 - 16:25
Я тоже делал через одну точку входа, мне так удобно, правда я еще mysql приплел – http://js-php.ru/web-development/apache-mod_rewrite-php-mysql/
Неплохо кстати это дело в симфони организовано, там тоже вроде все через одну точку входа, но настройки лежат в ymml формате, все никак руки до него не дойдут, что за формат такой