Столкнулись с необходимостью написания ЧПУ в одном из проектов и делимся опытом по этому поводу.
Дано:
- Сервер под управление Apache;
- Скрипт, который выдает разный контент исходя из GET параметров;
- Ссылки вида
http://site.com/?page=contacts
нужно привести кhttp://site.com/contacts/
; - Необходимо прописать переадресацию со старых адресов на новые.
Все находится в файле .htaccess
. Все подробно комментировано.
RewriteEngine On
RewriteBase /
# Редиректы на url со слеш "/" на конце
# http://www.site.com -> http://www.site.com/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*[^/])$ $1/ [L,R=301]
# Редирект на url "без www"
# http://www.site.com/ -> http://site.com/
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# Пример редиректа с get параметрами от корня сайта
# http://site.com/?id=10 -> http://site.com/contacts/
RewriteCond %{REQUEST_URI} /$
RewriteCond %{QUERY_STRING} ^id=10$
RewriteRule ^.*$ http://site.com/contacts/? [L,R=301]
# Пример редиректа с get параметрами с вложенностью
# http://site.com/app/?id=edit -> http://site.com/contacts/
RewriteCond %{REQUEST_URI} app\.php$
RewriteCond %{QUERY_STRING} ^id=edit$
RewriteRule ^.*$ http://site.com/application/edit/? [L,R=301]
# ЧПУ
RewriteRule ^contacts/?$ ?page=contacts [L,QSA]
RewriteRule ^news/?$ ?page=news [L,QSA]
RewriteRule ^news/([^/]+)/?$ ?page=news&slug=$1 [L,QSA]
Статья про регулярные выражения уже была, подробно останавливаться на этом нет смысла.
ЧПУ
«Волшебство» преобразований происходит благодаря флагу QSA (query string append), указанному в квадратных скобках после каждого правила. Если строка запроса удовлетворяет правилу, то она является эквивалентом указанного адреса, и выдает тот же самый контент.
Например, RewriteRule ^news/?$ ?page=news [L,QSA]
и обратиться к сайту по адресу /news/
, то:
- Строка запроса
/news/
совпадет с указанным в правиле, значит это правило сработает; - Флаг
L
(last) указывает, что после этого правила другие применяться не будут; - Флаг
QSA
указывает на подстановку строки запроса и её НЕ ЧПУ аналог; - Строка запроса
/news/
аналогична НЕ ЧПУ адресу?page=news
; - По запросу
/news/
выводится контент точно такой же, как и если набрать?page=news
.
После этого остается написать редиректы с 301 кодом (постоянный редирект), чтобы случайно не получить дубли страниц в поиске.
Редиректы
Переадресацию прописать можно несколькими способами.
# Простой редирект
Redirect 301 /old.php http://site.com/new.php
# Редирект через RewriteRule
RewriteRule ^old /new/$1 [L,R=301]
# Редиректа с get параметрами
RewriteCond %{REQUEST_URI} old\.php$
RewriteCond %{QUERY_STRING} ^id=edit$
RewriteRule ^.*$ http://site.com/new/edit/? [L,R=301]
С первыми двумя все ясно. Старый адрес, потом новый. Если писать не Redirect
, а RewriteRule
, то нужно еще указать флаг R
и код редиректа.
Третий вариант перенаправляет по новому адресу по различным GET-параметрам.
RewriteCond
определяет условие сработает правило RewriteRule
.
- REQUEST_URI — Адрес, по которому осуществляется запрос;
- QUERY_STRING — Строка с GET-параметрами.
Если оба этих условия совпадают, то срабатывает правило, по которому с указанного адреса посетителя сайта переадресуют на указанный новый.
Представленные примеры позволяют подготовить самописный сайт без ЧПУ к продвижению в поиске.
Комментариев нет