使用前缀和 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 的单一路由:

更新

好的,我已经非常接近于使用此代码尝试执行的操作了:

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);
    }