本文连接:https://www.cnblogs.com/alanabc/p/10246023.htmlhtml
把关系提到前面来说,但愿可以大体说清楚吧:web
controllerNamespace
进行指定Yii的版本化,说白了就是经过路由,把URL定位到对应的方法去。浏览器
咱们这里用Yii的基础版(basic)做为讲解模板吧。服务器
路由机制的工做过程,简单来讲就是:yii2
若没法经过URL直接定位到文件,则经过index.php
来接收请求(这里可能须要配置一下你的web服务器)。app
index.php
接收到请求后,先送达路由管理器,经过路由解析出URL对应的方法,而后送达这个方法,由方法受理请求并做出响应。框架
当没法定位到文件也没法解析出方法时,通常来讲作404错误处理,表示资源不存在。yii
在框架中,除了静态资源是直接定位文件,其余的请求都是路由到某个方法进行处理。Yii是一个面向对象的框架,路由表经过命名空间来一步一步的解析class、action,肯定处理请求的方法。好比,在基础版中,请求URL<域名>/index.php?r=site/index
,定位到SiteController
的actionIndex
方法。ide
那么路由表是怎么知道,URL里的site
指的就是SiteController
呢?继续看:
Yii的配置文件里,有一项很重要的配置是controllerNamespace
,顾名思义就是控制器的命名空间。在基础版里,它大概是这么配置的:'controllerNamespace' => 'app\controllers'
,根据这个命名空间,路由就能找到控制器的目录,而后就能定位到控制器和方法了。固然,你看不到它,由于这是核心框架的默认配置。若是你想要验证个人说法,那么:
vendor\yiisoft\yii2\base\Application.php
line 95
/** * @var string the namespace that controller classes are located in. * This namespace will be used to load controller classes by prepending it to the controller class name. * The default namespace is `app\controllers`. * * Please refer to the [guide about class autoloading](guide:concept-autoloading.md) for more details. */ public $controllerNamespace = 'app\\controllers';
当你请求URL<域名>?r=site/index
时,路由会去寻找app\controllers\SiteController
这个类(其实就是去应用根目录下的controllers
里寻找SiteController.php
文件),而后找到里面的actionIndex
方法。
凭什么site
就对应SiteController
类,index
就对应actionIndex
方法?它也是默认的配置!不过那就是另外一件话题了。
你使用过Yii自带的debug组件吗?若是没有,那你应该知道,当启用了这个组件,你就有两种方式能够使用它:一是在页面的右下角,会有一个Yii的小logo,展开它就是debug组件;二是经过<域名>/index.php?r=debug/default/index
,直接打开debug页面。
yii-debug组件必然是有处理请求的方法的,但是为啥上面这个URL能够准肯定位到方法呢,controllerNamespace
里没有配置过它呀?
其实yii-debug是一个组件(module),每个组件都由控制器、模型、视图等构成,是一个独立的小应用。对于这样的组件,咱们要在$config['modules']
里配置,而后就能挂载它,你就能够正常使用了。也正是这个“挂载”的过程,框架寻找到了对应的命名空间,就能够准确的找到控制器和方法了。
咱们来找找这个组件吧:vendor\yiisoft\yii2-debug
,会找到文件Module.php
:
<?php namespace yii\debug; //use ... class Module extends \yii\base\Module implements BootstrapInterface { //... }
它继承了\yii\base\Module
类,这是一个模块类,你只须要知道,继承模块类的文件在对应的目录时,会被自动加载。
组件的“挂载”大体就是这样。但是这和版本化有什么关系?关系可大了,咱们的版本化,就是依靠组件实现的。
先来梳理一下:
controllerNamespace
进行指定咱们在上面看到,yii-debug组件是在配置项的$config['modules']
里多加了一个debug
组件,而且指明了'class' => 'yii\debug\Module'
。
仍然是拿Yii基础版来,作个简单的“版本化”:我如今打算增长一个version1
应用,算是加了一个“版本1”吧。
首先在配置文件web.php
里:
$config = [ //略... 'modules' => [ //这里class指定的是模块类,看下文 'version1' => ['class' => 'app\version1\Version1'], ], ];
上面配置里的class
可不是乱写的哦!是有依据的。
在应用根目录下新建文件夹version1
(vendor
同一级,兄弟文件夹),在文件夹内新建文件Version1.php
做为一个模块类,继承\yii\base\Module
。在这个类里面还指定了$controllerNamespace
,注意跟上文提到的不同:上文指定的是整个应用的,这里指定的是组件本身的:
<?php namespace app\version1; class Version1 extends \yii\base\Module { //这里指定的是组件本身的控制器命名空间 public $controllerNamespace = 'app\version1\controllers'; public function init() { parent::init(); } }
接下来在version1
文件夹里继续新建三个子文件夹:
controllers
:控制器文件夹。里面的控制器文件,命名空间要写成namespace app\version1\controllers;
models
:模型文件夹。里面的模型文件,命名空间要写成namespace app\version1\models;
views
:视图文件夹你只要像正常的那样在这三个文件夹里写你的代码就能够了。
最后,去配置一下路由:
'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ 'version1/<controller:[\w-]+>/<action:[\w-]+>' => 'version1/<controller>/<action>', //version1路由 '<controller:[\w-]+>/<action:[\w-]+>' => '<controller>/<action>', //原有应用的路由(好比本来URL:<域名>/index.php?r=site/index,如今URL:<域名>/site/index) //其余略... ], ],
这样,访问URL<域名>/version1/site/index
的时候,就路由到version1
的SiteController
的actionIndex
方法进行处理。
语言组织的不够好见谅!
API的版本化和上面的也没什么太大的区别,你能够试着把API作个版本化;还能够试着把Yii基础版配置成Yii高级版的样子,这样能够加深理解。