Skip to content
Snippets Groups Projects
Commit 6c8b446f authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Added Router class.

parent 1dee302c
No related branches found
No related tags found
No related merge requests found
<?php
/**
* Functions for URL routing: given an URL, call the corresponding handler
* function (the 'route' to the corresponding output).
*
* @author Taddeus Kroes
* @version 1.0
* @date 14-07-2012
*/
namespace BasicWeb;
require_once 'base.php';
/**
*
*
* <code>
*
* </code>
*
* @package BasicWeb
*/
class Router extends Base {
/**
* The regex delimiter that is added to the begin and end of patterns.
*
* @var string
*/
const DELIMITER = '%';
/**
* An associative array of regex patterns pointing to handler functions.
*
* @var array
*/
private $routes = array();
/**
* Create a new Router instance.
*
* @param array $routes An initial list of routes to set.
*/
function __construct(array $routes=array()) {
foreach( $routes as $pattern => $handler )
$this->add_route($pattern, $handler);
}
/**
* Add a route as a (pattern, handler) pair.
*
* The pattern is regular expression pattern without delimiters. The
* function adds '%^' at the begin and '$%' at the end of the pattern as
* delimiters.
*
* The handler function must receive no arguments if the regex pattern
* does not contain groups (which are contained in parentheses). If there
* are groups, the matches for these are passed to the handler fucntion in
* an array.
*
* @param string $pattern A regex pattern to mach URL's against.
* @param mixed $handler The handler function to call when $pattern is matched.
* @throws \InvalidArgumentException If $handler is not callable.
*/
function add_route($pattern, $handler) {
if( !is_callable($handler) )
throw new \InvalidArgumentException(sprintf('Handler for patterns "%s" is not callable.', $pattern));
$this->routes[self::DELIMITER.'^'.$pattern.'$'.self::DELIMITER] = $handler;
}
/**
* Call the handler function corresponding to the specified url.
*
* If any groups are in the matched regex pattern, a list of matches is
* passed to the handler function.
*
* @param string $url An url to match the saved patterns against.
* @return mixed FALSE if no pattern was matched, the return value of the
* corresponding handler function otherwise.
*/
function call_handler($url) {
foreach( $this->routes as $pattern => $handler ) {
if( preg_match($pattern, $url, $matches) ) {
array_shift($matches);
return call_user_func_array($handler, $matches);
}
}
return false;
}
}
?>
\ No newline at end of file
<?php
require_once 'router.php';
use BasicWeb\Router;
function test_handler_no_args() {
return true;
}
function test_handler_arg($arg) {
return $arg;
}
function test_handler_args($arg0, $arg1) {
return $arg1.$arg0;
}
class RouterTest extends PHPUnit_Framework_TestCase {
function setUp() {
$this->router = new Router(array(
'foo' => 'test_handler_no_args',
'(ba[rz])' => 'test_handler_arg',
'(ba[rz])(ba[rz])' => 'test_handler_args',
));
}
function test_call_handler_success() {
$this->assertEquals($this->router->call_handler('foo'), true);
$this->assertEquals($this->router->call_handler('bar'), 'bar');
$this->assertEquals($this->router->call_handler('baz'), 'baz');
$this->assertEquals($this->router->call_handler('bazbar'), 'barbaz');
}
function test_call_handler_failure() {
$this->assertFalse($this->router->call_handler('barfoo'));
}
function test_add_route() {
$this->router->add_route('(foobar)', 'test_handler_arg');
$this->assertEquals($this->router->call_handler('foobar'), 'foobar');
}
}
?>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment