#php #apache #.htaccess
#php #apache #.htaccess
Вопрос:
На моем тестовом сервере с Apache и php7.1 я могу работать с подобным URL example.com/news/id/title
-адресом, и он перенаправляет меня example.com/news.php
, но URL-адрес остается тем же, и я могу использовать параметры после косых черт.
Теперь я работаю на живом хостинге, и он больше не работает. Я попытался перенаправить с помощью htaccess, и это работает для example.com/news
перенаправления example.com/news.php
, но если я добавлю что-нибудь после этого, я получу ошибку 404.
Как я могу перенаправить запросы /news/id/
туда news.php
, где я хочу прочитать идентификатор? И почему это работало изначально на моем тестовом сервере?
Тысяча благодарностей за любую подсказку.
Мой фактический .htaccess
:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^news/(.*) /news.php/$1 [R=301,NC,L]
Комментарии:
1. Можете ли вы поделиться более подробной информацией?
2. Обратите внимание, почему этот вопрос был закрыт? Все подробности есть в вопросе, если у вас есть опыт работы с MultiViews и
.htaccess
.3. Я тоже этого не знаю. Я сделал все улучшения в потоке. @MrWhite большое спасибо за вашу помощь и время!
Ответ №1:
Похоже, у вас может возникнуть конфликт с MultiViews (часть mod_negotiation). Вам нужно убедиться, что функция MultiViews отключена в верхней части вашего .htaccess
файла:
Options -MultiViews
Если включена функция MultiViews и вы делаете запрос на /news/id/
, то mod_negotiation выполняет внутренний подзапрос на /news.php
(без какой-либо дополнительной информации о пути), прежде чем mod_rewrite сможет переписать запрос.
почему это работало изначально на моем тестовом сервере?
По умолчанию в Apache функция MultiViews отключена, однако ряд общих веб-хостингов по какой-то причине ее включают. Это заставляет URL-адреса без расширения «волшебным образом» работать, ничего не делая, однако это потенциально создает дублирующий контент (плохо для SEO) и вызывает бесконечные неожиданные конфликты с mod_rewrite, такие как этот.
ОБНОВЛЕНИЕ: вместо этого измените свои директивы на что-то вроде следующего:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^news/(.*) /news.php/$1 [L]
Это внутренне переписывает (в отличие от _externally redirects_) all requests that start
/news//news.php//news.php to
- where
is passed as _path-info_ to
`. (Я предполагаю, что передача URL-пути в качестве path-info является намерением? Вы могли бы вместо этого использовать строку запроса или ничего не передавать в директиве и просто проверить запрошенный URL-адрес в PHP? — но это может потребовать немного большей обработки в PHP.)
Нет необходимости проверять, существует ли целевой файл, поскольку в этом примере он жестко запрограммирован.
Удаление R
флага приводит к внутренней перезаписи.
Вам нужно будет очистить кэш вашего браузера, поскольку 301 (постоянное) перенаправление будет кэшировано браузером.
Если вам нужно более общее решение, которое переписывает /<action>/<data>
/<action>.php/<data>
, напишите его следующим образом:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/] )/(.*) /$1.php/$1 [L]
Опять же, нет необходимости проверять, что запрос не сопоставляется с файлом, прежде чем проверять, что он сопоставляется с файлом при .php
добавлении.
Обратите внимание, что при этом не используется тестовая строка формы %{REQUEST_FILENAME}.php
(как у вас было изначально), поскольку это может привести к циклу перезаписи (ошибка 500) для определенных запросов. Смотрите мой ответ на следующий вопрос о ServerFault, который объясняет это подробнее: https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error
Комментарии:
1. Большое спасибо. Похоже, что это точка на моем тестовом сервере. Но как я могу перенаправить все запросы с
example.com/news/id/title
наexample.com/news.php?=id
на моем реальном сервере? Я нашел решение для перенаправления всех запросов на index.php но я хочу работать с разными php-файлами.2. Я упустил из виду, что вы перенаправляли запрос извне . Похоже, вместо этого вам следует внутренне переписать запрос. Я обновил свой ответ.
3. действительно
MultiViews
, иногда может быть очень раздражающим4. @CodeTube Как вы справились с этим? Если это ответило на ваш вопрос, пожалуйста, отметьте его как «принятый», нажав галочку / галочку рядом с ответом (чтобы помочь другим читателям и удалить вопрос из очереди неотвеченных вопросов). После того, как у вас будет 15 повторений, вы также можете проголосовать за ответы, которые сочтете полезными. Спасибо, очень признателен. 🙂