ZendFramework2学习笔记 视图文件路径,多控制器路由,同模块或同控制器的多路由配置

来源:互联网 发布:机械模型制作软件 编辑:程序博客网 时间:2024/06/08 19:10

一)路由配置和视图文件路径

    ZendFramework2项目的路由配置在config\module.config.php文件中:
    'router' => array(         'routes' => array(             'XXX' => array(                 'type'    => 'segment',                 'options' => array(                     'route'    => '/YYY[/][:controller][/:action][/:id]',                     'constraints' => array(                         'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',                         'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',                         'id'     => '[0-9]+',                     ),                     'defaults' => array(                         '__NAMESPACE__' => 'ZZZ\Controller',                     ),                                      ),             ),         ),    ),

1)路由名称XXX:

    在layout.phtml和view.phtml等视图文件中,经常会用到“$this->url(aaa);”语句来设置超链接,其中aaa就是路由名称。这个aaa必须在某个模块的config\module.config.php中设置过,否则,“$this->url(aaa);”这句在运行时会出现“没有处理的异常”错误!
    还有需要注意的是,对于mvc过程中的MVCEvent,通过$MVCEventObject->getRouteMatch()->getMatchedRouteName();获取到的路由名称是这个XXX,而不是url中的YYY。
2)YYY区分大小写,例如:如果YYY=“admin”,那么访问“http://.../Admin/...”会出现“404页面未找到”错误!但是,匹配项controller和action不区分大小写,即,“http://.../admin/ADMIN/INDEX/...”和“http://.../admin/admin/index/...”都能成功访问到AdminController控制器的名为index的action!
3)ZZZ是模块名称,即ZZZ\Controller是模块的控制器所在路径(“\module\ZZZ\src\ZZZ\Controller\”)!
4)mvc过程怎样获取视图文件路径:
    ZendFramework2需要读取视图文件来render网页的时候,会使用模块、控制器和action的名称的“小写”字符串来拼接出.phtml视图文件路径,例如:假设Admin模块有一个TestController控制器,TestController控制器有一个doAction的action,那么,ZendFramework2是读取view\admin\test\do.phtml这个视图文件来render网页。
5)模块、控制器和action名称的“小陷阱”
    先看看ZendFramework2拼接视图文件路径的代码,如下:
class InjectTemplateListener extends AbstractListenerAggregate{    public function injectTemplate(MvcEvent $e)    {        //......                $template   = $this->inflectName($module);        //......        $template .= '/';        //......        $template  .= $this->inflectName($controller);        //......            $template .= '/' . $this->inflectName($action);    }    protected function inflectName($name)    {        if (!$this->inflector) {            $this->inflector = new CamelCaseToDashFilter();        }        $name = $this->inflector->filter($name);//filter函数会将字符串中“位置不是第一个”且“前面的字母是小写字母”的大写字母前面添加一个分隔符‘-’,即,如果$name=“TestTest”,那么该函数返回的就是“test-test”        return strtolower($name);    }}
    可见,如果模块、控制器或者action的名称拥有一个“位置不是第一个”且“前面的字母是小写字母”的大写字母的话,会导致视图文件的路径中出现‘-’分隔符!!!因此,当创建模块、控制器或者action的时候就需要特别注意在view目录下创建视图文件及其所在文件夹的时候要适时添加分隔符‘-’!!!

二)同模块配置多路由

    只需要在config\module.config.php文件中配置相同“__NAMESPACE__”的路由即可:
    'router' => array(         'routes' => array(             'XXX' => array(                 'type'    => 'segment',                 'options' => array(                     'route'    => '/YYY[/][:controller][/:action][/:id]',                     'constraints' => array(                         'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',                         'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',                         'id'     => '[0-9]+',                     ),                     'defaults' => array(                         '__NAMESPACE__' => 'ZZZ\Controller',                     ),                                      ),             ),             'AAA' => array(                 'type'    => 'segment',                 'options' => array(                     'route'    => '/BBB[/][:controller][/:action][/:id]',                     'constraints' => array(                         'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',                         'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',                         'id'     => '[0-9]+',                     ),                     'defaults' => array(                         '__NAMESPACE__' => 'ZZZ\Controller',                     ),                                      ),             ),         ),    ),
    如上配置,通过“http://....../YYY/......”和“http://....../BBB/......”访问的就都是ZZZ模块的控制器了!

三)多控制器配置

    以上的配置就支持多控制器:
    'router' => array(         'routes' => array(             'XXX' => array(                 'type'    => 'segment',                 'options' => array(                     'route'    => '/YYY[/][:controller][/:action][/:id]',                     'constraints' => array(                         'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',                         'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',                         'id'     => '[0-9]+',                     ),                     'defaults' => array(                         '__NAMESPACE__' => 'ZZZ\Controller',                     ),                                      ),             ),         ),    ),
    假设ZZZ\Controller目录下有AdminController和TestController两个控制器,则可以通过“http://....../YYY/admin/......”和“http://....../YYY/test/......”来分别访问这2个控制器!

三)同控制器多路由配置

    要实现同控制器多路由配置,要将controller这个匹配项作为子路由,并且在主路由限定控制器,就可以实现,配置如下:
            'XXX' => array(                'type'    => 'Literal',                'options' => array(                    'route'    => '/YYY',                    'defaults' => array(                        '__NAMESPACE__' => 'ZZZ\Controller',                        'controller'    => 'WWW',                    ),                ),                'may_terminate' => true,                'child_routes' => array(                    'EEE1' => array(                        'type'    => 'Segment',                        'options' => array(                            'route'    => '/FFF1[/][:action][/:id]',                            'constraints' => array(                                'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',                            ),                            'defaults' => array(                            ),                        ),                    ),                    'EEE2' => array(                        'type'    => 'Segment',                        'options' => array(                            'route'    => '/FFF2[/][:action][/:id]',                            'constraints' => array(                                'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',                            ),                            'defaults' => array(                            ),                        ),                    ),                ),            ),
    按以上配置,由于在主路由中限制了控制器WWWController,所以通过“http://.../YYY/FFF1/...”和“http://.../YYY/FFF2/...”就都是访问ZZZ模块的WWWController了!另外,由于有了子路由,通过mvc过程中的MVCEvent,$MVCEventObject->getRouteMatch()->getMatchedRouteName();获取到的路由名称是“XXX/EEE1”或者“XXX/EEE2”。

    同样的方法,也可以实现统一action的不同路由配置。


0 0