creating correct instructions for mod_rewrite. It seems to be very difficult.
I need exactly the following:
Redirect from www.example.com
to example.com
.
www.example.com/hello
==> example.com/hello
www.example.com/abc/def
==> example.com/abc/def
etc., and then other rules should be applied.
Direct access (no rewrite) to some specified files and folders (such as robots.txt
, images/, etc.)
Maybe
RewriteCond %{REQUEST_URI} !^/(robots.txt|favicon.ico|images|documents|~.\*)
Am I right? So, URLs like
example.com/robots.txt
==> example.com/robots.txt
example.com/documents/file1.pdf
==> example.com/documents/file1.pdf
should remain as is and shouldn't be rewritten.
Another transformation:
example.com/index.php?anythinghere
==> example.com/a/index.php?anythinghere
But if we type URLs example.com
and example.com/
Apache should call index.php
in the root folder (example.com/index.php
)
example.com
==> example.com/index.php
example.com/
==> example.com/index.php
I have MVC script, and if we type the following URLs:
example.com/controller
or example.com/controller/
or example.com/controller//
example.com/controller/function
or example.com/controller/function/
and if controller is one of predefined words in the list, say, "index", "news", "contacts" (maybe it will be expanded up to few hundreds of words), then we should call index.php
, rewriting URLs the following way:
example.com/controller
==> example.com/index.php?q=controller
example.com/controller/
==> example.com/index.php?q=controller/
example.com/controller//
==> example.com/index.php?q=controller//
example.com/controller/function
==> example.com/index.php?q=controller/function
example.com/controller/function/
==> example.com/index.php?q=controller/function/
example.com/controller/function/parameter
==> example.com/index.php?q=controller/function/parameter
example.com/controller/function/param1/param2/param3
==> example.com/index.php?q=controller/function/param1/param2/param3
example.com/anythinghere
==> example.com/a/index.php?anythinghere
Hope Apache doesn't use mod_rewrite recursively, or I will have huge troubles with different index.php
s.
For the first rewrite, you can put these lines in .htaccess:
RewriteCond %{HTTP_HOST} ^www.site.com$ [NC]
RewriteRule ^(.*)$ http://site.com/$1 [R=301]
It's very important to put R=301
in order to make it a permanent redirect, so that search engines won't see www.site.com
and site.com
as two different sites.
For the second rewrite many options are available. Perhaps will be more useful for you to make apache serve all the files that actually exist (such as images and pdf documents) and to rewrite those URLs that mean some MVC commands.
If you think so, you can cover your fifth rewrite, and write this:
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/news$ ./index.php?news [L]
RewriteRule ^/news/(.*)$ ./index.php?news/$1 [L]
And so on for each controller
you have. If you plan to have hundreds of controllers, then I think you should rethink the design of your system, or make them subcontrollers of a few main controllers, so these main controller can be written in this .htaccess
file.
Also important is L
, which tells apache it is the last line executed (last one if matched the condition), so you avoid recursion (among other things if I remember well).
To cover the third one:
RewriteRule ^/index.php?(.*)$ ./a/index.php?$1 [L]
To cover the sixth and last one:
RewriteRule ^/(.*)$ ./a/index.php?$1 [L]
So, covering the rewrites 1, 2, 3, 5 and 6 we can have:
RewriteEngine On
# First rewrite
RewriteCond %{HTTP_HOST} ^www.site.com$ [NC]
RewriteRule ^(.*)$ http://site.com/$1 [R=301]
# Second and fifth rewrite
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^/news$ ./index.php?news [L]
RewriteRule ^/news/(.*)$ ./index.php?news/$1 [L]
# Third rewrite
RewriteRule ^/index.php?(.*)$ ./a/index.php?$1 [L]
# Sixth rewrite
RewriteRule ^/(.*)$ ./a/index.php?$1 [L]