PHP Code:
class Route {
const URL_VARIABLE = ':';
const REGEX_DELIMITER = '#';
const DEFAULT_REGEX = '[a-z0-9\-_]+';
private $parts;
private $defaults = array();
private $required = array();
public function __construct( $route, $defaults = array(), $required = array() ) {
$route = trim( $route, '/' );
$this -> defaults = array_merge( $this -> defaults, $defaults );
$this -> required = array_merge( $this -> required, $required );
foreach( explode( '/', $route ) as $position => $part ) {
if( self::URL_VARIABLE == $part[0] ) {
$name = substr( $part, 0 );
// added fix here
// removes : from string, ie
// :controller, :action, et al becomes controller, action, et al
$realname = substr( $name, 1 );
// following statement uses $realname instead of originally using $name
// 13 apr 2006 les quinn
$regex = isset( $required[$realname] )? $required[$realname]: self::DEFAULT_REGEX;
$this -> parts[$position] = array( 'name' => $name, 'regex' => $regex );
} else {
$this -> parts[$position] = array( 'regex' => preg_quote( $part, self::REGEX_DELIMITER ) );
}
}
}
public function match( $path ) {
$values = $this -> defaults;
$path = explode( '/', trim( $path, '/' ) );
foreach( $this -> parts as $position => $part ) {
$name = isset( $part['name'] )? $part['name']:null;
$regex = self::REGEX_DELIMITER.'^'.$part['regex'].'$'.self::REGEX_DELIMITER.'i';
// added fix here
$realname = substr( $name, 1 );
if( !empty( $path[$position] ) && preg_match( $regex, $path[$position] ) ) {
if( !is_null( $name ) ) {
// following statement(s) uses $realname instead of originally using $name
// 13 apr 2006 les quinn
$values[$realname] = $path[$position];
}
} else if( !is_null( $name ) && isset( $this -> defaults[$realname] ) ) {
continue;
} else {
return false;
}
}
return $values;
}
public function assemble( $data ) {
// ... not got around to this yet ;)
}
}
class Router {
private $routes = array();
public function __construct() {}
public function addRoute( $map, $defaults = array(), $required = array() ) {
$this -> routes[] = new Route( $map, $defaults, $required );
}
public function route() {
$path = $_SERVER['REQUEST_URI'];
if( strstr( $path, '?' ) ) {
$path = substr( $path, 0, strpos( $path, '?' ) );
}
foreach( $this -> routes as $route ) {
if( $parameters = $route -> match( $path ) ) {
return $parameters;
// break;
}
}
return array();
}
}
$router = new Router();
// archives is static parameter and is the controller portion of the url
$router -> addRoute( 'archives/:action/date/:yrs/:mth/:day',
array( 'action' => 'tmp_action_index', 'yrs' => '2006', 'mth' => '1', 'day' => '1' ),
array( 'action' => '[a-z]+', 'yrs' => '[0-9]{4}', 'mth' => '[0-9]{2}', 'day' => '[0-9]{2}' ) );
// controller, action with static parameter (category), with additional (may be optional) parameter
$router -> addRoute( ':controller/:action/category/:category',
// defaults are used where there are no matched parameter in url
array( 'controller' => 'index', 'action' => 'index', 'category' => 'home' ),
// requires are to determine the matched parameter from url validates against a given regex
// if no regex given for a specific parameter in this array, a default regex is used instead, ie
// the default regex ([a-z0-9\-_]+) will be used to validate the category parameter
array( 'controller' => '[a-z]+', 'action' => '[a-z]+' ) );
// controller, action, with static parameter (date), with additional (may be optional) parameters
$router -> addRoute( ':controller/:action/date/:yrs/:mth/:day',
// uses defaults for year, month and day
// would use php's date functions to set defaults to current date
array( 'controller' => 'index', 'action' => 'index', 'yrs' => '2006', 'mth' => '1', 'day' => '1' ),
// only specify the requires where the regex is different from the default regex
array( 'controller' => '[a-z]+', 'action' => '[a-z]+', 'yrs' => '[0-9]{4}', 'mth' => '[0-9]{2}', 'day' => '[0-9]{2}' ) );
// controller, action and an id only
$router -> addRoute( ':controller/:action/id/:id',
array( 'controller' => 'index', 'action' => 'index', 'id' => '' ),
array( 'controller' => '[a-z]+', 'action' => '[a-z]+', 'id' => '[0-9]+' ) );
// default route
// controller and action only
$router -> addRoute( ':controller/:action',
array( 'controller' => 'controller_index', 'action' => 'action_index' ),
array( 'controller' => '[a-z]+', 'action' => '[a-z]+' ) );
$rs = $router -> route();
Hope this is of some use anyways, it's helped me to understand it some more anyways.
Bookmarks