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

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

    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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值