使用前缀和 Zend_Controller_Router_Route
Working with prefixes and Zend_Controller_Router_Route
在现有的 Zend Framework 网站上,控制器很少且没有模块,我需要为默认路由添加一些前缀。
例如,我目前有:
/products
/products/id/1
/training
/commonpage
我想添加一个产品线级别,而不是在 x 模块中复制我的控制器(我只需要使用 _getParam
在我的控制器中请求正确的产品线)。
所以我的新路径是:
/line1/products
/line1/products/id/1
/line2/training
/commonpage
到目前为止我尝试的是这条路线(位于我的 Bootstrap 文件中):
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('productLineRoute', new Zend_Controller_Router_Route(
':line/:controller/:action',
array('module' => 'default'),
array('line' => '(' . implode('|', Zend_Registry::getInstance()->constants->lines) . ')')
));
}
但是没有任何成功(它给了我一个 404)。
在这些条件下,如何构建匹配所有 uri 的单一路由:
- uri 的前缀匹配我的产品线数组中的一个值
- 仅当允许在 "product line way" 中访问所请求的控制器时,路由才有效 - 例如通过包含我的控制器名称的数组
更新
好的,我已经非常接近于使用此代码尝试执行的操作了:
protected function _initConstants()
{
$registry = Zend_Registry::getInstance();
$registry->constants = new Zend_Config( $this->getApplication()->getOption('constants') );
$uri = ltrim($_SERVER['REQUEST_URI'], '/');
$product_line = substr($uri, 0, strpos($uri, '/'));
if(!empty($product_line) && in_array($product_line, Zend_Registry::getInstance()->constants->lines->toArray()) &&
$product_line != Zend_Registry::getInstance()->constants->lines->get(0)) {
$registry->product_line = $product_line;
} elseif(!isset($registry->gamme)) {
$registry->product_line = Zend_Registry::getInstance()->constants->lines->get(0);
}
}
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$registry = Zend_Registry::getInstance();
$router->addRoute('productLineRoute', new Zend_Controller_Router_Route(
':line/:controller/:action/*',
array(
'module' => 'default', 'action' => 'index',
'line' => (isset($registry->product_line)) ? $registry->product_line : Zend_Registry::getInstance()->constants->lines->get(0)
),
array(
'line' => '(' . implode('|', Zend_Registry::getInstance()->constants->lines->toArray()) . ')',
'controller' => '(' . implode('|', array('products', 'training')) . ')'
)
));
}
有了它我可以访问 /line1/products
但不能访问 /line1/commonpage
,这正是我想要的 - 所以控制器约束工作得很好。如您所见,我在 Zend Registry 中添加了产品线名称,因此当我在模板中使用 URL View Helper 时它会被保存(这样我就不必编辑所有模板来添加产品线我的助手调用中的参数)。
我现在遇到的问题是这个助手:似乎我的控制器约束被忽略了。当我在我的模板中这样做时:
<a href="<?php echo $this->url(array('controller'=> 'commonpage', 'action'=>'index'),null, true) ; ?>">My link</a>
我最终得到了这个:
<a href="/line1/commonpage">My link</a>
所以添加了产品线,尽管我的路线的控制器约束不允许这样做。
您可以使用 ini 参数文件添加/修改特定路由:
resources.router.routes.job_en.route = "/prefix/:request-offer"
resources.router.routes.job_en.defaults.module = "core"
resources.router.routes.job_en.defaults.controller = "engine"
resources.router.routes.job_en.defaults.action = "main"
其中 job_en
是我的路由名称,request-offer
是参数名称
好的,我找到了一个解决方案:我更改了 URL 助手以在其中添加控制器约束。如果控制器与 "product lines controllers" 数组不匹配,它会强制 assemble
使用默认路由(不完美,但对我有用):
public function url(array $urlOptions = array(), $name = null, $reset = false, $encode = true, $default = false)
{
$router = Zend_Controller_Front::getInstance()->getRouter();
if(isset($urlOptions['controller']) && !in_array($urlOptions['controller'], array('products', 'training'))) {
$name = 'default';
}
return $router->assemble($urlOptions, $name, $reset, $encode);
}
在现有的 Zend Framework 网站上,控制器很少且没有模块,我需要为默认路由添加一些前缀。
例如,我目前有:
/products
/products/id/1
/training
/commonpage
我想添加一个产品线级别,而不是在 x 模块中复制我的控制器(我只需要使用 _getParam
在我的控制器中请求正确的产品线)。
所以我的新路径是:
/line1/products
/line1/products/id/1
/line2/training
/commonpage
到目前为止我尝试的是这条路线(位于我的 Bootstrap 文件中):
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('productLineRoute', new Zend_Controller_Router_Route(
':line/:controller/:action',
array('module' => 'default'),
array('line' => '(' . implode('|', Zend_Registry::getInstance()->constants->lines) . ')')
));
}
但是没有任何成功(它给了我一个 404)。 在这些条件下,如何构建匹配所有 uri 的单一路由:
- uri 的前缀匹配我的产品线数组中的一个值
- 仅当允许在 "product line way" 中访问所请求的控制器时,路由才有效 - 例如通过包含我的控制器名称的数组
更新
好的,我已经非常接近于使用此代码尝试执行的操作了:
protected function _initConstants()
{
$registry = Zend_Registry::getInstance();
$registry->constants = new Zend_Config( $this->getApplication()->getOption('constants') );
$uri = ltrim($_SERVER['REQUEST_URI'], '/');
$product_line = substr($uri, 0, strpos($uri, '/'));
if(!empty($product_line) && in_array($product_line, Zend_Registry::getInstance()->constants->lines->toArray()) &&
$product_line != Zend_Registry::getInstance()->constants->lines->get(0)) {
$registry->product_line = $product_line;
} elseif(!isset($registry->gamme)) {
$registry->product_line = Zend_Registry::getInstance()->constants->lines->get(0);
}
}
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$registry = Zend_Registry::getInstance();
$router->addRoute('productLineRoute', new Zend_Controller_Router_Route(
':line/:controller/:action/*',
array(
'module' => 'default', 'action' => 'index',
'line' => (isset($registry->product_line)) ? $registry->product_line : Zend_Registry::getInstance()->constants->lines->get(0)
),
array(
'line' => '(' . implode('|', Zend_Registry::getInstance()->constants->lines->toArray()) . ')',
'controller' => '(' . implode('|', array('products', 'training')) . ')'
)
));
}
有了它我可以访问 /line1/products
但不能访问 /line1/commonpage
,这正是我想要的 - 所以控制器约束工作得很好。如您所见,我在 Zend Registry 中添加了产品线名称,因此当我在模板中使用 URL View Helper 时它会被保存(这样我就不必编辑所有模板来添加产品线我的助手调用中的参数)。
我现在遇到的问题是这个助手:似乎我的控制器约束被忽略了。当我在我的模板中这样做时:
<a href="<?php echo $this->url(array('controller'=> 'commonpage', 'action'=>'index'),null, true) ; ?>">My link</a>
我最终得到了这个:
<a href="/line1/commonpage">My link</a>
所以添加了产品线,尽管我的路线的控制器约束不允许这样做。
您可以使用 ini 参数文件添加/修改特定路由:
resources.router.routes.job_en.route = "/prefix/:request-offer"
resources.router.routes.job_en.defaults.module = "core"
resources.router.routes.job_en.defaults.controller = "engine"
resources.router.routes.job_en.defaults.action = "main"
其中 job_en
是我的路由名称,request-offer
是参数名称
好的,我找到了一个解决方案:我更改了 URL 助手以在其中添加控制器约束。如果控制器与 "product lines controllers" 数组不匹配,它会强制 assemble
使用默认路由(不完美,但对我有用):
public function url(array $urlOptions = array(), $name = null, $reset = false, $encode = true, $default = false)
{
$router = Zend_Controller_Front::getInstance()->getRouter();
if(isset($urlOptions['controller']) && !in_array($urlOptions['controller'], array('products', 'training'))) {
$name = 'default';
}
return $router->assemble($urlOptions, $name, $reset, $encode);
}