2012-08-15 82 views
0

我只是Zend的新手,我对Zend路由器有点麻烦。我搜索了它,但没有发现...Zend控制器路由器:定义变量以指向一个控制器中的不同动作

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

我与郎和模块,所以我在系统启动的应用程序定义的下一个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 /论坛 - >论坛/指数

  • MYDOMAIN /论坛/节 - >论坛/ sectionAction

  • MYDOMAIN /论坛/节/话题 - > forum/topicAction

还有lang和modul向在URI级别等来定义:

  • 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层次的模块,但如果我喜欢=> MYDOMAIN /论坛定义不起作用/ 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

你是Zend的新手。你说的。因此,这里有一些解释:

  1. 理想的Zend的应用程序的URL是:

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

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

example.co M /用户/编辑

如果动作增加,这将是:

example.com/users/add

当你指定第一个参数作为一个变量,它会与控制器请求冲突。例如:如果你说控制器是用户,但第一个参数接受一个值并把它放在emplyees中,那么作为example.com/employees和example.com/user的请求都会指向员工控制器,即使usercontroller存在!这又是一个理论!

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

关于语言,那么你需要使用Zend_Locale这将检查是

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

希望的事情是清楚的HTML语言! :)

+0

哦,我看到了,谢谢你的回复,但我想要做的事情是:取决于URI上有多少个参数,我将使用Controller_Action进行渲染。所以我可以在路由器级别定义,如果论坛控制器得到的第一个参数将用“sectionAction”渲染,如果我有两个参数,我将使用“topicAction”渲染,我只需要做一些事情,比如'public function sectionAction(){$ section = $ this - > _ request-> getParam('section'); // @ TODO:从Db获取并呈现}'这可以通过Zend_Controller_Router完成吗? – Ramiro 2012-08-15 19:38:50

+0

我在codeIgniter中做了这样的事情,在路由配置上我设置了一个像'$ routes ['forum /(az)'] ='forum/section''这样的数组,并且匹配第二个参数只需添加一个新的路由器过滤器例如:'$ routes ['forum /(az)/(az)'] ='forum/topic''这可能与Zend Routers相匹配吗?像重定向,但只获取uri参数并重定向到所需的操作。 – Ramiro 2012-08-15 20:06:43

+0

Codeigniter使用基于段的检查,而zend检查请求!所以没有'segment'这样的东西,但是,使用Request-Param获取东西...在这里,正如我所提到的,您将不得不重新计划应用程序......动作来自控制器...示例,用户控制器可以查看,添加,修改,删除..路线用于例如路线 - “我的仪表板”路由到用户控制器 - 工具和选项操作...很酷? – Karma 2012-08-15 21:27:44

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

上面我的例子只是为了说明你将如何使用,其中控制器,动作和几个参数的设定的路线网址。

控制器和行动应该没有任何额外的工作来解决然而拿到“身份证”或“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') 

和空如果为假。 这有帮助吗? :-D