Page 1 of 1

How can I simplify this URL rewriting code?

Posted: Sun Apr 29, 2012 12:59 am
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>

Re: How can I simplify this URL rewriting code?

Posted: Mon Apr 30, 2012 2:05 pm
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.

Re: How can I simplify this URL rewriting code?

Posted: Mon Apr 30, 2012 3:03 pm
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.