Essential Zend Controller (3)

3. Zend Controller之Router
[English Version]

Router的核心工作非常简单. 便是从请求的参数中为Zend_Controller_Front产生Zend_Controller_Dispatcher_Token. Zend Framework默认的Router是通过解析请求的URI来处理的. 如http://your.com/test/add会被解析成一个叫”TestController”的Controller和controller中一个叫”addAction”的方法. controller信息和action信息及其他参数将被封装成Zend_Controller_Dispatcher_Token.
在我们知道原理以后, 我们可以非常轻松的写我们所需要的router. 如, 当我们的web server不支持url_rewriter的时候我们需要一个NoRewriterRouter. 而当我们在一个虚拟主机的子目录里, 那么我们可能需要一个SubDirectoryRouter..

在diggmore的开发过程中, 我写了一个SubDirectoryRouter. 和最初在maillist里流传的稍有不同, 稍微严谨一些.

/**
*
* Sub Directory Router for diggmore
*
*/
class SubDirectoryRouter implements Zend_Controller_Router_Interface
{
//

private $sub_directory;

public function setSubDirectory($sub_directory)
{
$this->sub_directory = $sub_directory;
return $this;
}

public function route(Zend_Controller_Dispatcher_Interface $dispatcher)
{
//
$path = $_SERVER[’REQUEST_URI’];
if (strstr($path, ‘?’)) {
$path = substr($path, 0, strpos($path, ‘?’));
}
$path = explode(’/', trim($path, ‘/’));

$start = 2;

if ($this->sub_directory != ”)
{
//
$tmp = explode(’/', trim($this->sub_directory, ‘/’));
$start = sizeof($tmp) + 2;
}
$controller = $path[$start-2];
$action = isset($path[$start-1]) ? $path[$start-1] : null;

$params = array();
for ($i=$start; $i $params[$path[$i]] = isset($path[$i+1]) ? $path[$i+1] : null;
}

$token = new Zend_Controller_Dispatcher_Token($controller, $action, $params);

if (!$dispatcher->isDispatchable($token)) {
throw new Zend_Controller_Router_Exception(’Request could not be mapped to a route.’);
} else {
return $token;
}

}

}

如果你的web server不支持url_writer, 那么你可以尝试使用下面的代码.

class NoRewriterRouter implements Zend_Controller_Router_Interface
{
//

public function route(Zend_Controller_Dispatcher_Interface $dispatcher)
{
//

$params = array_merge($_GET, $_POST);

$controller = $params[’controller’];
$action = $params[’action’];

unset($params[’controller’]);
unset($params[’action’]);

$token = new Zend_Controller_Dispatcher_Token($controller, $action, $params);

if (!$dispatcher->isDispatchable($token)) {
throw new Zend_Controller_Router_Exception(’Request could not be mapped to a route.’);
} else {
return $token;
}

}

}

你也许想在router里加上权限控制的代码, 但我并不认为这是个好主意. 接下来我会说明diggmore是如何做权限控制的.

Related Posts

One Response to “Essential Zend Controller (3)”

Leave a Reply