Use .htaccess to rewrite/redirect requests

How to redirect or rewrite URLs using .htaccess?

File, called as .htaccess, can be used to rewrite URLs apart from doing other stuffs like application handlers etc.

We can do some potent manipulations with our links, like,

  • Transforming long URL’s into short, easy to remember URLs
  • Transforming URLs having in-comprehensive query strings like “filename?id=carnivores&cat=animals” into human readable URLs like “livingthings/animals/carnivores”
  • Redirect missing pages. Instead of showing frustrating messages like “401 Page Not Found” you can show your users a neat html pages showing a humble message like “Your request seems to be having wrong structure. Please check your URL“. Or “We are under maintenance. Please be back after some time“.
  • Preventing hot-linking. Hot linking is, a third party using your servers bandwidth to access some stuff from your server directly eg images, css, javascript etc.
  • Performing automatic language translation (keeping all language files under one directory), etc.

Lets start writing our .htaccess file. We should put two lines (Options +FollowSymlinks and RewriteEngine on) in almost all .htaccess files to start the writing engine (details out of scope). I will skip these two lines in my examples, please remember to have them in your file. The third line specifies which directory to start from (make base directory). Note: In case you are putting htaccess file in some sub directory then RewriteBase should be written to point to that sub-directory else rewritten URLs (targets) will be relative to home directory of the domain.

1) How to rewrite to

Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ $1.php

Forward slash (/) here means home directory of (usually public_html)

Therefore our rewrite rules would match only filenames & paths which are just after (here somefile.html)

^, (.*), $ and $1 are all regular expression special characters having special meaning e.g, ^ is to match the start of the string (it is start anchor), similarly $ is end anchor. Do not get confused with $1, it is not an anchor. It carries the back-referenced data captured with the parentheses “(” and “)”. A dot “.” matches any character and an asterisk following this dot means zero or more characters. A dot preceded by a back slash \. matches the literal dot (and not any character). For more info please refer regular expression tutorials.

2) How to rewrite all language files to a language directory, say, to

RewriteRule ^(.*)\.html$ french/$1.html

3) How to permanently redirect old URLs to new ones (to secure old page ranks)

RewriteCond %{HTTP_HOST} ^olddomain\.com$ [NC]
RewriteRule ^(.*)$$1 [R=301,L]

Here [NC] refers to case insensitive match and R=301 gives the HTTP Response to the client as “Permanently moved” to new URL.

It will tell crawlers not to discard old URLs from their index and drop the page rank rather replace old ones with new ones.


Redirect permanent /oldhtmlfile.htm

This way we can either strip www. from our domain (or add it, if you want) to put away ambiguity (between and for crawlers and maintain a uniform linkage with external websites. For crawlers both are different entities.

To strip www.

RewriteCond %{HTTP_HOST} ^www\.mydomain\.com
RewriteRule ^(.*)$$1 [R=permanent,L]

To add www.

RewriteCond %{HTTP_HOST} ^mydomain\.com
RewriteRule ^(.*)$$1 [R=permanent,L]

Note: Moved permanently response code can also be served using PHP but that is not as good as doing by .htaccess file.

Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location:" );

4) How to catch query strings (?var=value&var2=value2 etc) to readable ones, say, to

RewriteCond %{QUERY_STRING} cat=(.*)
RewriteRule ^file.php.* /file.php/category/%1 [R]

This can be used to redirect (not only rewrite) a user to readable URL. [R] handles redirection. %{QUERY_STRING} a global variable, contains the whole query string. This can be used to support some old URL patterns (backward compatibility). Though the reverse of it would be used to show and store the human readable URLs while at server you still process them with old functionality, eg. your users remember and write URL like file/category/carnivores while you still process them with file.php?id=123

RewriteRule ^file/catogory/canivores/ file.php?id=123

Stop hotlinking of your images with,

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?host\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(jpe?g|gif|bmp|png)$ [L]

%{HTTP_REFERER} contains the name of the refereeing website (eg [NC] means case insensitive match, [L] means last (end up) the conditions rule here (to start another brand new rule, in case).

5) You can create some Not found error message pages.

ErrorDocument 401 /my-401-page.php

In this case if anybody requests a page which is not there on the server, s/he would be presented my-401-page.php, which can do some logging task also.

6) Limit the number of simultaneous connections to a directory or whole website (homepage) by,

MaxClients 100

7) In case of error, you can show your users an email of system administrator

How to debug rewrite rules in htaccess file?

a) Mostly, the problem could be that AllowOverride is not set to allow configuration directives.

You should make sure an AllowOverride None is not in effect for the file scope in question by putting garbage in your .htaccess file and reload. If a server error is not generated, then you almost certainly have AllowOverride None in effect.

b) Check the apache error log file (check through cpanel) at the sever.

c) Use the [R] option (which redirects the browser) to redirect the rewritten URL into the browser’s address bar. This URL can be appended with the matched back-references. Hence we get the regular expression matched strings in URLs e.g.,

RewriteEngine On
RewriteRule ^(.*)$ /file.php/category/match=$1 [R]

It will paste /file.php/category/match=”matched value here” in the address bar.

d) Close all instances of the browser while debugging.

Block robots from accessing webpages using .htaccess

How to block Use htaccess file. this is run by server and ensured by the server that the rules written in it are enforced. On the other hand, robots.txt file is just a guideline file. Robots are not bound to follow it. To ensure denial of all requests for the restricted directory, put the following […]

Stop indexing files in a directory using .htaccess

How to stop indexing of files in a directory using .htaccess? Sometimes we do not want to show all the files in a directory (which by default is a behavior of web servers). That can be done using htaccess file. Though there’s a simple solution to this, put an index.html file showing a decent message […]

HTTP Authentication in URL not working in IE

IE (Internet Explorer) doesn’t work with user names and passwords in Web site addresses URLs (HTTP/S). Though, IE versions 3.0 to 6.0 support this. The following URL syntax may not work in Internet Explorer or in Windows Explorer, http(s):// Reason: Such URL syntax is used to automatically send username/password to a Web site which requires […]

How to increase file upload limit using .htaccess

Sometimes sever settings do not allow you to upload files more than a fixed limit (usually 2 MB). But, some websites might require allowing files more than this limit. In such cases we need to set some options in httpd.conf configuaretion file. This sometimes is not allowed on shared servers. “.htaccess” file comes to the […]

How To Send Mail Using Mail Command in UNIX

Sometimes we need to send e-mails from UNIX command-line itself. Sometimes we need to write a small script to do so. Here’s what we need to do for such tasks. We can send mail in UNIX using “mail” command. Syntax is as follows, mail -s “Subject” -c “any_cc_email_id” -b “any_bc_email_id” “comma_separated_To_email_id” But the above syntax […]

How to know if a file exists on the web or not, in PHP?

I have listed a few methods in PHP to check the existence of a file on the web. <?php $fileURL = “”; echo “Checking the existence of $fileURL<br>”; ?> Method 1: <?php $a = microtime(true); //start time in microseconds of 1st method echo date(“d/m/y : H:i:s”, time()), ” “,$a, “<br>”; get_http_response_code($fileURL); //fast but not fool […]

How to remove last comma from a string in PHP?

To remove/trim the last/trailing or first/heading comma from a string, one should first confirm that the last character of the string is comma itself and nothing else. This would make the code foolproof and prevent accidental removal of characters other than comma. A few methods are described here and listed in the order of increasing […]