`ThinkPHP5.0`應用基于`MVC`(模型-視圖-控制器)的方式來組織。
> MVC是一個設計模式,它強制性的使應用程序的輸入、處理和輸出分開。使用MVC應用程序被分成三個核心部件:模型(M)、視圖(V)、控制器(C),它們各自處理自己的任務。
5.0的URL訪問受路由決定,如果關閉路由或者沒有匹配路由的情況下,則是基于:
> #### [http://serverName/index.php(或者其它應用入口文件)/模塊/控制器/操作/參數/值...](http://servername/index.php%EF%BC%88%E6%88%96%E8%80%85%E5%85%B6%E5%AE%83%E5%BA%94%E7%94%A8%E5%85%A5%E5%8F%A3%E6%96%87%E4%BB%B6%EF%BC%89/%E6%A8%A1%E5%9D%97/%E6%8E%A7%E5%88%B6%E5%99%A8/%E6%93%8D%E4%BD%9C/%E5%8F%82%E6%95%B0/%E5%80%BC...)
下面的一些概念有必要做下了解,可能在后面的內容中經常會被提及。
## 入口文件
用戶請求的PHP文件,負責處理一個請求(注意,不一定是URL請求)的生命周期,最常見的入口文件就是`index.php`,有時候也會為了某些特殊的需求而增加新的入口文件,例如給后臺模塊單獨設置的一個入口文件`admin.php`或者一個控制器程序入口`think`都屬于入口文件。
## 應用
應用在`ThinkPHP`中是一個管理系統架構及生命周期的對象,由系統的?`\think\App`類完成,應用通常在入口文件中被調用和執行,具有相同的應用目錄(`APP_PATH`)的應用我們認為是同一個應用,但一個應用可能存在多個入口文件。
應用具有自己獨立的配置文件、公共(函數)文件。
## 模塊
一個典型的應用是由多個模塊組成的,這些模塊通常都是應用目錄下面的一個子目錄,每個模塊都有自己獨立的配置文件、公共文件和類庫文件。
> 5.0支持單一模塊架構設計,如果你的應用下面只有一個模塊,那么這個模塊的子目錄可以省略,并且在應用配置文件中修改:
>
> ~~~
> 'app_multi_module' => false,
> ~~~
## 控制器
每個模塊擁有獨立的`MVC`類庫及配置文件,一個模塊下面有多個控制器負責響應請求,而每個控制器其實就是一個獨立的控制器類。
控制器主要負責請求的接收,并調用相關的模型處理,并最終通過視圖輸出。嚴格來說,控制器不應該過多的介入業務邏輯處理。
> 事實上,5.0中控制器是可以被跳過的,通過路由我們可以直接把請求調度到某個模型或者其他的類進行處理。
5.0的控制器類比較靈活,可以無需繼承任何基礎類庫。
一個典型的`Index`控制器類如下:
~~~
namespace app\index\controller;
class Index
{
public function index()
{
return 'hello,thinkphp!';
}
}
~~~
## 操作
一個控制器包含多個操作(方法),操作方法是一個URL訪問的最小單元。
下面是一個典型的`Index`控制器的操作方法定義,包含了兩個操作方法:
~~~
namespace app\index\controller;
class Index
{
public function index()
{
return 'index';
}
public function hello($name)
{
return 'Hello,'.$name;
}
}
~~~
操作方法可以不使用任何參數,如果定義了一個非可選參數,則該參數必須通過用戶請求傳入,如果是URL請求,則通常是`$_GET`或者`$_POST`方式傳入。如`$name` 可以是$_GET['name'] 或 $_POST['name']的值
## 模型
模型類通常完成實際的業務邏輯和數據封裝,并返回和格式無關的數據。
> 模型類并不一定要訪問數據庫,而且在5.0的架構設計中,只有進行實際的數據庫查詢操作的時候,才會進行數據庫的連接,是真正的惰性連接。
> ThinkPHP的模型層支持多層設計,你可以對模型層進行更細化的設計和分工,例如把模型層分為邏輯層/服務層/事件層等等。
## 視圖
控制器調用模型類后返回的數據通過視圖組裝成不同格式的輸出。視圖根據不同的需求,來決定調用模板引擎進行內容解析后輸出還是直接輸出。
視圖通常會有一系列的模板文件對應不同的控制器和操作方法,并且支持動態設置模板目錄。
## 驅動
系統很多的組件都采用驅動式設計,從而可以更靈活的擴展,驅動類的位置默認是放入核心類庫目錄下面,也可以重新定義驅動類庫的命名空間而改變驅動的文件位置。
## 行為
行為(Behavior)是在預先定義好的一個應用位置執行的一些操作。類似于`AOP`編程中的“切面”的概念,給某一個切面綁定相關行為就成了一種類`AOP`編程的思想。所以,行為通常是和某個位置相關,行為的執行時間依賴于綁定到了哪個位置上。
要執行行為,首先要在應用程序中進行行為偵聽,例如:
~~~
// 在app_init位置偵聽行為
\think\Hook::listen('app_init');
~~~
然后對某個位置進行行為綁定:
~~~
// 綁定行為到app_init位置
\think\Hook::add('app_init','\app\index\behavior\Test');
~~~
一個位置上如果綁定了多個行為的,按照綁定的順序依次執行,除非遇到中斷。
## 命名空間
`ThinkPHP5`采用了`PHP`的命名空間進行類庫文件的設計和規劃,并且符合`PSR-4`的自動加載規范。