ЧПУ для сайта на PHP. Простой и эффективный ЧПУ
- Подробности
- Категория: Для сайта
- Опубликовано 07.11.2012 23:34
Не так давно излазив порядочное количество сайтов, так ничего и не нашёл по интересующей меня теме о простом ЧПУ для сайтов, материалы безусловно были, но рассказано очень уж непонятно и както размыто, создавалось ощущение будто авторы текстов сами не понимали о чём пишут. Это также напоминало отдалённый корявый перевод с другого языка, настолько корявый что теряется весь смысл.
Ну так вот и с тех самых пор я хотел создать свой материал об этой теме, который наконец раскроет тайны создание простого незамысловатого ЧПУ без излишеств, строго и эффективно. Будем создавать ЧПУ с использованием .htaccess и непосредственно mod_rewrite, но всё по порядку.
Итак, начнём... Для примера выдумаем небольшую ситуацию:
Допустим нам нужно чтобы файл index.php принимал 2 переменные, например cat и art, т.е index.php?cat=содержимое&art=содержимое. Пусть в рамках примера cat - категория, art - статья, и есть у нас материал доступный по адресу index.php?cat=php&art=info-chpu, но мы понимаем как некрасиво это будет выглядеть в адресной строке браузера и нам нужно чтобы наш материал был доступен по адресу php/info-chpu. Поэтому нам нужен ЧПУ:
Главная роль представляемого ЧПУ отдаётся файлу .htaccess именно он делает всю работу. Итак чтоже должно быть в файле .htaccess:
RewriteEngine On
RewriteRule ^(.*)/(.*)$ index.php?cat=$1&art=$2 [L]
Теперь попытаюсь объяснить содержимое файла .htaccess. Строка RewriteEngine On - используется для так сказать включения перенаправления, по правилам которые вы опишите. Пользователь переходит по ссылке php/info-chpu, запускается тут же содержимое файла .htaccess, которое видит что запрашиваемая ссылка php/info-chpu подходит по правилу (.*)/(.*), всвязи с чем разделяет запрашиваемый адрес по частям правила содержимое1/содержимое2 и передаёт их исполнительному файлу index.php?cat=содержимое1&art=содержимое2.
Вот и всё. Теперь всё что нам следует сделать это "ловить" и использовать нашим index.php две переменные cat и art.
Внимание если обработчиком php вы используете cgi-bin то вместо файла .htaccess у вас должен быть htaccess.txt
Всё максимально просто и понятно. Если вдруг вы столкнулись с какими-то трудностями в использовании предложенном мною ЧПУ для сайта, рекомендую скачать
index.php - основной файл
htaccess.txt - файл для Cgi-bin обработчика
.htaccess - файл для Apache обработчика
Распакуйте содержимое архива к себе на сервер, и попробуйте запрос например <ваш_сервер>/trololo/512 или любой другой, <ваш_сервер> - как вы поняли писать не стоит, это я указал так место куда вы распакуете архив и откуда будете запускать файл.
Если остануться вопросы - пишите в комментариях.
Для тех, кто не понял что и как.
Вся суть данного ЧПУ состоит в htaccess файле, а что он именно делает?
RewriteEngine On
RewriteRule ^(.*)/(.*)$ index.php?cat=$1&art=$2 [L]
Можно сказать данный пример принимает адрес вида:
домен.ру/категория/материал
и отдаёт обработчикам ужи такого вида:
домен.ру/index.php?cat=категория&art=материал
А мы уже файлом index.php принимаем $_GET['cat'] и $_GET['art'], которые в себе содержат название категории и материала.
Показанный в статье пример можно изменять как угодно.
Например у нас есть рабочий адрес domen.ru/avto.php?cat=sportcars&avto=porshe&model=carrera и если мы хотим сделать его ЧПУ вида:
domen.ru/sportcars/porshe/carrera
, то пишем в .htaccess:
RewriteEngine On
RewriteRule ^(.*)/(.*)/(.*)$ avto.php?cat=$1&avto=$2&model=$3 [L]
И после того как мы добавим вешеуказанные пару строк в .htaccess файл, наш материал будет открываться для посетителей по адресу:
domen.ru/sportcars/porshe/carrera
Или вдруг если у нас имеется несколько обработчиков PHP, то можно для каждого поставить правило в .htaccess:
RewriteEngine On
RewriteRule ^avto/(.*)$ avto.php?id=$1 [L]
RewriteRule ^air/(.*)$ forair.php?id=$1 [L]
RewriteRule ^flot/(.*)$ waterflot.php?id=$1 [L]
Из примера видно, то всё запросы начинающиеся с domen.ru/avto/ будут отправляться в обработчик avto.php, начинающиеся с domen.ru/air/, в обработчик forair.php.
Теперь стоит отметить важное! перед вашим RewriteRule поставьте такой код:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
Этот код позволит вам избежать направления на обработчик при запросе статических папок и файлов, физически хранящихся в папке сайта.
Ещё очень важная особенность ЧПУ, которая не была освещена это ссылки в HTML коде вашего сайта к стилям, картинка и пр. Дело в том что относительный путь к картинкам и файлам, которые вы подключаете на странице нужно составлять с учётом ЧПУ, так как каждый слэш (/) в адресе будет расцениваться как папка. В итоге относительные пути ЧПУ будут вида "../../". Рекомендуем вам почитать статьи о относительных адресах, если вы не знаете как составлять их иерархию в HTML. Если же вы не хотите заморачиться на этом или не понимаете о чём речь, просто выставьте везде абсолютные пути, т.е для картинок вместо:
src="/images/vasya.png"
делайте
src="http://site.com/images/vasya.png"
В таком случае данные сайта будут вызываться корректно при любом ЧПУ, с любым количеством слешей. Точно также поступите со всеми подключаемыми файлами к HTML.
Настало самое время поговорить о втором варианте редиректа через .htaccess. Второй вариант полностью завязан на первом, но представляет собой универсальный редирект со стороны htaccess. Состоит редирект всего из одного правила:
RewriteRule ^([A-Za-z0-9-/]+)$ /engine.php?query=$1 [L]
Вся логика такого редиректа в том, что абсолютно всё после http://site.com/ будет отсылаться на обработчик engine.php в переменной $_GET['query']. Далее мы в engine.php можем разбить переменную на части:
$query=$_GET['query'];
$url=explode("/", $query);
И теперь мы получили массив $url в каждой ячейке которого содержиться часть полного пути. Например, если наш адрес (переменная query) выглядит так: transport/auto/ferrary/laferrary/description, тогда после обработки будет:
$url[0]="transport";
$url[1]="auto";
$url[2]="ferrary";
$url[3]="laferrary";
$url[4]="description";
И вы после обработки можете выполнять любые действия с этими данными.
И возможно пригодится: Для того чтобы узнать количество записей в массиве используйте count($url), для того чтобы посмотреть значение последней записи в массиве используйте end($url).