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