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

Сегодня поговорим о том, как реализовать человекопонятные 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]

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