使用前缀和Zend_Controller_Router_Route

时间:2022-01-15 11:09:16

On an existing Zend Framework website with few controllers and no modules I need to add some prefixes to the default routes.

在现有的Zend Framework网站上,只有很少的控制器而没有模块,我需要在默认路由中添加一些前缀。

For example, I currently have :

例如,我目前有:

/products
/products/id/1
/training
/commonpage

I want to add a product line level, without duplicating my controllers in x modules (I'll just request the right product line inside my controllers with _getParam ).

我想添加一个产品线级别,而不是在x模块中复制我的控制器(我只需要使用_getParam在我的控制器中请求正确的产品系列)。

So my new paths will be :

所以我的新途径将是:

/line1/products
/line1/products/id/1
/line2/training
/commonpage

What I tried so far is this route (located in my Bootstrap file) :

到目前为止我尝试的是这条路线(位于我的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) . ')')
    ));
}

But without any success (it gives me a 404). How can I build a single route that match all uri under those conditions :

但没有任何成功(它给了我一个404)。如何在这些条件下构建匹配所有uri的单一路径:

  • The prefix of the uri match a value in my product lines array
  • uri的前缀与我的产品系列数组中的值匹配

  • The route is valid only if the controller requested is allowed to be accessed in a "product line way" - by an array containing the names of my controllers for example
  • 只有当允许以“产品线方式”访问所请求的控制器时,该路由才有效 - 通过包含我的控制器名称的数组,例如

UPDATE

Ok I managed to get really close of what I'm trying to do with this code :

好的,我设法真正接近我正在尝试使用此代码:

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

With that I can access /line1/products but not /line1/commonpage, which is what I want - so the controller constraint is working great. As you can see I add the product line name in the Zend Registry, so it is saved when I use the URL View Helper in templates (that way I don't have to edit all my templates to add the product line parameter in my helper calls).

有了这个,我可以访问/ line1 / products而不是/ line1 / commonpage,这就是我想要的 - 所以控制器约束工作得很好。正如您所看到的,我在Zend Registry中添加了产品系列名称,因此当我在模板中使用URL View Helper时会保存它(这样我就不必编辑所有模板来在我的帮助器中添加产品系列参数调用)。

The problem I have now is about this helper : it seems that my controller constraint is just get ignored. When I do this in my template:

我现在遇到的问题是关于这个帮助器:似乎我的控制器约束被忽略了。当我在我的模板中执行此操作时:

<a href="<?php echo $this->url(array('controller'=> 'commonpage', 'action'=>'index'),null, true) ; ?>">My link</a>

I end up with this :

我最终得到了这个:

<a href="/line1/commonpage">My link</a>

So the product line is added, despite of the fact that this is not allowed by the controller constraint of my route.

因此添加了产品系列,尽管我的路径的控制器约束不允许这样做。

2 个解决方案

#1


1  

Ok I found a solution : I changed the URL Helper to add the controller constraint inside it. If the controller doesn't match the "product lines controllers" array, it force assemble to use the default route (not perfect, but it works for me):

好的我找到了一个解决方案:我更改了URL Helper以在其中添加控制器约束。如果控制器与“产品线控制器”阵列不匹配,则强制组装使用默认路径(不完美,但它适用于我):

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

#2


0  

you can add / modify specific route with ini params file :

您可以使用ini params文件添加/修改特定路径:

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"

where job_en is the name of my route and request-offer the param name

其中job_en是我的路线名称,请求提供参数名称

#1


1  

Ok I found a solution : I changed the URL Helper to add the controller constraint inside it. If the controller doesn't match the "product lines controllers" array, it force assemble to use the default route (not perfect, but it works for me):

好的我找到了一个解决方案:我更改了URL Helper以在其中添加控制器约束。如果控制器与“产品线控制器”阵列不匹配,则强制组装使用默认路径(不完美,但它适用于我):

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

#2


0  

you can add / modify specific route with ini params file :

您可以使用ini params文件添加/修改特定路径:

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"

where job_en is the name of my route and request-offer the param name

其中job_en是我的路线名称,请求提供参数名称