Zend控制器路由器:定义变量以指向一个控制器中的不同操作

时间:2012-08-15 15:37:57

标签: zend-framework zend-controller-router

我是Zend的新手,我和Zend Routers有点麻烦。我搜索过它,但没有找到......

我希望能够在uri级别为每个定义的变量定义路由器,以指向一个控制器中的不同操作。

我正在使用lang和模块,所以我在bootstrap应用程序中定义了下一个initRoutes函数:

protected function _initRoutes()
{
    $front = Zend_Controller_Front::getInstance();
    $router = $front->getRouter();

    $defaultRoute = new Zend_Controller_Router_Route(
        ':lang/:module/:controller/:action',
        array(
            'lang' => 'es',
            'module' => 'default',
            'controller' => 'index',
            'action' => 'index'
        ),
        array(
            'lang' => '^(en|es)$',
            'module' => '^(default|admin)$'
        )
    );

    $router->addRoute('defaultRoute', $defaultRoute);

    return $router;
}

我希望能够通过定义的操作访问论坛部分和论坛主题。

类似的东西:

  • mydomain / forum - >论坛/索引

  • mydomain / forum / section - >论坛/ sectionAction

  • mydomain / forum / section / topic - >论坛/ topicAction

以及在uri级别定义的lang和模块,如:

  • MYDOMAIN /郎/模块/论坛

  • MYDOMAIN /郎/模块/论坛/部分

  • MYDOMAIN /郎/模块/论坛/部分/主题

所以我有这个:

class ForumController extends Zend_Controller_Action
{

public function indexAction()
{
}

public function sectionAction()
{
}

public function topicAction()
{
}

然后我在Default_Bootstrap中创建了下一个路由:

$forumRoutes = new Zend_Controller_Router_Route(
    ':lang/:module/forum',
    array(
        'lang' => 'es',
        'module' => 'default',
        'controller' => 'forum',
        'action' => 'index'
    )
);

$sectionRoutes = new Zend_Controller_Router_Route(
    ':lang/:module/forum/:section',
    array(
        'lang' => 'es',
        'module' => 'default',
        'controller' => 'forum',
        'action' => 'section',
        'section' => ''
    )
);

$topic = new Zend_Controller_Router_Route(
    ':lang/:module/forum/:section/:topic',
    array(
        'lang' => 'es',
        'module' => 'default',
        'controller' => 'forum',
        'action' => 'topic',
        'section' => '',
        'topic' => ''
    )
);

$router->addRoute('forumTopics', $topic);
$router->addRoute('forumSections', $section);
$router->addRoute('forum', $forumRoutes);

现在,这仅在我在uri级别定义lang和模块时有效,但如果我定义为=>则不起作用mydomain / forum / section |部分/主题。这也给我的导航 - >菜单带来了另一个问题。如果我在路由器定义中将“forum”定义为静态变量,当我将鼠标悬停在navigatoin.xml中定义的任何标签上时,uri级别对于每个标签都具有相同的值。

我试图建立一个这样的链:

    $forumRoutes = new Zend_Controller_Router_Route(
        ':lang/:module/forum',
        array(
            'lang' => 'es',
            'module' => 'default',
            'controller' => 'forum',
            'action' => 'index'
        )
    );

    $section = new Zend_Controller_Router_Route(
        ':section',
        array(
            'action' => 'section',
            'section' => ''
        )
    )

    $topic = new Zend_Controller_Router_Route(
        ':topic',
        array(
            'action' => 'topic',
            'topic' => ''
        )
    )

    $chainedRoute = new Zend_Controller_Router_Route_Chain();
    $chainedRoute->chain($topic)
                 ->chain($section)
                 ->chain($forumRoutes);
    $router->addRoute($chainedRoute);

但这并不像我预期的那样有效。

任何帮助都将不胜感激,谢谢。

2 个答案:

答案 0 :(得分:2)

你是Zend的新手。你说的。所以这里有一些解释:

  1. 理想情况下,Zend应用程序上的URL是:
  2.   

    example.com/controller/action/param-name/:param-value

    所以在这种情况下,如果在UsersController下有一个名为Edit的动作,它将是:

      

    example.com/users/edit

    如果添加操作,则为:

      

    example.com/users/add

    当您将第一个参数指定为变量时,它将与控制器请求冲突。示例:如果您说控制器是User但第一个参数接受一个值并将其放入emplyees,那么即使usercontroller存在,一个请求如example.com/employees和example.com/user也将指向employees控制器!这又是一个理论!

    您可能想要做的是,让路线只接受动态值而不是路由!您不希望用户路由您的应用程序,而是将用户路由到应用程序的不同部分。

    关于语言,您需要使用Zend_Locale来检查

    的HTML语言

    <html lang="nl"> or <html lang = "en">

    希望事情很清楚! :)

答案 1 :(得分:1)

这是一个快速示例,可以帮助您使用ZF中的路线。

如果您使用的默认项目结构类似于使用Zend Tool启动新项目时获得的项目结构,请进入Application文件夹。

在你的Bootstrap.php中设置如下内容:

protected function _initRouteBind() {
        // get the front controller and get the router
        $front  = Zend_Controller_Front::getInstance();
        $router = $front->getRouter();
        // add each custom route like this giving them a descriptive name 
        $router->addRoute(
            'addTheDescriptiveRouteNameHere',
            new Zend_Controller_Router_Route(
                '/:controller/:id/:action/:somevar',
                array(
                    'module'     => 'default', 
                    'controller' => ':controller',
                    'action'     => ':action', 
                    'id'         => ':id',
                    'somevar'    => ':somevar'
                )
            )
        );   
}

上面的示例仅用于说明如何使用路径,其中控制器,操作和一些参数在网址中设置。

控制器和操作应该在没有任何额外工作的情况下解决,但要获得'id'或'somevar'值,您可以在控制器中执行此操作:

public function yourAction()
{
    // How you get the parameters to pass in to a function
    $id = $this->getRequest()->getParam('id');
    $somevar = $this->getRequest()->getParam('somevar');

    // Using the parameters
    $dataYouWant = $this->yourAmazingMethod($id);
    $somethingElse = $this->yourOtherAmazingMethod($somevar);

    // Assign results to the view
    $this->view->data = $dataYouWant;
    $this->view->something = $somethingElse;
}     

因此,虽然您希望确保您的方法处理小心传递的参数(毕竟它是用户提供的信息),但这是使用路由参数绑定的原则。您当然可以将“/ site”作为路径并将其指向CMS模块或控制器,然后将另一个指向“/ site /:id”,其中“id”是页面标识符。

也只是说一个很好的替代方案:

$id = $this->getRequest()->getParam('id');
$somevar = $this->getRequest()->getParam('somevar');

这本身并不好,因为它假设一个参数将被传递,使用速记条件语句与动作助手一起使用:

$id = ($this->_hasParam('id')) ? $this->_getParam('id') : null;
$somevar = ($this->_hasParam('somevar')) ? $this->_getParam('somevar') : null;

如果您对此不熟悉,

($this->_hasParam('id'))

是条件测试,如果为true,则分配':'左边的任何值,如果为false,则赋值为':'右边的值。

因此,如果为真,则指定的值为

$this->_getParam('id')

如果为false,则返回null。 这有帮助吗? :-D