Я просто хотел сделать простую вещь с mod_rewrite. У меня есть сайт, который использует файлы .php, и я хотел переписать их на более чистые URL-адреса и удалить .php. Таким образом, файлы были бы www.mysite.com/contact и так далее.
Это работает так, как я хотел, но я ожидал, что он все равно будет обслуживать мой файл contact.php, а просто покажет пользователю, что они находятся в / contact, а не contact.php. Но он ищет файл, только что вызванный контакт, которого нет.
Итак, что мне нужно делать, все еще используйте мой файл contact.php, но перепишите URL-адрес для пользователя / контакт?
Вот что я использую:
SetEnv APPLICATION_ENV development RewriteEngine on RewriteBase / # Always use www. RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC] RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301] # Change urlpath.php to urlpath RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC] RewriteRule ^(.*)\.php$ http://www.mysite.com/$1 [L,R=301]
Для этого решения я придерживался следующих правил:
/something.php
они должны быть перенаправлены извне в /something
. /something
то они должны быть внутренне перенаправлены на /something.php
. И вот окончательный набор магии mod_rewrite:
RewriteEngine on RewriteBase / ## Always use www. RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC] RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301] # Change urlpath.php to urlpath ## Only perform this rule if we're on the expected domain RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC] ## Don't perform this rule if we've already been redirected internally RewriteCond %{QUERY_STRING} !internal=1 [NC] ## Redirect the user externally to the non PHP URL RewriteRule ^(.*)\.php$ $1 [L,R=301] # if the user requests /something we need to serve the php version if it exists ## Only perform this rule if we're on the expected domain RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC] ## Perform this rule only if a file with this name does not exist RewriteCond %{REQUEST_FILENAME} !-f ## Perform this rule if the requested file doesn't end with '.php' RewriteCond %{REQUEST_FILENAME} !\.php$ [NC] ## Only perform this rule if we're not requesting the index page RewriteCond %{REQUEST_URI} !^/$ ## Finally, rewrite the URL internally, passing through the user's query string ## using the [qsa] flag along with an 'internal=1' identifier so that our first ## RewriteRule knows we've already redirected once. RewriteRule ^(.*)$ $1.php?internal=1 [L, QSA]
Третье правило должно быть наоборот:
# Change urlpath.php to urlpath RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC] RewriteCond %{REQUEST_FILENAME} !\.php$ [NC] RewriteRule ^/?(.*)$ $1.php [L,R=301]
Как только пользователь перейдет в / контакт, он загрузит contact.php. Дополнительный RewriteCond – это то, что если люди идут в contact.php, он не будет пытаться загрузить contact.php.php
Насколько я понимаю, вы хотите, чтобы URL-адрес был / был связан, даже если URL-адрес был /contact.php.
Вы можете проверить расширение .php и сделать перенаправление, чтобы удалить его. Используйте R = 301 (как и вы).
Затем вы должны заставить свой сервер принимать URL-адрес без расширения .php. На самом деле это уже можно сделать.
Это то, что делает mod_negotiation . Он должен быть установлен по умолчанию, но вам, возможно, придется включить его.
Вы также можете сделать это с помощью mod_rewrite, но удалите R из параметров. Он будет перенаправлять внутренне вместо ответа с помощью перенаправления HTTP.