{"id":6995,"date":"2017-09-12T15:03:35","date_gmt":"2017-09-12T07:03:35","guid":{"rendered":"http:\/\/rmohan.com\/?p=6995"},"modified":"2017-09-12T15:03:35","modified_gmt":"2017-09-12T07:03:35","slug":"mod_rewrite-a-beginners-guide","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=6995","title":{"rendered":"MOD_REWRITE, A BEGINNERS GUIDE"},"content":{"rendered":"<p>mod_rewrite is used for rewriting a URL at the server level, giving the user output for that final page. So, for example, a user may ask for http:\/\/www.somesite.com\/widgets\/blue\/, but will really be given http:\/\/www.somesite.com\/widgets.php?colour=blue by the server.<\/p>\n<p>You can use mod_rewrite to redirect all pages to one central PHP page, which then loads the data that the user wanted from an external data file. Lots of people use mod_rewrite to show an \u201calternative\u201d image when people are hotlinking directly to their images.<\/p>\n<p>Assuming the mod_rewrite module is loaded, then you\u2019re good to go!<\/p>\n<p>A simple mod_rewrite example<\/p>\n<p>So, let\u2019s write a simple mod_rewrite example. This isn\u2019t going to be anything fancy; we\u2019re just going to redirect people who ask for alice.html to the page bob.html instead. First, let\u2019s create the Alice and Bob pages. Below is Alice\u2019s webpage \u2013 create a similar one for Bob.<\/p>\n<p>         This is Alice&#8217;s webpage<br \/>\nUpload both of these to your web server, and check that you can view both of them. Now comes the fun \u2013 we\u2019re going to add a couple of lines to your .htaccess file. The .htaccess file is a text file which contains Apache directives. Any directives which you place in it will apply to the directory which the .htaccess file sits in, and any below it. To ours, we\u2019re going to add the following:<\/p>\n<p>RewriteEngine on<br \/>\nRewriteRule ^alice.html$ bob.html<br \/>\nUpload this .htaccess file to the same directory as alice.html and bob.html, and reload Alice\u2019s page. You should see Bob\u2019s page being displayed, but Alice\u2019s URL. If you still see Alice\u2019s page being displayed, then check you\u2019ve followed the instructions correctly (you may have to clear your cache). If things still aren\u2019t working for you, then contact your technical support people and ask them to enable mod_rewrite and the FileInfo override in their httpd.conf file for you<\/p>\n<p>The structure of a RewriteRule<\/p>\n<p>RewriteRule Pattern Substitution [OptionalFlags]<br \/>\nThe general structure of a RewriteRule is fairly simple if you already understand regular expressions. This article isn\u2019t intended to be a tutorial about regular expressions though \u2013 there are already plenty of those available. RewriteRules are broken up as follows:<\/p>\n<p>RewriteRule<\/p>\n<p>This is just the name of the command.<\/p>\n<p>Pattern<\/p>\n<p>A regular expression which will be applied to the \u201ccurrent\u201d URL. If any RewriteRules have already been performed on the requested URL, then that changed URL will be the current URL.<\/p>\n<p>Substitution<\/p>\n<p>Substitution occurs in the same way as it does in Perl, PHP, etc.<\/p>\n<p>You can include backreferences and server variable names (%{VARNAME}) in the substitution. Backreferences to this RewriteRule should be written as $N, whereas backreferences to the previous RewriteCond should be written as %N.<\/p>\n<p>A special substitution is -. This substitution tells Apache to not perform any substitution. I personally find that this is useful when using the F or G flags (see below), but there are other uses as well.<\/p>\n<p>OptionalFlags<\/p>\n<p>This is the only part of the RewriteRule which isn\u2019t mandatory. Any flags which you use should be surrounded in square brackets, and comma separated. The flags which I find to be most useful are:<\/p>\n<p>F \u2013 Forbidden. The user will receive a 403 error.<br \/>\nL \u2013 Last Rule. No more rules will be proccessed if this one was successful.<br \/>\nR[=code] \u2013 Redirect. The user\u2019s web browser will be visibly redirected to the substituted URL. If you use this flag, you must prefix the substitution with http:\/\/www.somesite.com\/, thus making it into a true URL. If no code is given, then a HTTP reponse of 302 (temporarily moved) is sent.<br \/>\nA full list of flags is given in the Apache mod_rewrite manual.<\/p>\n<p>A slightly more complicated mod_rewrite example<\/p>\n<p>Let\u2019s try a slightly more meaty example now. Suppose you have a web page which takes a parameter. This parameter tells the page how to be displayed, and what content to pull into it. Humans don\u2019t tend to like remembering the additional syntax of query strings for URLs, and neither do search engines. Both sets of people seem to much prefer a straight URL, with no extra bits tacked onto the end.<\/p>\n<p>In our example, you\u2019ve created a main index page with takes a page parameter. So, a link like index.php?page=software would take you to a software page, while a link to index.php?page=interests would take you to an interests page. What we\u2019ll do with mod_rewrite is to silently redirect users from page\/software\/ to index.php?page=software etc.<\/p>\n<p>The following is what needs to go into your .htaccess file to accomplish that:<\/p>\n<p>RewriteEngine on<br \/>\nRewriteRule ^page\/([^\/\\.]+)\/?$ index.php?page=$1 [L]<\/p>\n<p>Let\u2019s walk through that RewriteRule, and work out exactly what\u2019s going on:<\/p>\n<p>^page\/<\/p>\n<p>Sees whether the requested page starts with page\/. If it doesn\u2019t, this rule will be ignored.<\/p>\n<p>([^\/.]+)<\/p>\n<p>Here, the enclosing brackets signify that anything that is matched will be remembered by the RewriteRule. Inside the brackets, it says \u201cI\u2019d like one or more characters that aren\u2019t a forward slash or a period, please\u201d. Whatever is found here will be captured and remembered.<\/p>\n<p>\/?$<\/p>\n<p>Makes sure that the only thing that is found after what was just matched is a possible forward slash, and nothing else. If anything else is found, then this RewriteRule will be ignored.<\/p>\n<p>index.php?page=$1<\/p>\n<p>The actual page which will be loaded by Apache. $1 is magically replaced with the text which was captured previously.<\/p>\n<p>[L]<\/p>\n<p>Tells Apache to not process any more RewriteRules if this one was successful.<\/p>\n<p>Let\u2019s write a quick page to test that this is working. The following test script will simply echo the name of the page you asked for to the screen, so that you can check that the RewriteRule is working.<\/p>\n<p>         The requested page was:<br \/>\n         < ?php echo $_GET['page']; ?><br \/>\nAgain, upload both the index.php page, and the .htaccess file to the same directory. Then, test it! If you put the page in http:\/\/www.somesite.com\/mime_test\/, then try requesting http:\/\/www.somesite.com\/mime_test\/page\/software. The URL in your browser window will show the name of the page which you requested, but the content of the page will be created by the index.php script! This technique can obviously be extended to pass multiple query strings to a page \u2013 all you\u2019re limited by is your imagination.<\/p>\n<p>Conditional Statements and mod_rewrite<\/p>\n<p>But what happens when you start getting people hotlinking to your images (or other files)? Hot linking is the act of including an image, media file, etc from someone else\u2019s server in one of your own pages as if it were your own. Obviously, as a webmaster, there are plenty of times when you don\u2019t want people doing that. You\u2019ll almost certainly have seen examples where someone has linked to one image on a website, only for a completely different, \u201cnasty\u201d one to be shown instead. So, how is this done?<\/p>\n<p>It\u2019s pretty simple really. All it takes are a couple of RewriteCond statements in your .htaccess file.<\/p>\n<p>RewriteCond statements are as they sound \u2013 conditional statements for RewriteRules. The basic format for a RewriteCond is RewriteCond test_string cond_pattern. For our purpose, we will set the test_string to be the HTTP_REFERER. If the test string is neither empty nor our own server, then we will serve an alternative (low bandwidth) image, which tells the person who is hotlinking off for stealing our bandwidth.<\/p>\n<p>Here\u2019s how we do that:<\/p>\n<p>RewriteEngine on<br \/>\nRewriteCond %{HTTP_REFERER} !^$<br \/>\nRewriteCond %{HTTP_REFERER} !^http:\/\/(www\\.)?somesite.com\/.*$ [NC]<br \/>\nRewriteRule \\.(gif|jpg|png)$ http:\/\/www.somesite.com\/nasty.gif [R,L]<br \/>\nHere, the RewriteRule will only be performed if all the preceeding RewriteConds are fulfilled. In the second RewriteCond, [NC] simply means \u201cNo Case\u201d, so it doesn\u2019t matter whether the domain name was written in upper case, lower case or a mixture of the two. So, any requests for gif, jpg or png files from referers other than somesite.com will result in your \u201cnasty\u201d image being shown instead.<\/p>\n<p>The [R,L] in the RewriteRule simply means \u201cRedirect, Last\u201d. So, the RewriteRule will visibly redirect output to \u201cnasty.gif\u201d and no more RewriteRules will be performed on this URL.<\/p>\n<p>If you simply don\u2019t want the hot linkers to see any image at all when they hot link to your images, then simply change the final line to RewriteRule \\.(gif|jpg|png)$ \u2013 [F]. The \u2013 means \u201cdon\u2019t rewrite the requested URL\u201d, and the [F] means \u201cForbidden\u201d. So, the hot linker will get a \u201c403 Forbidden message\u201d, and you don\u2019t end up wasting your bandwidth.<\/p>\n<p>Conclusion<\/p>\n<p>mod_rewrite is an incredibly handy tool to have in your arsenal. This article only scratched the surface of what is possible with mod_rewrite, but should have given you enough information to go out and start mod_rewriting history yourself!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>mod_rewrite is used for rewriting a URL at the server level, giving the user output for that final page. So, for example, a user may ask for http:\/\/www.somesite.com\/widgets\/blue\/, but will really be given http:\/\/www.somesite.com\/widgets.php?colour=blue by the server.<\/p>\n<p>You can use mod_rewrite to redirect all pages to one central PHP page, which then loads the data [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/6995"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6995"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/6995\/revisions"}],"predecessor-version":[{"id":6996,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/6995\/revisions\/6996"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6995"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6995"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}