Htaccess и ссылки вида /page/name?param=test

Рейтинг: 1Ответов: 1Опубликовано: 21.10.2014

Добрый день, помогите, пожалуйста, разобраться с htaccess.
Хочется получить ссылки ввида:

/page/name?param=test

где page - название страницы;
name - название первого параметра (пусть будет тоже name);
param - второй параметр, test - его значение (для примера, может меняться).

Так вот, каким образом можно заставить htaccess приводить ссылки к такому виду?
Сейчас у меня работает вот такое для одного параметра, а нужно добавить ещё:

RewriteRule ^page/(.*)$ index.php?name=$1 [NC,L]

По всякому пытался менять, но безуспешно. Первый параметр забирает в себя своё значение и значение второго параметра:

RewriteRule ^page/(.*)(\?(.*))?$ index.php?name=$1&param=$2 [NC,L]

Я понимаю, что всё из-за (.*), но как сказать, что мне нужно считывать первый параметр до ?, не знаю.

Ответы

▲ 3Принят
RewriteRule ^page/([^/]*)$ /index.php?name=$1 [NC,L]
RewriteRule ^page/([^/]*)/([^/]*)$ /index.php?name=$1&param=$2 [NC,L]

Учтите, что это действительно только для вариантов без слэша на конце. Примеры:

page/                             не попадает под правило
page/author                       синоним для index.php?name=author
page/author/                      не попадает под правило
page/author/20                    синоним для index.php?name=author&param=20
page/author/20/                   не попадает под правило
page/author/20/something          не попадает под правило

Чтобы учитывались с конечным слэшем и без него, нужно написать так:

RewriteRule ^page/([^/]*)/?$ /index.php?name=$1 [NC,L]
RewriteRule ^page/([^/]*)/([^/]*)/?$ /index.php?name=$1&param=$2 [NC,L]

Тогда правила будут срабатывать так:

page/                             не попадает под правило
page/author                       синоним для index.php?name=author
page/author/                      синоним для index.php?name=author
page/author/20                    синоним для index.php?name=author&param=20
page/author/20/                   синоним для index.php?name=author&param=20
page/author/20/something          не попадает под правило

Обновление:

# Строка вида profile/test без QUERY_STRING
# Вместо test может быть любое значение
# В качестве примера, для этого случая подставлено значение page=1 в целевой URL
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^profile/([^/]+)$ /profile.php?name=$1&page=1 [NC,L]

# Строка вида profile/test?page=8
# Вместо test может быть любое значение
RewriteCond %{QUERY_STRING} ^page=(\d+)$
RewriteRule ^profile/([^/]+)$ /profile.php?name=$1&page=%1 [NC,L]

Разберем построчно:

RewriteCond %{QUERY_STRING} ^$

RewriteCond - это "условие" для срабатывания первого нижеследующего "правила" RewriteRule. Перед правилом может быть несколько условий. Проверяться они будут последовательно.

%{QUERY_STRING} - это все, что идет после знака вопроса.
для profile/test?page=8 %{QUERY_STRING} будет таким: page=8
^$ - означает пустую строку.
Все вместе это означает, что в URL нет запроса с параметрами, т.е. страница такого вида profile/test.

RewriteRule ^profile/([^/]+)$ /profile.php?name=$1&page=1 [NC,L]

RewriteRule - как и говорил выше, это правило редиректа.

^profile/([^/]+)$ означает любую страницу, первая часть адреса которой начинается с profile/ а далее следует любой символ (как минимум 1), кроме "/". Значение в скобках будет запомнено. Иными словами profile/test глазами машины: profile/(test). Условию удовлетворяет, "test" сохранено в переменную. Имена переменным даются автоматически. Это числительные, начиная с 1. Сколько парных скобок - столько переменных.

В случае с правилом редиректа, указатель на переменную - это знак "$". Т.е. переменная, содержащая "test" будет вида $1 (1 - потому что это первая пара скобок).

/profile.php?name=$1&page=1 для нашего примера равно /profile.php?name=test&page=1

RewriteCond %{QUERY_STRING} ^page=(\d+)$

^page=(\d+)$ - ищем url, с такими параметрами запроса:

?page=число_которое_будет_сохранено_в_переменную_потому_что_выражение_в_скобках

Для ?page=8 в переменную будет сохранено число "8".

RewriteRule ^profile/([^/]+)$ /profile.php?name=$1&page=%1 [NC,L]

В случае с условием редиректа, указатель на переменную - это знак "%". Т.е. переменная, содержащая "8" будет вида %1 (1 - потому что это первая пара скобок).

/profile.php?name=$1&page=%1 для нашего примера равно /profile.php?name=test&page=8

Почему? Потому что $1 = "test", а %1 = "8"

Приоритеты нумерации скобок: снаружи вовнутрь, слева направо.