I showed Sebastian my little SEO-friendly PHP example, so why shouldn’t I share it with you people?

Many of you know one or more PHP frameworks like Zend, CakePHP or Symfony which provide SEO-friendy URLs via so called routing functions. Routing it is, because there is a centralized object instance, which delegates function calls to the appropiate class. Implementing this is quite easy with PHP 5 which provides autoloading of classes and (due to its typeless language structure) function loading on demand via “string” variables.

Lets start with a simple class named booking:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
class booking
{
	private $params;
 
	function __construct($params)
	{
		$this->params = $params;
		echo 'Constructor of class booking. <br />';
	}
 
	function sayHello()
	{
		echo 'Hello World in class booking. <br />';
		echo var_dump($this->params);
	}
}
?>

The real logic takes place in the class router, which explodes the request uri and resolves the classes/methods we want to call:

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
44
45
46
47
48
<?php
class router
{
	private $origUrl;
	private $controller;
	private $action;
	private $params;
 
	public function __construct($origUrl)
	{
		$this->origUrl = $origUrl;
		$this->extractController();
	}
 
	private function extractController()
	{
		$urlParts = explode('index.php', $this->origUrl);
		$mvcParts = explode('/', $urlParts[1]);
		$this->controller = $mvcParts[1];
		$this->action = $mvcParts[2];
		$this->params = $mvcParts[3];
	}
 
	public function connect()
	{
		$controller = $this->controller;
		$action = $this->action;
		$params = $this->params;
 
		if (class_exists($controller, true))
		{
			$controllerInstance = new $controller($params);
		}
		else
		{
			throw new Exception('There was no controller named ' . $controller);
		}
		if (method_exists($controllerInstance, $action))
		{
			$controllerInstance->$action();
		}
		else
		{
			throw new Exception('There was no action named ' . $action);
		}
	}
}
?>

This is our index.php which instantiates the router object:

1
2
3
4
5
6
7
<?php
 
require_once('config.inc.php');
 
$router = new router($_SERVER['REQUEST_URI']);
$router->connect();
?>

And a config.inc.php, which extends our include path for classes and defines the required autoload function:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
 
set_include_path(get_include_path() 
	. PATH_SEPARATOR 
	. dirname(__FILE__)
	. DIRECTORY_SEPARATOR
	. 'classes');
 
function __autoload($class_name)
{
	require_once $class_name . '.php';
}
?>

A call of index.php/booking/sayHello/123456 will result in the following output:

Constructor of class booking.
Hello World in class booking.
123456

Further explanation needed? Comment please :-)

PS: Attached example files as zip.
PPS: This is no production code!

example