$ _GET ["foo"] NULL от RewriteRule - PullRequest
       3

$ _GET ["foo"] NULL от RewriteRule

1 голос
/ 11 января 2020

Я пытаюсь перенаправить http://localhost/tour/hello на http://localhost/tour.php?name=hello

Я попробовал следующее в моем .htaccess

RewriteEngine on

RewriteCond %{REQUEST_URI} ^/tour/(.+)/?$
RewriteRule ^tour/(.+)/?$ tour.php?name=$1 [L,QSA, NC]

Он перенаправляет на http://localhost/tour.php, но $ _GET ["name"] всегда равно NULL

, если я изменяю целевую страницу на что-либо, кроме tour. php это работает

RewriteRule ^tour/(.+)/?$    handler.php?name=$1 
RewriteRule ^tour/(.+)/?$    blah.php?name=$1

Все работы

1 Ответ

3 голосов
/ 11 января 2020

Вам необходимо отключить обсуждение содержания с помощью:

Options -MultiViews

В вашем .htaccess.

И AcceptPathInfo off.

Некоторые пояснения :

Первая проблема - это обсуждение контента. Допустим, у вас есть два файла с именами tour.txt и tour. php, если включено согласование содержимого, если ваш URL-адрес http://localhost/tour без расширения, Apache ищет файлы с именем tour с любое расширение, основанное на предпочтениях клиента (в частности, заголовок HTTP Accept для этого примера), попытается найти наилучшее совпадение среди tour.txt и tour. php для обслуживания клиента.

Второй элемент с вашей проблемой - AcceptPathInfo: при включении Apache принимает лишнюю часть в конце пути URL, чтобы заполнить ее как внутреннюю переменную (например, хорошо известную $_SERVER['PATH_INFO'] в PHP). Для иллюстрации, скажем, у вас есть файл тура. php. Так, с AcceptPathInfo on, http://localhost/tour.php/extra/path вызывает tour. php с $_SERVER['PATH_INFO'] = / extra / path вместо того, чтобы считаться несуществующим (404), как обычно ожидается / с AcceptPathInfo off.

Теперь скомбинируйте AcceptPathInfo и контент-аннулирование: проблема в том, что ваше правило пытается «перехватить» то, что начинается с tour /, но tour. php существует [это файл], поэтому оно конфликтует с вашим собственным правилом, поскольку путь tour / foo [для URL http://localhost/tour/foo] сначала определяется разрешением содержимого как tour.php / foo и «принимается» как tour. php с $_SERVER['PATH_INFO'] = / foo благодаря AcceptPathInfo. Вывод: в этом очень конкретном c случае переписывание не произошло, но это выглядит так из-за отрицательного отношения к контенту + AcceptPathinfo, который оказывает тот же эффект при посадке в тур. php, и именно поэтому вы не получаете строку запроса вы ожидали (name = foo).

Также обратите внимание, что в вашем правиле не должно быть пробела перед флагом N C.

...