I started off with a simple dispatch class, but it's grown and I'm sure it could be simplified in the very least. In fact, I'm doing way too much in the __construct() method
It it being called as such:
$router = new router($_SERVER['REQUEST_URI'], $database);
$router->dispatch();
Yep, I'm pushing my database object into it.
Here's the class:
class router {
/**
* @var array Request URL
* @var array|string Controller Class Name
* @var array|string Method Name
* @var array|string Parameters
* @var array|bool|string Route Validity
* @var array|bool|string Primary Source
* @var \Zend\Db\Adapter\Adapter Database Adapter
*/
protected $url,
$controller,
$method,
$params,
$validRoute,
$primary,
$database;
/**
* Constructs the router class with routing paramters
* and database to inject into dispatched controller.
* Construct also sets the appropriate controller, method
* based in routing params, then checks if route is valid.
* @param $params
* @param $database
*/
public function __construct($params, \Zend\Db\Adapter\Adapter $database)
{
$this->database = $database;
$this->url = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
$this->validRoute = true;
$requestParams = $_REQUEST;
unset($requestParams['url']);
$this->controller = !empty($this->url[0]) ? 'controller\\' . $this->url[0] : 'controller\\home';
if ($this->url[0] != 'ajax') {
$this->method = !empty($this->url[1]) ? $this->url[1] . "View" : 'indexView';
$this->params = !empty($this->url[2]) ? $_REQUEST : $_REQUEST;
$GLOBALS['url'] = array();
$GLOBALS['url'][] = !empty($this->url[0]) ? $this->url[0] : 'home';
$GLOBALS['url'][] = !empty($this->url[1]) ? $this->url[1] : '';
$GLOBALS['url'][] = !empty($this->url[2]) ? $this->url[2] : '';
} else {
$this->controller = 'catalina\\ajax';
$this->method = 'handleRequest';
$this->params = array (
'url' => $this->url,
'controller' => !empty($this->url[1])
? 'controller\\' . $this->url[1] : 'controller\\home',
'method' => !empty($this->url[2]) ? $this->url[2] . "Ajax" : '',
'params' => $requestParams,
'database' => $this->database,
);
$this->primary = 'ajax';
}
return self::checkRoute();
}
/**
* Checks to see if a given route is valid
* @return bool
*/
private function checkRoute()
{
if ($this->controller != 'controller\ajax') {
if (preg_match("#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*#", $this->controller)) {
try {
class_exists($this->controller);
} catch (Exception $e) {
$error = new ErrorHandler($this->database);
$error->invalidDispatch(debug_backtrace(), $this->controller);
$this->validRoute = false;
return false;
}
$reflection = new \ReflectionClass($this->controller);
if (!class_exists($this->controller) || (!($reflection->hasMethod($this->method)))) {
$error = new ErrorHandler($this->database);
$error->invalidDispatch(debug_backtrace(), $this->controller, $this->method);
$this->validRoute = false;
return false;
}
} else {
$error = new ErrorHandler($this->database);
$error->invalidDispatch(debug_backtrace(), $this->controller);
$this->validRoute = false;
}
}
return true;
}
/**
* Dispatches the route to the requested controller
* and method.
* @return bool
*/
public function dispatch()
{
if ($this->validRoute == true) {
$dispatchedController = new $this->controller($this->database);
$method = $this->method;
return $dispatchedController->$method($this->params);
} else {
return false;
}
}
}