SEO-friendly URLs in PHP (5) w/o mod_rewrite

| Posted in Entdeckungen, Lesenswertes, Tips, Tutorials

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

Comments (3)

Are you sometimes bored? Looking sometimes out of the window and thinking about nothing just because you have thought about everything before? .. :D Go get a life

STFU! :P I like the explanation. Thanks again. :)

We have the same opinion.

Write a comment