As mentioned above, the order of these directives is important. More specific rules should apply to more general rules, and this is a key problem with the above. However, the template also needs to be changed (made more specific) to prevent other distorted URLs causing an internal server 500 error and hacking your site. eg. /en/blog_post/2/3 (optional - erroneous - /something ) will still cause a 500 error in the "fixed" code above.
So, this can be written as:
Options +FollowSymLinks RewriteEngine On RewriteRule ^(bg|en)/([^/.]+)$ /$2?lang=$1 RewriteRule ^(bg|en)/([^/.]+)/([^/.]+)$ /$2?lang=$1&id=$3 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule (.*) /$1.php [L]
The generic pattern (.*) Is replaced by ([^/.]+) To match only path segments (excluding the slash). By doing this, it also means that the order no longer matters, and /en/blog_post/2/3 will simply result in 404.
I also removed the L flag in the initial RewriteRule directives, as you need to continue to add the .php extension.
RewriteRule substitutions should also be stored as relative to the root, i.e. starting with a slash. (Or you should include the RewriteBase directive.)
I also added another RewriteCond directive to make sure that <file>.php actually exists before adding the file extension. If you do not, and <file>.php does not exist, you will get another 500 errors.
You could combine the two RewriteRule into one if you don't mind having an empty id= parameter (which supposedly processes your script):
RewriteRule ^(bg|en)/([^/.]+)(?:/([^/.]+))?$ /$2?lang=$1&id=$3
This handles the requests /en/blog_post and /en/blog_post/2 .
source share