I've just started using mod_rewrite, this is what I use for a quite basic structured website with multiple language support:
RewriteEngine on
ErrorDocument 404 /error404.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})/([^/]+)$ $2.php?lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})/$ index.php?lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})$ index.php?lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ $1.php [L]
My idea was that languages are indicated at the beginning of the URl and need to be two characters (a-z or A-Z). After that there will be a string that refers to a php-file which has the same filename as the string, just .php attached. The language will be added as a GET-Variable (?lang=en
).
So, an URl could look like this: /en/index
and should then be redirected to index.php?lang=en
.
If the URl does not start with a language, but directly with the string, then no GET-variable will be attached to the string. E.g. /index
should refer to index.php
. If there is no string, then index should be used as default.
So far, so good. Works fine. Just if I enter a string (no matter if I use 2 characters for language or not), the site always shows an 500 Internal Server Error, instead of going to error404.php
. Also, if I delete this line (404) in .htaccess, it is still the same error.
So, I assume that there is something wrong with the other lines in the .htaccess that cause this error, does anybody have an idea what this could be?
Any help is highly appreciated!
Your rules are looping. At a glance, it looks like your last one:
Say I have this URL,
http://your.domain.com/blah
, and the fileblah.php
doesn't exist. This is what's happening.blah
, !-f is true, it's not a fileblah
, !-d is true, it's not a directoryblah
, internal rewrite toblah.php
blah
!=blah.php
, rewrite rules loopblah.php
!-f is true, it's not a fileblah.php
!-d is true, it's not a directoryblah.php
, internal rewrite toblah.php.php
blah.php
!=blah.php.php
, rewrite rules loopThis goes on until the rewrite engine has had enough and returns a 500 server error.
You can do one of 2 things here:
Add a directive to make all looping stop no matter what, which is an easy to get around this kind of stuff. But it will break rules that require looping. I don't see anything like that in your rules so it's safe (at least for now) to do this. Just add this to the top of your rules:
Do a pre-emptive check to see if the php file actually exists:
Helmut, try this (the last rule is the reason for the 500 internal error, and this also includes the suggestion of @DaveRandom to merge rule 2 and 3):