本文連接: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高級版的樣子,這樣能夠加深理解。