ЧПУ (ЧеловекоПонятныеУрлы) - это ссылка вида site.com/page/2 вместо site.com/index.php?option=page&page_id=2 .
Приемущества использования ЧПУ думаю всем понятны. Это более короткие, простые и понятные урлы. К тому же "ходят слухи", что поисковикам они "больше нравятся". Последний факт я не проверял и было б странно, если б поисковики отсеивали или как то ограничивали ссылки, которые им "не нравятся", но если таке мнение есть - к ним надо прислушаться... Причина, из-за которой я начал смотреть в сторону ЧПУ - многие заказчики очень хотят их видеть у себя на сайте ...
Разработано достаточно много способов создания ЧПУ :
1. mod_rewrite - часто используемая технология. Идея заключается в установке спецового модуля к апачу и добавлению правил для преобразования короткого урла в полный в файл .htaccess
RewriteRule ^([^/]*)\.rss /rss.php?type=$1 [L]
+ : достаточно простой в реализации метод - накатал в .htaccess правила и все тут
-: надо, чтоб на сервере был установлен собственно mod_rewrite, при обьемном сайте - накопление правил в .htaccess
2. FileMatch - Основан на директиве FilesMatch, которая в Апаче является core feature. Все просто. Пишем опять же в .htaccess
Action throw /index.php <FilesMatch "^([^.]+)$">
ForceType throw
ForceType application/x-httpd-php
Эти директивы будут перенаправлять все запросы , не содержащие точки , на index.php. Дальше разобрать запрос - не особо сложно...
+: та же простота в реализации
-: надо, чтоб на сервере был установлен модуль mod_action
3. ErrorDocument - основан на дерективах в .htaccess файле для переброски запросов с несуществующих урлы на указаный файл. Для этого в .htaccess надо добавить:
ErrorDocument 404 /index.php ErrorDocument 401 /index.php
+: ИМХО самый простой способ, ничего устанавливать на сервере не надо, в индексе получил запрос , обработал и радуешься
-: на сервере в логах накапливается сообщения об 404 урлах... надо отключать логирование таких ошибок.
Еще стоит сказать, что даже после перенаправления запроса с несуществующего урла на существующий файл, сервер покажет нужную страницу, но все ровно вернет стаату 404 для этой страницы. Чтоб этого не было - надо вначало index.php добавить
header("http/1.0 200 Ok");
Уверен, что есть еще множество методов, но мы ограничимся этими.
В моем случае первый способ брать смысла не было ... непонятно будет ли на сервере у хостера стоять mod_rewrite (хотя обычно стоит ;)). Второй - у меня не заработал ... даже не знаю почему ;( Остался третий способ. Он как раз заработал как надо. Вся сложность заключалась в преобразовании ЧПУ-шного урла и обычный и наоборот. CMS Joomla (и многие другие видимо) используют для этих целей базу данных и динамически генерят новые урлы. Мну это не прет ... бо поработав с той же джумлой убедился, что львиная доля времени формирования страницы уходит на формирование и поиск этих урлов в БД ... Хотелось найти решение без баз данных, и я его нашел. Суть заключается в наборе правил вида:
$linksUrls[]=array('pages',"do=?");
$linksUrls[]=array('pages/?',"do=?&pid=?");
Для обработки таких урлов я написал спецовый класс (сам класс и файлы примеров можно найти вконце статьи). Разбирать сам класс мы не будем, а посомтрим способы его приминения на примерах.
1. Подключение и использование ЧПУ на сайте
$links=new Links($url,$use_ufu); //$url - название сайта. Будет добавляться к ссылам при генерации, $use_ufu (0\1) - использовать ЧПУ или нет
if ($use_ufu == 1) {
require_once("Links.rules.php"); // подгружаем файл с правилами
if (isset($linksUrls) && is_array($linksUrls)) // если есть массив с правилами - делаем инициализацию
$links->init($linksUrls);
}
Содержимое файла Links.rules.php :
$linksUrls=array();
$linksUrls[]=array('news',"do=?");
$linksUrls[]=array('news/?',"do=?&news_id=?");
// mod pages
$linksUrls[]=array('pages',"do=?");
$linksUrls[]=array('pages/?',"do=?&pid=?");
2. Разбор ЧПУ-шного урла и формирование GET запроса
if (isset($_SERVER['REDIRECT_STATUS']) && $_SERVER['REDIRECT_STATUS'] == '404') {
$url=$_SERVER['REQUEST_URI'];
if (!$links->parseURL($url)) {
// error 404;
die('Sorry, page not found'');
}
}
print_r($_GET);
Если все прошло хорошо - в массив $_GET будут добавлены переменные, которые б использовались при обычном запросе. Следует сказать, что запрос должен быть вида /pages/2 ю Следует так же указать, что можно указывать переменные, не определенные в правилах как в обычном запросе /pages/2?foo=5
3. Генерация ЧПУ из обычного запроса
$links->createUFU('index.php?do=pages');
// результат: site.com/pages/
Я конечно понимаю, что способ не есть универсальным, зато он достаточно простой в реализации, простов в применении.
В любом случае буду благодарен за любые коментарии\критику, поскольку они могут помочь усовершенствовать код\метод\способ ;)
TODO: Сейчас ЧПУ-шный урл формируется соединением значений из обычного урла с помощью "/". В дальнейшем планирую убрать привязку к порядку следования переменных в обычном урле.