开发者

Removing .php with mod_rewrite

开发者 https://www.devze.com 2022-12-10 16:48 出处:网络
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

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 manual开发者_开发技巧ly 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.


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]
0

精彩评论

暂无评论...
验证码 换一张
取 消