htaccess Clean URL Gives Too Many Redirects

Viewed 31

I have the code below in my .htaccess file to remove php from the filename in the URL

# Apache Rewrite Rules
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

I now need to change the URL

editpermit.php?type=edit&id=1 

to

editpermit/edit/1

I've added below but I get the error 'Request exceeded the limit of 10 internal redirects due to probable configuration error.'. Other posts say to add an L to the end to show it's the last line but it's not making any difference.

RewriteRule ^editpermit/([a-z]*)/([0-9]+)$ editpermit.php?type=$1&id=$2 [NC,L]

I plan to have a few pages that will use this configuration so I need to know how to add these too at a later time

My full htaccess file is below

# Error pages
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
ErrorDocument 405 /405.php
ErrorDocument 500 /500.php
ErrorDocument 503 /503.php

# Apache Rewrite Rules
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f

RewriteRule ^(.*)$ $1.php
RewriteRule ^editpermit/([a-z]*)/([0-9]+)$ editpermit.php?type=$1&id=$2 [NC,L]
1 Answers
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

The problem is with your first "generic" rule that appends the .php extension. When you request editpermit/edit/1 and editpermit.php exists then the second condition is successful (REQUEST_FILENAME contains editpermit, not editpermit/edit/1), but it rewrites to editpermit/edit/1.php based on the requested URL-path captured from the RewriteRule pattern. This then causes a rewrite loop since editpermit/edit/1.php also matches this rule, rewriting the request a second time to /editpermit/edit/1.php.php etc. etc.

You need to write the above rule like this instead:

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

Now you are checking the same file that you are ultimately rewriting to.

See also my answer to the following question on ServerFault which goes into more detail:

(You don't need the first condition that checks the request does not map to a directory to then check that the request does map to a file.)

This can also be resolved by reversing the order of your rules (which you should do anyway). For example:

RewriteEngine On

RewriteRule ^editpermit/([a-z]+)/([0-9]+)$ editpermit.php?type=$1&id=$2 [NC,L]

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

NB: I changed the quantifier that matches the 2nd path segment in the first rule from * to +. Presumably this cannot be omitted? (Although if it was it wouldn't have matched anyway.)

Related