В статье ЧПУ своими руками PHP я уже немного рассказал о методе построения ЧПУ. Конечно, тот вариант не сильно привлекателен, если у вас огромный сайт и несколько сотен (а то и тысяч) страниц. Для таких больших проектов стоит применять немного другие методы. В этой статье будет рассмотрен один из них:
Хранение ЧПУ в базе данных
1) Плюсы:
Такие урлы доступны в любой точке кода. Просто сделал выборку по какой-то переменной из базы и получили ЧПУ-шный урл.
При хранении ссылки в базе можно расширить таблицу и внести туда 3 поля (для мета данных). В таком случае каждому урлу можно руками присваивать title,keywords & description. А это порой очень и очень нужная штука.
2) Минусы:
Для каждого товара, для каждой записи на странице будет необходимо обращаться к базе данных за ЧПУ-шным урлом. Думаю любому понятно, что это не есть хорошо. С другой стороны - если реализовать нормальное кеширование самых популярных ссылок - особых проблем (тем более на небольшом магазине) быть не должно.
При добавлении какой-то переменной (будь то страница, язык и т.д.) в базе будет создаваться новый урл (ведь исходный был изменен). В итоге, если вы не будете делать необходимых проверок и эту особенность заметят конкуренты - у вас будет вся база данных забита левыми ссылками и, вскоре, просто подохнет.
3) Реализация.
Для начала создайте табличку, в которой будете хранить сгенерированные ЧПУ.
У меня она имеет такой вид:
CREATE TABLE IF NOT EXISTS `pp_sef_links` (
`link_id` int(11) NOT NULL auto_increment,
`hits` int(11) NOT NULL,
`ufu` varchar(255) NOT NULL,
`link` varchar(255) NOT NULL,
`mdate` date NOT NULL,
`status` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`link_id`),
UNIQUE KEY `ufu` (`ufu`),
UNIQUE KEY `link` (`link`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Видим, что таким образом можно отслеживать обращения к ссылке, включать\выключать ее и т.д.
Далее нужен будет класс, который будет содержать набор методов для работы с ссылками.
При формировании страницы в месте, где должна быть ссылка будет вызов метода, который вернет ЧПУ
$sef->getUfu("index.php?task=news");
Реализация самого метода зависит от проекта. Это может быть просто набор правил, который по входящим параметрам выдает результат, или набор модулей (для каждого модуля - свой алгоритм). Важно одно: метод должен сначала проверить, нет ли ссылке в базе (если есть - вернуть ее), и если нет - создать новую и запихнуть в базу.
С генерацией и сохранением урлов разобрались. Теперь рассмотрим случай, когда пользователь кликнул по этому самому ЧПУ.
Для того, что новый урл обрабатывать, необходимо 2 вещи:
1) Единая точка входа (один файл, который будет отрабатывать наши ЧПУ, подключать необходимые модули, создавать переменные и т.д.). В моем случае - это index.php
2) Работающий .htaccess файл на сервере и включенный мод_rewrite
Содержимое .htaccess
# включаем мод реврайт
RewriteEngine on
#пишем условия срабатывания - всегда, кроме файлов (реально существующих на сервере)
RewriteCond %{REQUEST_FILENAME} !-f
# и директорый
RewriteCond %{REQUEST_FILENAME} !-d
# перебрасывать все на нашу точку входа, запихнув параметры запроса в переменную sefq
RewriteRule ^(.*)$ index.php?sefq=$1 [L,QSA]
Надо сказать, что sefq - я вообще не использую, вместо этого - проверяю $_SERVER['REQUEST_URI']
Часть кода из index.php, отрабатывающая запрос
if (isset($_SERVER['REDIRECT_STATUS'])) { // если есть редирект
$url=urldecode($_SERVER['REQUEST_URI']);// отрабатываем урл
$url=ltrim($url,"/"); // убираем лишние "/"
if (!$sef->parseURL($url)) { // метод по входящему ЧПУ получает "нормальную" ссылку
// и создает необходимые переменные в $_GET
// если не нашел ссылку - возвращает false
// error 404;
$sef->register404($_SERVER); // регистрируем 404 (чтоб потом можно было их чинить)
$app->notice($langData['_ERROR_404_']);//выдаем пользователю сообщение, что стрнаица не найдена
header("http/1.0 404 Not found");// ставим соответствующий хеадер
} else
header("http/1.0 200 Ok");// ставим соответствующий хеадер
}else { // direct page is ...
$newUrl=$sef->getUrl($_SERVER['REQUEST_URI']); // пытаемся сформировать ЧПУ по прямой ссылке
if ($newUrl === false){
$app->notice($langData['_ERROR_404_']); // если ничего не вышло - 404 ..
header("http/1.0 404 Not found");
}
elseif($newUrl != "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] && $_SERVER['REQUEST_METHOD'] == "GET") {
header("HTTP/1.1 301 Moved Permanently"); // если все нормально - по 301 редиректу перенаправляем пользователя на новую страницу
header("Location: ".$newUrl);
exit;
}
}
Плюшки, я дума, вы уже придумаете сами.
В следующей статье я напишу еще более (на мой взгляд) прикольный метод формирования ЧПУ, который наиболее подходит для больших магазинов или высоко нагруженных проектов!