homepage Welcome to WebmasterWorld Guest from
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

mod rewrite: /foo but not /foo.php

 12:50 pm on Oct 12, 2012 (gmt 0)

I hope you can help me with a little mod_rewrite issue. I have index.php and foo.php in my document root, but I need this behaviour:
example.com # 200
example.com/foo # 200
example.com/foo.php # 404

So it should not be possible to call the .php file directly.

I tried something like this, but now example.com/foo also responses with a 404.

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

RewriteCond %{REQUEST_URI} \.php$
RewriteRule ^(.*)$ - [L,R=404]

Can you help me?




 8:18 pm on Oct 12, 2012 (gmt 0)

The REQUEST_URI pointer is modified (updated) by an internal rewrite.

Your rule that blocks access must test THE_REQUEST so that only external requests for .php are rejected.

The rule that blocks access must be listed before the internal rewrite rule.

If you omit the required leading slash before $1 in the rewrite, you leave your server wide open to "path injection" attacks.


 10:27 pm on Oct 12, 2012 (gmt 0)

Hi g1smd,
this seems to work fine now:

RewriteCond %{THE_REQUEST} \.php
RewriteRule ^(.*)$ - [L,R=404]

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

Do you have other improvements for this rewrite rule? I also added a leading slash before $1 (it's correct now, right?), but...I think I don't know well why this is necessary in this case. :(
Do you know a page, where the path injection problem without leading slash is explained?

Thank you very much,


 10:59 pm on Oct 12, 2012 (gmt 0)

A few changes for efficiency...

The first
^(.*)$ should be \.php$

The second
^(.*)$ should be ^[^/.]+$ or ^([^/]+/)*[^/.]+$ and then the !-f test can be deleted.

/$1\.php should be /$1.php

[edited by: g1smd at 11:08 pm (utc) on Oct 12, 2012]


 11:03 pm on Oct 12, 2012 (gmt 0)

Ok, I've got another problem now. It's not working if someone trys example.com/bar and there is no bar.php file. Normally he should see a 404, but because of my last RewriteRule he will get an Internal Server Error. :(

So I think my solution isn't as good as I thought. Any idea to prevent this?


 12:14 am on Oct 13, 2012 (gmt 0)

It's not working if someone trys example.com/bar and there is no bar.php file.

Your rule doesn't check whether bar.php exists. It only checks whether bar exists-- and you already know it doesn't, because filenames in this form never exist.

I would be doing (starting from scratch)

RewriteCond %{THE_REQUEST} \.php
RewriteRule ^([^.]*)\.php$ http://www.example.com/$1.php [R=301,L]

(I think this is what g1 says, but we overlapped in editing so I'm not sure)

and if they get the 301-to-404 sequence that's their tough luck for requesting a nonexistent page in the first place.

9 times out of 10, the !-f line seems to be the lazy way of dealing with entirely different requests such as .jpg or .css which should never make it to the Condition in the first place.

Note that you may need to make a few file-specific exemptions, for example in my case piwik.php, which lives in the same domain.


 12:22 am on Oct 13, 2012 (gmt 0)


^([^.]*)\.php$ allows blank filename. Replace * with + here.

Assume you'd want to redirect to extensionless. Either block or redirect. It doesn't matter either way if the .php URLs haven't been previously published.


 1:55 am on Oct 13, 2012 (gmt 0)

Whoops, I did type too fast didn't I :)



and then pair with a REWRITE to



Global Options:
 top home search open messages active posts  

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved