Go Back   CodingForums.com > :: Server side development > Apache configuration

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-22-2011, 03:54 AM   PM User | #1
ShaneC
Codeasaurus Rex


 
Join Date: Jun 2008
Location: Redmond, WA
Posts: 659
Thanks: 31
Thanked 100 Times in 94 Posts
ShaneC is on a distinguished road
Exclamation Mod_Rewrite How-To Guide

Apache's Mod_Rewrite How-To Guide

Helpful Resources
Editorial Note: If you find anything in this guide that is incorrect, or would like content added, please Send a PM to ShaneC. Mod_Rewrite questions should be posted in the Apache Configuration forum.

Note: Guide Assumptions

This guide assumes that you're using the following:
  • Apache 1.3 or later
  • PHP
  • Apache's Mod_Rewrite Module enabled on your server

Important: Make sure Mod_Rewrite is Installed and Enabled

On some web hosts Mod_Rewrite is not enabled by default.

To check if mod_rewrite is installed:

Note: In most PHP configurations you can detect if Mod_Rewrite is installed with the method below. If, however, you're using CGI / SuPHP you will have to check the Apache httpd.conf file manually.

Create a PHP page on your web server. For demonstration purposes, call this page phpinfo.php. This file should read as follows:

PHP Code:
<?php phpinfo(); ?>
Now, navigate to this page in your browser and look under the Loaded Modules section. This can be located using Ctrl+F in your browser. In this list try and locate mod_rewrite. If it is listed here, you're good to go. If not, you'll need to enable it.

To enable it, you need to locate Apache's configuration file. This file is called httpd.conf.

Note: If you're on a shared host and don't have access to the httpd.conf file for the Apache Server you will need to contact your web host and request they enable the mod_rewrite module.

Once you've located httpd.conf open it and search for the following line. Ensure it is not commented out by removing a # symbol if it is in front of the line:

Enabled: LoadModule rewrite_module modules/mod_rewrite.so

Disabled: #LoadModule rewrite_module modules/mod_rewrite.so

Once you've enabled the line you will need to restart your Apache server in order for it to take effect.


Understanding what Mod Rewrite does

Mod_Rewrite is the process of converting from URLs filled with variables to clean URLs:

URL Before Re-write: http://mydomain.com/index.php?page=search&type=post

URL After Re-write: http://mydomain.com/search/post

Benefits:
  • Search engine friendly
  • Easy for users to read
  • Protects details of how your web application is implemented

The Server (aka Apache) doesn't understand http://mydomain.com/page/about-us/27. To that it will understand it as folders and sub-directories.

Essentially what you are doing is making it so all the links the user sees are the nice, clean ones. The only time the long index.php?p=about...etc. links appear are internally to apache - never seen by the user.


Setting up the Rewrite

Create a file, if there isn't already, in the root of your web directory (/) that is called .htaccess. This is the file that will control the rewrite rules.

For this example, this is how the final .htaccess file will look:
Code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /

RewriteRule ^news/(.*)$ news.php?article_id=$1 [L]
This will allow us to enter this URL into the address bar: http://mydomain.com/news/357 and have Apache process it like this: http://mydomain.com/news.php?article_id=357.

The First Part : Start the engine
Code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
This tells Apache we will be using the Mod Rewrite functionality and enables it at the base of the web root.

You should place this above your rewrite rules every time you use Mod_Rewrite.

The two Options lines at the start are optional, assuming they are already set as such in your httpd.conf file. If you're not sure if your httpd.conf file is set to allow these methods, or you know they aren't included, then include them here in your .htaccess.

The Second Part : Rules to live by

Rewrite Rules are created using Regular Expressions. They tell Apache under what patterns certain actions should be performed.

We will go in depth on them in the next section.


Rewrite Rules: Tell Apache what to do

Rewrite rules take the following format:
Code:
RewriteRule ^{REGEX_PATTERN}$ {PAGE_ADDRESS}{PATTERN_MATCH} [FLAGS]
REGEX_PATTERN

