How can I simplify this URL rewriting code?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Sindarin
Forum Regular
Posts: 521
Joined: Tue Sep 25, 2007 8:36 am
Location: Greece

How can I simplify this URL rewriting code?

Post by Sindarin »

So I've been trying to create proper URL rewriting managed by PHP and not in the htaccess.
So far I have this code which works but I'd like to simplify it.

What I mean this:

/news/3/1/

would map to:

/index.php?section=news&id=3&page=1

But for example I'd like to make the order of the query string items irrelevant, in case I have e.g.

/index.php?section=news&page=1&id=3

or simply not to have to define each query string parameter order myself.

index.php

Code: Select all

<?php

error_reporting(E_ERROR);

$url = 'http://localhost/url-rewrite/';
$url_rewriting_offset = 0;

/* Manage URL Rewriting Parameters for each Section */
if (isset($_REQUEST['url_params'])) {

	$url_rewriting_params = explode('/', trim($_SERVER['REDIRECT_URL'], '/'));
	
	$_REQUEST['section'] = $url_rewriting_params[1+$url_rewriting_offset];
	
	switch($url_rewriting_params[1+$url_rewriting_offset]) {
	
		case 'news':
			$_REQUEST['id'] = $url_rewriting_params[2+$url_rewriting_offset];
			//...
		break;
		
		case 'contact':
			$_REQUEST['action'] = $url_rewriting_params[2+$url_rewriting_offset];
			//...
		break;
		
		//...
	}
}

?>
<a href="<?php echo $url; ?>">Home</a> / <a href="<?php echo $url; ?>news/">News</a> / <a href="<?php echo $url; ?>contact/">Contact</a>
<br /><strong>
<?php

/* Load Views by Section */
switch($_REQUEST['section']) {

	case 'news':
		include('views/news.php');
	break;
	
	case 'contact':
		include('views/contact.php');
	break;
	
	case '':
		include('views/home.php');
	break;
	
	default:
		include('views/error.404.php');
}

echo '</strong><br />';

echo 'section ='.$_REQUEST['section'].'<br />';
echo 'action ='.$_REQUEST['action'].'<br />';
echo 'id ='.$_REQUEST['id'].'<br />';

?>
.htaccess

Code: Select all

<IfModule mod_rewrite.c>
	Options +FollowSymLinks
	RewriteEngine On
	
	RewriteCond %{REQUEST_FILENAME} !-l
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteRule .* index.php?url_params [L,QSA]
</IfModule>
User avatar
tr0gd0rr
Forum Contributor
Posts: 305
Joined: Thu May 11, 2006 8:58 pm
Location: Utah, USA

Re: How can I simplify this URL rewriting code?

Post by tr0gd0rr »

This is a very common task that is usually performed by an MVC library. Try a general function for parsing defined routes.

Here is my idea. The `$routes` array has keys that represent the view file to use; it has values that represent the names of the variables to save to $_GET and $_REQUEST.

Example usage: `getViewPath($routes, '/news/3/1');` returns 'views/news.php' and sets `$_GET['id'] = '3'` and `$_GET['page'] = '1'`.

Also, consider making a converse function that takes a view name and an associative array and returns a url. e.g. `url('news', array('id'=>3, 'page'=>1))` would return `"/news/3/1"`. That will reduce chance of error and allow you to change your routing scheme any time.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: How can I simplify this URL rewriting code?

Post by pickle »

Are you wanting to continue to do this in PHP, or are you looking for an .htaccess solution?

In order for the order of parameters to not matter, there can be no chance of collision. For example, what if you have a page with an ID 3, and an (I'm guessing article) id of 1? Either the order is significant, which is common practice and not bad at all, or you need to guarantee the separation by coming up with different tokens, ie: /news/page:1/id:3/, or news/p1/i3/ etc.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
Post Reply