Как написать RewriteRules для .htaccess? - PullRequest
2 голосов
/ 01 мая 2019

У меня есть файл PHP с именем otp.php.

Когда URL-адрес в строке URL-адреса

http://localhost/college/otp/MTA=/teacher

Он должен рассматриваться как

http://localhost/college/otp.php?user=MTA=&role=teacher

Для этого я создал .htaccess файл в http://localhost/college/:

RewriteEngine On    # Turn on the rewriting engine
RewriteRule    ^otp/?$    otp.php    [NC,L]
RewriteRule    ^otp/[A-Za-z-]+/([A-Za-z0-9-]+)/?$    otp.php?user=$1&role=$2    [NC,L]

Но, otp.php файл говорит:

Примечание: неопределенный индекс: роль в C: \ wamp \ www \ College \ otp.php в строке 11

Примечание: неопределенный индекс: пользователь в C: \ wamp \ www \ College \ otp.php в строке 11

ОБНОВЛЕНИЕ

Когда URL-адрес в строке URL-адреса

http://localhost/college/otp/MTA/teacher

Он должен рассматриваться как

http://localhost/college/otp.php?user=MTA&role=teacher

Как мне решить эту проблему?

Ответы [ 2 ]

2 голосов
/ 16 мая 2019

URL: /college/otp/MTA=/teacher
Target: /college/otp.php?user=MTA=&role=teacher
.htaccess: /college/.htaccess

RewriteRule    ^otp/[A-Za-z-]+/([A-Za-z0-9-]+)/?$    otp.php?user=$1&role=$2    [NC,L]

Ваш RewriteRule шаблон нуждается в небольшой модификации, чтобы соответствоватьURL-адрес вашего примера, поскольку в настоящее время он не будет работать на = в MTA=.(Хотя я только что заметил, что «обновление» на ваш вопрос не показывает = в URL?) Этот шаблон также должен быть захватывая , чтобы $1 мог выбрать егоup.

Итак, вышеприведенная директива должна выглядеть примерно так:

 RewriteRule ^otp/([A-Za-z-]+=)/([A-Za-z0-9-]+)/?$ otp.php?user=$1&role=$2    [NC,L]

Это предполагает, что = всегда появляется в конце сегмента пути, какв вашем первоначальном примере (включите его в класс символов, если это может произойти где угодно - хотя это будет немного запутанно).Флаг NC, вероятно, не нужен, если только вам не нужно разрешать смешанные версии otp (не рекомендуется).Вы уже допускаете смешанный регистр в своем регулярном выражении.

ОБНОВЛЕНИЕ # 1: Кажется, что второй сегмент пути является строкой / целым числом в кодировке base64.Для этого вам нужно будет включить цифры в регулярное выражение, и может быть 0, 1 или 2 конечных = символов.Также нет необходимости сопоставлять дефис.Например:

 RewriteRule ^otp/([A-Za-z0-9]+={0,2})/([A-Za-z0-9-]+)/?$ otp.php?user=$1&role=$2    [NC,L]

Однако другая проблема, с которой вы, похоже, сталкиваетесь (и та, которую вы на самом деле «видите»), - это конфликт с MultiViews (часть mod_negotiation).Это должно быть отключено для работы вышеупомянутой директивы mod_rewrite (фактически, чтобы сделать что-нибудь).Если вы не включаете это в .htaccess, то отключите его, добавив в начало файла .htaccess следующее:

Options -MultiViews

Если MultiViews включен, то когда вы запрашиваете otp (гдесуществует файл с тем же basename , который также возвращает соответствующий тип mime) mod_negotiation выдает внутренний подзапрос для otp.php.Проблема в том, что это происходит за до mod_rewrite, поэтому otp.php в конечном итоге вызывается без каких-либо параметров URL.


В стороне:

Ваш код не должен генерировать эти уведомления с неопределенным индексом.Поскольку это, по сути, «данные, предоставленные пользователем», вы должны проверить это в своем скрипте.Например:

$role = isset($_GET['role']) ? $_GET['role'] : null;
RewriteEngine On    # Turn on the rewriting engine

Обратите внимание, что Apache не поддерживает комментарии в конце строки, поэтому вы должны удалить текст # Turn on the rewriting engine из первой строки.(Комментарии в конце строки могут показаться «работающими», однако это просто совпадение с тем, как работают директивы Apache в целом, в других случаях они приводят к внутренней ошибке сервера 500.)


ОБНОВЛЕНИЕ № 2:

Если строка URL имеет http://localhost/college/otp.php?user=MTA=&role=teacher, можно ли изменить ее на http://localhost/college/otp/MTA/teacher?

Да, это можно сделать,Хотя я предполагаю, что MTA= должно появиться в обоих местах?(У вас есть MTA= в исходном и MTA в целевом, что предположительно повредит кодировку base64?) Я предполагаю, что вы уже внутренне ссылаетесь на правильный URL-адрес, и это только в интересах случайных запросов (поисковых систем, обратных ссылок)и т. д .?)

Можно выполнить внешнее перенаправление перед перезаписью выше, соблюдая осторожность, чтобы не перенаправить перезаписанный URL и не запустить цикл перенаправления.Например:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^user=([A-Za-z0-9]+={0,2})&role=([A-Za-z0-9-]+)
RewriteRule ^(otp)\.php$ /college/$1/%1/%2 [QSD,R=302,L]

Это, в сущности, обратное внутреннему перезаписи (которое появится позже в файле .htaccess).Условие, которое проверяет переменную среды REDIRECT_STATUS, гарантирует, что она запускается только для прямых запросов, а не для переписанных запросов.

Обратите внимание, что, поскольку это внешнее перенаправление, вам необходимо включить относительный к корню URL-путьв аргументе substitution .то есть.включите подкаталог /college.(Или вы можете использовать относительную замену и установить RewriteBase - хотя это можно сделать только при наличии нескольких из этих директив.)

$1 - это обратная ссылкак шаблону RewriteRule (т. е. всегда otp), а %1 и %2 являются обратными ссылками на предыдущий CondPattern , т.е.значение параметров URL user и role соответственно.

Флаг QSD (Apache 2.4+) отбрасывает исходную строку запроса из запроса.

0 голосов
/ 12 мая 2019

Этот инструмент может помочь вам написать правильные выражения для ваших RewriteRules.Возможно, это выражение даст вам представление, где проблемы могут быть:

(.*otp)\/([A-Za-z0-9-]+=)\/([A-Za-z0-9-]+)

enter image description here

Описательный график RegEx

Это ссылка помогает визуализировать ваши выражения для RewriteRule:

enter image description here

Затем вы можете написать RewriteRule, может быть, что-то похожее на:

<IfModule mod_rewrite.c>
    RewriteEngine On    # Turn on the rewriting engine
    RewriteCond %{HTTP_HOST} localhost  [NC]
    RewriteRule    (.*otp)\/([A-Za-z0-9-]+=)\/([A-Za-z0-9-]+)  $1.php?user=$2&role=$3  [NC,L]
</IfModule>

Возможно, вы захотите очистить историю браузера при каждом изменении файла .htaccess.

...