For simplicity sake, this guide assumes you already have a good working knowledge of REGEX. If you don't, I highly recommend you read about Regular Expressions (REGEX) and how to create them. You can also download The Regex Coach for testing your REGEX and seeing if it will match the patterns you'd like it to.

The REGEX Pattern is the Regular Expression string that apache will try to match every time a user types in a URL on your domain. If it matches this expression, then the RewriteRule is followed.

PAGE_ADDRESS

Your page address is exactly that, the actual literal path of the target page on your server.

For example, let's take our earlier instance. I want to be able to type in http://mysite.com/news/NEWS_ID and have my news page process it. Obviously, I don't have all these fancy directories set up to accomodate this. My news page is actually called news.php and is located in the web root (/).

The PAGE_ADDRESS in this example would then be news.php?news_id=, assuming the variable I want to pass into the PHP script from the URL is news_id. It could just as easily be newsID or omgTheNews.

I would then evaluate this in my news.php script as:

PHP Code:
<?php

echo( "The News ID you've specified is: " $_REQUEST['news_id'] );
exit();

?>
PATTERN_MATCH

In REGEX, pattern matches are reported as $n, where N is the number of the match.

For example, lets say I have a Regular expression like this:

Code:
^search/(.*)/(.*)/apples/(.*)/oranges/(.*)$
If I then typed in the URL: http://mydomain.com/search/OMG/THIS/apples/IS/oranges/COOL

REGEX would report the following matches:

$1 = "OMG"
$2 = "THIS"
$3 = "IS"
$4 = "COOL"

In summary:

(.*) - This is REGEX essentially meaning that it accepts any character into that spot within the link
$1... $2... $n - This signals the REGEX expression you are relating to. So the first instance of (.*) is $1, the second instance is $2, and so on.

TYING THIS TOGETHER:

Let's say I wanted to use the Regular Expression I just specified (^search/(.*)/(.*)/apples/(.*)/oranges/(.*)$) in my website and I wanted it to redirect to a search.php. In search.php, though, I only want the fourth match set as the search ID.

This would be my RewriteRule:
Code:
RewriteRule ^search/(.*)/(.*)/apples/(.*)/oranges/(.*)$ search.php?search_id=$4 [L]
We will address what the L means in the upcoming section.

If I were to now proceed to the web address http://mydomain.com/search/OMG/THIS/apples/IS/oranges/COOL search.php would be passed the variable search_id with a value of "COOL".


Rewrite Rules: Flag them down

Flags are your way of further customizing what your RewriteRules do. There are many different flags available, see the Mod Rewrite Cheat Sheet for a detailed listing, but we'll only cover the common ones here.

[L] - Last
If this has been applied to a Rule then the Rewrite Engine will stop executing any remaining rules that follow.

[R] - Redirect
This will execute a redirect and send a status code as well as the new location to the user's browser. This will then cause the client browser to update the address bar with the new destination. This flag can, optionally, take in a status code by invoking it as such R=301, where 301 can be any valid Redirection Status Code.

[QSA] - Query String Append
On dynamic pages the query string contains GET data (ie. everything after the ?). If you do not include a query string in the destination then the original query is automatically transferred. If you do specify a query string destination then this overwrites the original. If you wish to add to the query string and keep original data intact, you must use the QSA flag.

[NC] - No Case
Makes the comparison case insensitive

INVOKING FLAGS

Invoking flags is done easily. Simply encase them in square brackets ("[" and "]") and separate them by a comma.

For example, if I wanted to apply a Last and No Case flag to a rule:
[L,NC]


Extra Learning and Reference

For a more detailed tutorial, complete with more examples, see the Easy Mod Rewrite Guide.

Moreover, if you have any questions then you're at the right place! Simply start a topic stating your problem/question and we'll do our best to help. Please try to be as clear as possible, and post all relevant lines of your code as well as your .htaccess file.



Good Luck!
__________________
Unless otherwise stated, any code posted is most likely untested and may contain syntax errors.
My posts, comments, code, and suggestions reflect only my personal views.
Web Portfolio and Code Snippets: http://shanechism.com

