您可以實現子模塊與ZF相對較少的努力。比方說,你有目錄結構如:
application/
modules/
admin/
cms/
controllers/
views/
controllers/
views/
你會這樣註冊模塊在引導文件(子模塊使用_從主模塊的子模塊分開):
$frontController->setControllerDirectory(array(
'default' => APPLICATION_PATH . '/modules/default/controllers',
'admin' => APPLICATION_PATH . '/modules/admin/controllers',
'admin_cms' => APPLICATION_PATH . '/modules/admin/cms/controllers'
));
問題在於它實際上會在URL中使用下劃線而不是斜槓,例如:「admin_cms/conteroller/action」而不是「admin/cms/controller/action」。雖然這個「有效」,但並不漂亮。解決問題的一種方法是爲默認路線提供您自己的路線。由於默認一個Zend_Controller_Router_Route_Module做它幾乎正確的,你可以簡單地從它延伸並添加想要的行爲:
<?php
class App_Router_Route_Module extends Zend_Controller_Router_Route_Module
{
public function __construct()
{
$frontController = Zend_Controller_Front::getInstance();
$dispatcher = $frontController->getDispatcher();
$request = $frontController->getRequest();
parent::__construct(array(), $dispatcher, $request);
}
public function match($path)
{
// Get front controller instance
$frontController = Zend_Controller_Front::getInstance();
// Parse path parts
$parts = explode('/', $path);
// Get all registered modules
$modules = $frontController->getControllerDirectory();
// Check if we're in default module
if (count($parts) == 0 || !isset($modules[$parts[0]]))
array_unshift($parts, $frontController->getDefaultModule());
// Module name
$module = $parts[0];
// While there are more parts to parse
while (isset($parts[1])) {
// Construct new module name
$module .= '_' . $parts[1];
// If module doesn't exist, stop processing
if (!isset($modules[$module]))
break;
// Replace the parts with the new module name
array_splice($parts, 0, 2, $module);
}
// Put path back together
$path = implode('/', $parts);
// Let Zend's module router deal with the rest
return parent::match($path);
}
}
而在你的引導:
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('default', new App_Router_Route_Module);
這樣做是遍歷路徑只要它找到一個模塊,並且透明地重寫路徑,以便默認的Zend_Controller_Router_Route_Module可以完成真正的工作。例如下面的路徑:「/ admin/cms/article/edit」將被轉換爲「/ admin_cms/article/edit」,它允許ZF的「:module /:controller /:action」的標準約定做到神奇。
這可以讓你有獨立模塊很好的模塊化結構,同時還使用漂亮,邏輯的URL。你想一兩件事,使值得注意的是,如果你使用Zend_Navigation和使用模塊/控制器/動作參數指定的導航項目,你需要告訴ZF如何使用正確生成URL「/」,而不是「_」,在模塊名稱(默認情況下,ZF在構建URL時使用:module /:controller /:action spec)。您可以通過實現自己的Zend_Controller_Action_Helper_Url,這樣做:
<?php
class App_Router_Helper_Url extends Zend_Controller_Action_Helper_Url
{
public function url($urlOptions = array(), $name = null, $reset = false, $encode = false)
{
// Replace the _ with/in the module name
$urlOptions['module'] = str_replace('_', '/', $urlOptions['module']);
// Let the router do rest of the work
return $this->getFrontController()->getRouter()->assemble($urlOptions, $name, $reset, $encode);
}
}
而在你的引導:
Zend_Controller_Action_HelperBroker::addHelper(new App_Router_Helper_Url);
現在Zend_Navigation與子模塊的支持很好地工作爲好。
Tkanks,這也是我的印象 – 2009-10-28 12:56:16