mod_rewrite, чтобы удалить .php, но все равно служить файлу .php?

Я просто хотел сделать простую вещь с 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] 

Solutions Collecting From Web of "mod_rewrite, чтобы удалить .php, но все равно служить файлу .php?"

Для этого решения я придерживался следующих правил:

  1. Если пользователь пытается загрузить /something.php они должны быть перенаправлены извне в /something .
  2. Если пользователь пытается загрузить /something то они должны быть внутренне перенаправлены на /something.php .
  3. Если пользователь передал какие-либо параметры строки запроса в URL-адрес, они должны быть сохранены через перенаправления.
  4. Если пользователь пытается загрузить другой файл, который действительно существует в файловой системе (таблица стилей, изображение и т. Д.), Тогда это должно быть загружено как есть.

И вот окончательный набор магии 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.