Реализация ЧПУ для сайта

Сегодня поговорим о том, как реализовать человекопонятные URL, а точнее, мы поговорим о том, как я это делаю.

Не будем вдаваться в споры — лучше или хуже, просто сразу к делу.

Итак. Для того, чтобы сделать ЧПУ нам необходимо прийти к общему знаменателю, а именно:
— данные хранятся в базе данных (субд MySQL)
— данные имеют уникальный идентификатор (id), являющийся полем int AUTO INCREMENT
— для отображения содержимого на странице мы используем строку GET типа index.php?id=3, само собой, как называть переменные — не имеет значения.
— на данный момент ваш sql запрос в коде выглядит как то так

SELECT * FROM table WHERE id='".mysql_real_escape_string($_GET['id'])."'

— структура таблицы выглядит как то так

CREATE TABLE `pages` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `text` text character set utf8,
  `title` varchar(255) character set utf8 default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Если все выше написанное у вас имеется — перейдем к делу.
Давайте поймем как все работает сейчас, и как оно должно работать в будущем, когда у нас будет ЧПУ.
Сейчас мы получаем какой то id страницы, и тащим всю информацию, которая соответствует полю с этим id в таблице.
В случае с ЧПУ все должно быть примерно также, за исключением того, что выборку по id мы больше делать не будем.. мы будем делать выборку по URL, а для того, чтобы не было повторов URL мы будем всячески извращаться в админской части.

Итак, если ранее мы просто вбивали в БД данные, то теперь нам нужно создавать еще два поля, для формирования ЧПУ

CREATE TABLE `news` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `text` text character set utf8,
  `title` varchar(255) character set utf8 default NULL,

  `url` varchar(255) character set utf8 default NULL,
  `url_num` int(11) default '0',

  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;

как видите, я добавил два поля — url и url_num. Поле url это само собой, сам URL (как получить транслит), но нам нужно учесть, что при добавлении записи в БД мы можем иметь одинаковые названия (у меня url формируется из названия: название + транслит = URL), но нам нельзя допускать совпадений, так как мы по сути эмулируем id, по которому будет происходить выборка из бд, поэтому, мы вручную будем проверять наличие только что созданного URL в базе данных.

$chpu = translit($_POST['title']); //получаем транслит название
$sql=mysql_query("SELECT max(url_num) as url_num FROM  pages  where url='".$chpu."'");
$row=mysql_fetch_array($sql);
if ($row['url_num']!=null)// проверяем - есть такой url или нет, если есть - то
		{
       $row['url_num']=$row['url_num']+1; //увеличиваем url_num на 1, чтобы избежать одинаковых ссылок
       $chpu2=$chpu."_".$row['url_num'];  // создаем дополнение к ссылке вида nash_url_1
       $upd="UPDATE pages SET url_num=url_num+1 where url='".$chpu."'"; // в бд указывем, что этот урл уже использует число (1 например, если это первый раз)
       mysql_query($upd);
		}
else
    { // если такого url нет
      $chpu2 = $chpu; // то переменная $chpu2 будет простым транслитом без дополнений
    }

Затем мы обычным способом вносим в БД наши данные, не забыв при этом внести в поле url значение $chpu2.

При выборке на странице пользователю мы уже отправляем не id, а url, т.е. вначале мы получим что то вроде
index.php?id=eto_ssylka_stranicy

Но ведь тоже не фонтан, правда? Мы ж хотим быть как все, чтобы все красиво и без закорючек и переменных. Для этого мы будем использовать mod_rewrite.

Начать нужно с того, что отдавая ссылки пользователю, нужно преобразовывать их в тот вид, который нужен вам, т.е. НЕ

<a href=index.php?url=<?=$row['url']; ?>"><?=$row['title']; ?></a>

а например так

<a href="page/<?=$row['url']; ?>/"><?=$row['title']; ?></a>

затем мы открываем (или создаем) файл .htaccess в корне сайта, и пишем следующее

RewriteEngine On
RewriteRule ^page/([^/]*)\/$ index.php?url=$1 [L]

Собственно — все. Если что непонятно — буду рад помочь в меру своих скромных способностей.

Дорогие читатели! Мною было принято решение закрыть комментарии на блоге. Теперь все обсуждения переносятся на недавно открытый форум, ввиду того, что формат сообщений там намного удобней для обсуждения. Не стесняйтесь задавать любые вопросы по тематике блога! Я всегда на связи.
Перейти на форум
.