• zend framework2 的controller内如何直接返回不带模板的页面


     

    ZendFramework2学习笔记 静态配置layout模板和动态设置layout模板

    分类: ZendFramework2
     

    目录(?)[+]

     

    1)静态配置layout

    ZendFramework2项目在启动过程中,会读取配置文件中的layout配置。

    layout配置默认放在Application模块的configmodule.config.php配置文件中的‘view_manager’项中,如下:

    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. 'view_manager' => array(  
    2.         'layout'                   => 'layout/layout',  
    3. ),  
    手动创建的zf2项目的‘view_manager’项中可能没有‘layout’这个子项,这时候需要我们手动添加“'layout'=>'layout/layout',”。很奇怪,为什么zf2项目的‘view_manager’项中没有‘layout’这个子项也能够自动加载ModuleApplicationviewlayoutlayout.phtml呢?原因就在于ViewManager中已经写死了默认值,如果没有配置‘layout’就采用默认值'layout/layout',如下:
    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. class ViewManager extends AbstractListenerAggregate  
    2. {  
    3.     public function getLayoutTemplate()  
    4.     {  
    5.         $layout = 'layout/layout';  
    6.         if (isset($this->config['layout'])) {  
    7.             $layout = $this->config['layout'];  
    8.         }  
    9.         return $layout;  
    10.     }  
    11. }  
    除了Application模块,layout配置也可以放在其他模块的configmodule.config.php配置文件中的‘view_manager’项中。

    如果Application模块和其他模块中都配置了layout项的话,根据各个模块的加载顺序,后加载的模块的layout配置会覆盖掉先加载的模块的layout配置,即zf2会采用最后一个加载的模块的layout配置。如下:

    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. class ConfigListener extends AbstractListener implements  
    2.     ConfigMergerInterface,  
    3.     ListenerAggregateInterface  
    4. {  
    5.     public function onMergeConfig(ModuleEvent $e)  
    6.     {  
    7.         foreach ($this->configs as $config) {//遍历各个模块的配置  
    8.             $this->mergedConfig = ArrayUtils::merge($this->mergedConfig, $config);//合并各个模块的配置  
    9.         }  
    10.   
    11.         return $this;  
    12.     }  
    13. }  
    14.   
    15. abstract class ArrayUtils  
    16. {  
    17.     public static function merge(array $a, array $b, $preserveNumericKeys = false)  
    18.     {  
    19.         foreach ($b as $key => $value) {  
    20.             if (array_key_exists($key, $a)) {  
    21.                 if (is_int($key) && !$preserveNumericKeys) {  
    22.                     $a[] = $value;  
    23.                 } elseif (is_array($value) && is_array($a[$key])) {  
    24.                     $a[$key] = static::merge($a[$key], $value, $preserveNumericKeys);  
    25.                 } else {  
    26.                     $a[$key] = $value;//相同的配置项,后者的value会覆盖前者的value  
    27.                 }  
    28.             } else {  
    29.                 $a[$key] = $value;  
    30.             }  
    31.         }  
    32.   
    33.         return $a;  
    34.     }  
    35. }  
    模块的加载顺序是根据应用配置文件configapplication.config.php中的‘modules’项来的:
    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. 'modules' => array(  
    2.     'Application',  
    3.     'User',  
    4.     'Admin',  
    5. ),  
    按照上面的配置,模块的加载顺序就是'Application'->'User'->'Admin',所以,如果moduleAdminconfigmodule.config.php中的‘view_manager’项中配置了‘layout’子项,则zf2会采用Admin模块中的这个layout配置。

    既然zf2对layout配置的获取是根据模块的加载顺序采用最后一个,那么zf2对于layout的.phtml文件的获取是怎么样的?
    1)zf2会按照模块的加载顺序,在各个模块的view目录下查找最后采用的layout配置对应的.phtml文件;
    2)zf2采用最后一个从模块的view目录下获取的layout对应的.phtml文件。
    例如:上面例子中,zf2采用了Admin模块的layout配置“layout/layout”,该layout配置对应的.phtml文件是模块的view目录下的layoutlayout.phtml文件,如果'Application'和'User'这2个模块的view目录下都有layoutlayout.phtml文件,而'Admin'模块的view目录下没有layoutlayout.phtml文件,那么,根据模块的加载顺序'Application'->'User'->'Admin',zf2最后采用的layout文件就是'User'模块的view目录下的layoutlayout.phtml文件。

    因此,如果采用静态配置layout,zf2项目就只有一个layout,这样对实际项目开发而言可能不够。例如,一个商城网站可能会有“顾客”、“店铺主”和“管理员”这三种角色,“顾客”可能需要一个能浏览商城的layout和一个能付款收货的个人中心layout,“店铺主”可能需要能管理货物上下架、收款发货的店铺管理layout,“管理员”可能需要能查看商城所有交易信息的商城管理layout。因此,就需要动态设置layout。

    2)动态设置layout

    ZendFramework2项目的mvc过程中,会有一个MvcEvent对象贯穿始终,通过该对象,可以动态设置layout:

    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. $viewModel = $e->getViewModel();//($e instanceof MvcEvent == true);  
    2. if ($viewModel)  
    3.     $viewModel->setTemplate("layout/layout");  
    一个商城网站,像“顾客”、“店铺主”和“管理员”这三种角色所需要的4种layout可以通过不同url来区分,例如:浏览商品可能是http://xxx/goods/xxxxxxx这样的url,顾客中心可能是http://xxx/customer/xxxxxxx这样的url,店铺后台管理可能是http://xxx/shopowner/xxxxxxx,管理后台可能是http://xxx/admin/xxxxxxx这样的url。

    假定这样配置路由:

    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. 'goods' => array(  
    2.            'type'    => 'segment',  
    3.            'options' => array(  
    4.                'route'    => '/goods[/][:action][/:id]',  
    5.                'constraints' => array(  
    6.                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',  
    7.                    'id'     => '[0-9]+',  
    8.                ),  
    9.                'defaults' => array(  
    10.                    'controller' => 'GoodsControllerGoods',  
    11.                    'action'     => 'index',  
    12.                ),  
    13.            ),  
    14.        ),  
    15.        'customer' => array(  
    16.            'type'    => 'segment',  
    17.            'options' => array(  
    18.                'route'    => '/customer[/][:action][/:id]',  
    19.                'constraints' => array(  
    20.                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',  
    21.                    'id'     => '[0-9]+',  
    22.                ),  
    23.                'defaults' => array(  
    24.                    'controller' => 'CustomerControllerCustomer',  
    25.                    'action'     => 'admin',  
    26.                ),  
    27.            ),  
    28.        ),  
    29. 'shopowner' => array(  
    30.            'type'    => 'segment',  
    31.            'options' => array(  
    32.                'route'    => '/shopowner[/][:action][/:id]',  
    33.                'constraints' => array(  
    34.                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',  
    35.                    'id'     => '[0-9]+',  
    36.                ),  
    37.                'defaults' => array(  
    38.                    'controller' => 'ShopownerControllerShopowner',  
    39.                    'action'     => 'admin',  
    40.                ),  
    41.            ),  
    42.        ),  
    43. 'admin' => array(  
    44.            'type'    => 'segment',  
    45.            'options' => array(  
    46.                'route'    => '/admin[/][:action][/:id]',  
    47.                'constraints' => array(  
    48.                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',  
    49.                    'id'     => '[0-9]+',  
    50.                ),  
    51.                'defaults' => array(  
    52.                    'controller' => 'AdminControllerAdmin',  
    53.                    'action'     => 'admin',  
    54.                ),  
    55.            ),  
    56.        ),  
    这样,就可以通过route名称来区分url了。

    然后,在Application模块的viewlayout目录下面可以分别放置4个layout文件:goods.phtml、customer.phtml、shopowner.phtml和admin.phtml。

    ZendFramework2项目的启动过程,依次会触发loadModules、loadModule、bootstrap、route、dispatch......等事件,其中对layout配置的读取是在loadModule事件中完成的,而对url的路由解析是在route事件中完成的,因此,可以设置一个route事件的listener,在该listener中完成动态设置layout。

    Application模块Module.php的onBootstrap是bootstrap事件被触发后最后一个被执行的listener,可以在该函数中attach一个route事件的listener:

    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. class Module  
    2. {  
    3.     public function onBootstrap(MvcEvent $e)  
    4.     {  
    5.         $eventManager        = $e->getApplication()->getEventManager();  
    6.         $moduleRouteListener = new ModuleRouteListener();  
    7.         $moduleRouteListener->attach($eventManager);  
    8.   
    9.         $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'onRoute'), -9000);//attach一个route事件的listener  
    10.     }  
    11. }  
    在onRoute函数中就可以根据route的不同名称来设置不同的layout了:
    [php] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. class Module  
    2. {  
    3.     public function onRoute(MvcEvent $e)  
    4.     {  
    5.         $route = $e->getRouteMatch()->getMatchedRouteName();  
    6.         if ($route == 'user')//顾客个人中心  
    7.             $e->getViewModel()->setTemplate("layout/customer");  
    8.         else if ($route == 'shopowner')//店铺主管理后台  
    9.             $e->getViewModel()->setTemplate("layout/shopowner");  
    10.         else if ($route == 'admin')//管理员后台  
    11.             $e->getViewModel()->setTemplate("layout/admin");  
    12.         else//浏览商品  
    13.             $e->getViewModel()->setTemplate("layout/goods");  
    14.     }  
    15. }  
    16.    
  • 相关阅读:
    Java多线程之 对同一个值操作
    Java 之 应用多线程计算1+2+...+100之多种方法比较(二)
    Java 之 应用多线程计算1+2+...+100之多种方法比较(一)
    SQL语句优化
    第六章:shiro Realm相关对象
    第五章:shiro密码加密
    第四章:shiro的INI配置
    第三章:shiro授权认证
    第二章:shiro身份验证
    第一章:Shiro简介
  • 原文地址:https://www.cnblogs.com/HuiLove/p/4923393.html
Copyright © 2020-2023  润新知