Removing .php with mod_rewrite

谁说胖子不能爱 提交于 2020-01-14 02:06:22

问题


I want to rewrite all my URLs to hide the .php extension. A general rule that adds .php to all URLs obviously won't do, so I want this rule to be conditional on the fact that

  • There is no file nor directory that matches the URL
  • After adding the .php, there is a match

I've arrived at these rewriting rules:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]

The first two take care of checking whether the request can be satisfied without rewriting (so for images and other non-PHP content). With the third rule I'd like to check if adding .php would make the request valid (if not, we'll try something else further down the rewrite rules, or return 404).

The RewriteCond %{REQUEST_FILENAME}.php -f part never seems to match though. Any suggestions?

EDIT

The rewrite log is containing these entries:

(4) RewriteCond: input='/contact' pattern='!-f' => matched 
(4) RewriteCond: input='/contact' pattern='!-d' => matched 
(4) RewriteCond: input='/contact.php' pattern='-f' => not-matched 

I find it strange that it's trying to match /contact, and not /var/www/mysite/htdocs/contact (At least that's what I'd expect when reading the docs on REQUEST_FILENAME). Apparently REQUEST_FILENAME is only what I expect when there is an actual match?

EDIT2

Thanks to Thomas for the answer: use %{DOCUMENT_ROOT} instead to manually compose the complete filename of the as yet unfound PHP file.

I've also thrown in an extra '/?' in the regexp to remove an optional / at the end of the URL, now all of /contact, /contact/ and /contact.php all refer to /contact.php:

RewriteCond %{DOCUMENT_ROOT}$1 !-f
RewriteCond %{DOCUMENT_ROOT}$1 !-d
RewriteCond %{DOCUMENT_ROOT}$1\.php -f
RewriteRule ^(.*?)/?$ $1.php [L]

UPDATE

After a lot of cursing I also found out that it depends on whether the RewriteRules are inside a <Directory> directive or .htaccess file on the one hand, or in your <VirtualHost> directive or just in the main body of an httpd.conf on the other hand. When inside a <Directory>/.htaccess, %{REQUEST_FILENAME} does contain the path so my initial solution should work there. Outside of <Directory>, you need to add the %{DOCUMENT_ROOT} yourself.


回答1:


I'm not so sure about using REQUEST_FILENAME. REQUEST_FILENAME should point to the full path of the matched file, but you are actually checking it's existence.

I would try something like:

RewriteCond  %{DOCUMENT_ROOT}/$1         !-f
RewriteCond  %{DOCUMENT_ROOT}/$1\.php    -f
RewriteRule  ^(.*)$                      $1.php [L]


来源:https://stackoverflow.com/questions/1672673/removing-php-with-mod-rewrite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!