Назад | Перейти на главную страницу

Apache mod_rewrite и переменная PHP REQUEST_URI

У меня проблема с передачей Apache на PHP $_SERVER['REQUEST_URI'] изменить URL-адрес после его перезаписи, а не запрашиваемый исходный.

Я делаю это переписывание, потому что у меня был веб-сайт WordPress, и я хотел переместить его в подкаталог, а не в корневой каталог, но все же хотел, чтобы его URL был корневым.

Это не происходит постоянно. Если я прошу www.xyz.com/wp-admin он заполняет PHP REQUEST_URI переменная с www.xyz.com/wordpress/wp-admin (который является URL-адресом после его перезаписи), но если я запрошу www.xyz.com/wp-admin/ (с косой чертой в конце) он фактически заполняет PHP REQUEST_URI переменная с www.xyz.com/wp-admin/ (исходный URL до перезаписи). Я хочу REQUEST_URI должен быть заполнен URL-адресом до его перезаписи.

Мой .htaccess файл ниже:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?xyz.com$
RewriteCond %{REQUEST_URI} !^/wordpress/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /wordpress/$1
RewriteCond %{HTTP_HOST} ^(www.)?xyz.com$
RewriteRule ^(/)?$ wordpress/index.php [L]
</IfModule>`

Версия PHP - 5.3. Версия Apache - 2.4 (Win32).


ОБНОВИТЬ: Я изучил это подробнее, и когда я ввожу URL www.xyz.com/wp-adminто сначала выполняется перенаправление 301 на www.xyz.com/wordpress/wp-admin/ но этого не происходит для www.xyz.com/wp-admin/ (с косой чертой в конце). Как и ожидалось, для той, у которой есть завершающая косая черта, есть только перезапись. Итак, теперь возникает вопрос, почему перенаправление 301 происходит в первую очередь для URL-адреса без косой черты в конце.

Чтобы уточнить, актуальной папки нет /wp-admin/, но есть папка /wordpress/wp-admin/.

«Проблема» связана с mod_dir (хотя mod_dir не является строго «проблемой» - он выполняет правильные действия и «исправляет» URL-адрес).

поскольку wp-admin является физическим каталогом, mod_dir "исправляет" URL-адрес, добавляя в конце косую черту (требуется для правильного обслуживания индекса каталога, например. index.php). Это делается с перенаправлением 301. Проблема в том, что это происходит после ваша внутренняя перезапись, которая приводит к тому, что перезапись превращается в перенаправление, таким образом подвергая вашу /wordpress подкаталог.

Итак, правильный URL строго /wp-admin/ (с косой чертой в конце). Если бы у тебя не было /wordpress подкаталог, и все было в корне документа, тогда mod_dir просто перенаправил бы /wp-admin к /wp-admin/, что затем приведет к /wp-admin/index.php обслуживается (как внутренний подзапрос).

Что вам нужно сделать, так это добавить завершающую косую черту вручную. Если запрошенный URL-адрес не заканчивается косой чертой, но в противном случае будет отображаться в физическом каталоге в /wordpress подкаталог, затем добавьте завершающую косую черту (через внешнее перенаправление). Это перенаправление должно произойти перед ваши внутренние переписывают.

Итак, попробуйте следующее перед ваши существующие директивы:

# Append a slash if it is omitted and would map to a directory
RewriteCond %{REQUEST_URI} !^/wordpress/
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/wordpress/$1 -d
RewriteRule (.*) /$1/ [R=302,L]

Что это значит, для любого запроса, который еще не запущен /wordpress/ и не заканчивается косой чертой, но сопоставляется с физическим каталогом внутри /wordpress подкаталог, затем перенаправьте и добавьте косую черту. Итак, запрос на /wp-admin перенаправляется /wp-admin/, предоставляя /wordpress/wp-admin существует как каталог. (Ваша внутренняя перезапись затем маршрутизирует URL-адрес, как и раньше.)

Вам нужно будет убедиться, что кеш вашего браузера очищен (или протестировать с открытым инспектором объектов браузеров и отключением кеша), поскольку предыдущие 301 редиректы (от mod_dir) были кэшированы.

Если вы уверены, что все в порядке, измените 302 (временное) перенаправление на 301 (постоянный) - если это намерение. 302 кэшируются браузером, что упрощает тестирование.


В стороне:

... Apache переходит на PHP $_SERVER['REQUEST_URI'] измените URL-адрес после его перезаписи, а не запрашиваемый исходный.

Apache на самом деле не проходит REQUEST_URI переменная из mod_rewrite напрямую в PHP. Хотя эти две переменные имеют одинаковое имя, насколько я могу судить, сам PHP заполняет эту переменную из запроса.

Апач REQUEST_URI серверная переменная и PHP $_SERVER['REQUEST_URI'] суперглобальные на самом деле содержат разную информацию:

  • PHP $_SERVER['REQUEST_URI'] содержит строку запроса, Apache REQUEST_URI серверной переменной нет.
  • PHP $_SERVER['REQUEST_URI'] содержит исходный URL-путь из запроса, а не перезаписанный URL. В то время как Apache REQUEST_URI Переменная сервера обновляется (на протяжении всего запроса), чтобы содержать перезаписанный URL.