views:

10

answers:

1

I have this rule which redirects all requests without a . in them to index.php, and it works fine:

# Redirect all page requests to content handler
RewriteRule ^([^.]*)$ index.php [L]

Now I'd also like to disallow any requests where the original URL contains .php in it. When I add another rule like this (after the first one), the first rule breaks:

# Disallow access to PHP files
RewriteRule \.php 404.php [L]

I thought that adding [L] to the first rule would stop the second rule from being executed, but it seems to have no effect: the output from the first rule (i.e. index.php) matches the second rule and all requests end up in 404.php. What am I doing wrong here?

+1  A: 

The [L] means no more rules are processed for this request, but the entire path is triggered again when index.php is being processed. Try adding a new rule making the 404 rule fire only if the requested page isn't index.php, something like this:

# Disallow access to PHP files
RewriteCond %{REQUEST_FILENAME} !=index.php
RewriteRule \.php 404.php [L]
zigdon
Thanks, I got it working with something similar to your example. I didn't realize that each rule would fire a new request. Just one more thing: is there a way to tell if a URL is the original one or a rewritten one? That way I could prevent the user from accessing `index.php` directly.
casablanca
Yeah, take a look at the reference for mod_rewrite, there's a test for subrequests.
zigdon