I have an .htaccess
file with the following rules
# replace 'RewriteBase' with current working folder
# put '<base href="/">' in <head> if you are in the root folder
# put '<base href="/foldername/">' in <head> if you are in a subfolder of the root
Options +FollowSymLinks
RewriteEngine On
RewriteBase /pretty-urls
# Remove slash if file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ $1 [R=301,L]
# Redirect to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ $1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^(.*)$ user.php?u=$1 [NC]
This basically transforms and redirects any of the following URLS, www.mysite.com/about.php
, www.mysite.com/about
and www.mysite.com/about/
to www.mysite.com/about
and also should allow me to write www.mysite.com/user/john
but instead throws a Internal Server Error plus a 500.
I can't figure out what is wrong, the code is based on this ( How-to? Vanity URL & ignore .PHP extension with .htaccess )
My php looks like this
foreach ( $users as $user ) {
echo '<p><a href="user/'.$user->username.'">'.$user->username.'</a></p>';
}
Any help is appreciated, thank you.
EDIT: the Apache error log says
[Fri Sep 27 14:26:26.539589 2013] [core:error] [pid 2276:tid 1680] [client ::1:60023] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace., referer: http://localhost/pretty-urls/users
As suggested, I removed the [NC]
flag and added the [L]
flag, but the same error persists.
The error Request exceeded the limit of 10 internal redirects
is usually caused by a rewrite rule that both matches the original url as well as the rewritten url. The L
flag will only stop rewriting for the current cycle, but as apache pushes the request through .htaccess again anyway, this will not stop these faulty internal redirects.
When recreating this on my own localhost, I noticed that the problem is the rule that adds .php
to your url.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
%{REQUEST_FILENAME}
contains the filepath to document_root/user
in my case. You test if document_root/user.php
is a file (which it is), but then add .php
to the url, which will result in /user/john/.php
. I think the problem can be fixed to move your files to a subdirectory, so that the virtual url will never match a file or directory in your folders.
You could change the rule to something like the following, but I am not sure if this will eliminate the problem completely:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)/?(.*)$ $1.php?q=$2 [L]
This will rewrite link.url/test/qwer
to test.php?q=qwer
and link.url/test
to test.php?q=
.
Your rule to make an internal rewrite for user.php
should be moved above the 'general' rule and should be changed to:
RewriteRule ^user/(.*)/?$ user.php?u=$1 [NC,L]
This will rewrite link.url/user/john/
to user.php?u=john
.
As always, see the documentation. To properly debug .htaccess
, put LogLevel alert rewrite:trace3
in your httpd.conf
and restart the service. This would have showed lines like the following, which give you a clue what is happening:
[rewrite:trace1] [pid 4800:tid 1532] mod_rewrite.c(468): [client ::1:49451] ::1 - - [localhost/sid#3ecb48][rid#12b1a88/initial/redir#2] [perdir C:/wamp/www/] internal redirect with /user/john/.php.php.php [INTERNAL REDIRECT]