Configure mod_rewrite + .htaccess for an Apache VirtualHost (Centos 6)
I've been playing around with PHP webservices recently. While getting one setup is fairly simple, they look kind of funny since you have to specify the /index.php component of the URL before any parameters. The index.php piece can be hidden if you use the apache webserver with mod_rewrite enabled.
To improve the flexibility of my development environment I decided to implement an .htaccess file to store the mod_rewrite rules in an Apache VitualHost. This article describes how to get mod_rewrite and htaccess files working inside a VirtualHost file.
- Apache Module mod_rewrite [httpd.apache.org]
- Learn Apache mod_rewrite: 13 Real-world Examples Article [sitepoint.com]
- Apache Web Server .htaccess File Configuration Not working [cyberciti.biz]
- Centos provides mod_rewrite by default (see comment #2) [centos.org]
Setup the Apache Virtual Host configuration
- Open /etc/httpd/conf/httpd.conf
- Go to the bottom of the file and add in a virtual host that looks something like this:
< VirtualHost 18.104.22.168:80 >
CustomLog logs/mydomain.tld-access_log common
< Directory "/var/www/production/mydomain" >
< /Directory >
< /VirtualHost >
A few things to note:
- I had to add a couple of spaces to the opening and closing VirtualHost and Directory tags so Concrete5 doesn't auto-hide the tag
- Ensure that the Directory directive within the VirtualHost matches the DocumentRoot location.
- Make sure that you configure the AllowOverride setting inside the Directory directive to something other than None. I set mine to All since this is a test environment. In Production you'll want to be more specific in what overrides you grant
- Since you will need to restart apache for the virtual host to take effect, make sure that the virtualhost is setup correctly (no typos or illegal commands). If any command is not recognized or misspelled, apache will fail to start. Take appropriate precautions (like backing up your httpd.conf file) in case something goes wrong.
- In Centos 6 mod_rewrite is compiled into Apache. If you use a different distribution be sure to follow the appropriate instructions to get mod_rewrite installed
Prepare the .htaccess file with mod_rewrite directives
In the previous section we setup an Apache VirtualHost with a Directory directive pointing to /var/www/production/mydomain. Now we need to create an .htaccess file in the 'mydomain' folder that contains mod_rewrite directives. Here is what the sample mod_rewrite rule looks like:
RewriteRule ^(what.html)$ test.php/$1
About the .htaccess file:
- The FollowSymLinks option is only needed if you have symbolic links that need to be followed.
- RewriteEngine must be set to On for mod_rewrite rules to be in effect
- The RewriteRule section is composed of a regular expression with a matching group and a target URL that uses the capture group in the URL.
- In this case if you try to hit /what.html you will be redirected to /test.php/what.html. Not very useful, but it illustrates how mod_rewrite rules with capture groups work
- The $1 in the target URL specifies the FIRST capture group in the regular expression. You can have multiple capture groups. For example, here is a sample RewriteRule with 3 capture groups:
RewriteRule ^/([0-9A-Za-z]+)/([0-9A-Za-z]+)/([0-9A-Za-z]+)$ test.php/$1/$2/$3
This rule will capture 3 groups that are delineated by slashes (/). For more comprehensive examples see this reference.
Create test.php and give it a try
With the VirtualHost and .htaccess file created we now need a target file that will be called when the rewrite rule 'matches'. Here is a simple php file (saved as test.php in the 'mydomain' folder) we can use for the purpose (Spaces have been added to opening and closing tags so concrete5 doesn't filter them out):
echo 'Request URI: '.$_SERVER["REQUEST_URI"];
Path Info: '.$_SERVER['PATH_INFO'];
About the php file
This is a very simple php file that shows 2 things:
- The PHP $_SERVER["REQUEST_URI"] variable
- PHP $_SERVER['PATH_INFO'] variable
If you want to do some sort of PHP URL routing, these two variables will be of use to you. In this example you will be able to see the differences between the two in a controlled setting
Here is what you will see if you navigate to http://mydomain.tld/what.html (domain name is set 2 sections above in the Apache VirtualHost directive):
Note: You may notice that I'm accessing a directory beneath the domain in this screenshot. To make this work you just need to place the php and htaccess files in a subdirectory of the virtual host. From my testing I found that you can place an htaccess file in any sub-directory of a virtualhost and it will work, as long as the AllowOverride setting is configured the root directory of the VirtualHost directive (as we did in the previous section).
Final Note: I tried getting this to work by configuring the global AllowOverride options in the apache httpd.conf file and found no success. I had to use the < Directory> tag in each VirtualHost that needed to be configured for .htaccess and mod_rewrite.