How to serve files with mod rewrite

Have you ever wondered how some websites seem to serve files in a way that looks like folders instead of actual file names? For instance this website. To see this blog post you are linked to the URL http://adambecker.info/development/how-to-serve-files-with-mod-rewrite/ but in actuality the web server is running a PHP file and serving it as if it is being run from the location I just pasted.

Why do this? There are some good reasons for doing this:

  • You can make your URLs friendlier to the people who are visiting your website
  • Having friendlier URLs means easier to understand URLs for search engines, which is good for search engine optimization
  • Better security. With the way I’ve setup this model all of the server files are outside of the browse-able web directory, which means they can only be accessed through the index.php file.

Besides your normal code, you basically need two additional files: an .htaccess file and a redirection file which I’ve named index.php.

The .htaccess file lives in your root directory and should look something like this:

1
2
3
4
5
6
7
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

If you aren’t familiar with htaccess files, Google it and you will find some great information about them.

The index.php file also lives in the root directory and should look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
 
if(substr($_SERVER['REQUEST_URI'], 0, 10) == '/index.php'){
	header('Location:/');
}
else
{
	// due to mod_rewrite every path comes to this file
	$args = explode('/', $_SERVER['REDIRECT_URL']);
	$pages = array();
 
	// we're going to remove all of the empty arguments
	foreach($args as $arg)
	{
		if(strlen($arg) > 0)
		{
			$pages[] = $arg;
		}
	}
 
	// if we don't get any arguments we want to give it our main page
	if(count($pages) == 0)
	{
		$pages[] = 'main';	
	}
 
	// in this model the area's main page is named after the area
	if(count($pages) == 1)
	{
		$pages[] = $pages[0];
	}
 
	// in this model we can accept as many nested areas
	$includePath = '../lib/pages/' . implode('/', $pages) . '.php';
 
	if((@include $includePath) != true){
		if((@include '../lib/pages/error/404.php') != true){
			echo 'There was a serious error, and we\'re sorry for the inconvenence. Please try again soon.';
		}
	}
}
 
?>
Sample File Structure

Sample File Structure

The file is pretty self explanatory, but it is important to know that this isn’t the only way to do it. I’ve added some functionality for error 404 pages, and an even bigger fatal error. Last, I wanted to include a picture of a sample file structure that this particular example works for. Keep in mind that the htdocs directory is the only publicly browsable folder via a web browser in this sample.

Mac OS X: end and home keys

I have been using Macs over five years and it has always bothered me that the home and end keys didn’t do what they do on every other computer. For whatever reason, in Mac OS X, when you hit the home or end key your view of the text document is moved to the beginning or end respectively. This wouldn’t be an issue if every other computer hadn’t taught me that these keys are supposed to move me to the beginning and end of the line of text that I am on. I finally get annoyed enough to figure out the answer.

After a quick Google search I found the answer from a blog called Phatness. You can read the article here, but if you don’t want to read all the introduction over there, which was decently funny, here is what you do to fix it yourself:

1. Create a new file called DefaultKeyBinding.dict in the directory Users/%YOUR USERNAME%/Library/KeyBindings/
* Note: This folder won’t exist if you haven’t setup non-standard key bindings
2. Copy the following code into the file, and save the file
3. The new key bindings won’t take affect in any applications that are open without re-opening them

1
2
3
4
5
6
7
8
{
"\UF729"  = "moveToBeginningOfLine:";
"$\UF729" = "moveToBeginningOfLineAndModifySelection:";
"\UF72B"  = "moveToEndOfLine:";
"$\UF72B" = "moveToEndOfLineAndModifySelection:";
"\UF72C"  = "pageUp:";
"\UF72D"  = "pageDown:";
}

A nerd blog

There is no denying it, I am a big nerd. I play video games and I program for a living. I mean, I have my own domain name and that means something because I know some “nerds” that don’t have their own domain name.

I’ve decided that it is time to embrace my inner nerd and take it to the next level. If you’re interested in web development, gaming, and other nerdy adventures stay tuned! I am very much interested in what the viewers think, so please comment and I look forward to start writing dome good entries very soon.