Last edited by ShaneC; 01-22-2011 at 07:21 PM..
ShaneC is offline   Reply With Quote
Old 11-20-2012, 04:37 AM   PM User | #2
stevenmw
Regular Coder

 
stevenmw's Avatar
 
Join Date: Jun 2007
Location: OK
Posts: 449
Thanks: 26
Thanked 30 Times in 30 Posts
stevenmw is an unknown quantity at this point
Often times I come across the same questions asked in this part of the forum. I thought it might be a good reference to have these answers in one location.

Hide file Extension

This will hide specified file extensions from files. The below code will hide .php extensions.

So in order to go to
http://www.this.com/that.php

You could type
http://www.this.com/that

Code:
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule .* $0.php
Change both instances of .php to something else if you want to hide another extension.

Password Protect a Directory
This requires two files, .htaccess and .htpasswd

.htaccess
Code:
AuthUserFile /home/.htpasswd 
AuthName "Super Secret Directory" 
AuthType Basic 
require user username
The last line gives access to a specific user. Simply change username to whatever you want.

If you want to give access to everyone in the .htpasswd file add this line
Code:
require valid-user
Everything else should be straight forward

AuthUserFile - path to .htpasswd (this file contains usernames and paswords)

AuthName - is the name displayed when logging into the directory

AuthType - basic authentication allows the use restrict access by looking up users in plain text password files (plain text pass files are very dangerous!)

.htpasswd
this file have lines that look like
Code:
username:encryptedpassword
Each line is one username and that user's password.

The password is displayed in an encrypted format. The password encryption is the same as PHP's crypt() function. It is not reversible.

An example would be
Code:
steven:yH974afpUXC72
There are numerous password encryption tools online.

Last edited by stevenmw; 11-20-2012 at 04:43 AM..
stevenmw is offline   Reply With Quote
Old 01-17-2013, 03:55 PM   PM User | #3
sunilmkt
New Coder

 
Join Date: Jan 2013
Location: India
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
sunilmkt can only hope to improve
Good tutorials for mod rewrite, could you suggest me guideline for window IIS server?. I found very hard in case of windows IIS server. Thanks
sunilmkt is offline   Reply With Quote
Old 05-18-2013, 06:34 PM   PM User | #4
wlf
New Coder

 
Join Date: Aug 2012
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
wlf is an unknown quantity at this point
Nice howto ShaneC.

When running your own server (vps/dedicated) you can use the following commands to check whether mod rewrite is on or off.

This will output the list of loaded modules (static & dynamic)
httpd -M

This will output the list of loaded modules (doesn't include dynamic ones included using LoadModule directive)
httpd -l
__________________
A good programmer is someone who looks both ways before crossing a one-way street. Free hosting
wlf is offline   Reply With Quote
Old 05-18-2013, 11:19 PM   PM User | #5
stevenmw
Regular Coder

 
stevenmw's Avatar
 
Join Date: Jun 2007
Location: OK
Posts: 449
Thanks: 26
Thanked 30 Times in 30 Posts
stevenmw is an unknown quantity at this point
Quote:
Originally Posted by wlf View Post
Nice howto ShaneC.

When running your own server (vps/dedicated) you can use the following commands to check whether mod rewrite is on or off.

This will output the list of loaded modules (static & dynamic)
httpd -M

This will output the list of loaded modules (doesn't include dynamic ones included using LoadModule directive)
httpd -l
Some distros will not recognize the httpd package name. Just keep that in mind.
__________________
--
Thanks!
stevenmw is offline   Reply With Quote
Old 06-14-2013, 10:03 PM   PM User | #6
riauhost
New to the CF scene

 
Join Date: Jun 2013
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
riauhost is an unknown quantity at this point
Good tutorials for mod rewrite

Thanks
riauhost is offline   Reply With Quote
Reply

Bookmarks

Tags
apache, flags, guide, mod_rewrite, redirect, regular expressions, tutorial

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:54 AM.


Advertisement
Log in to turn off these ads.