簡介
ThinkPHP 5.0 的控制器定義比較靈活,可以無需繼承任何的基礎類,也可以繼承官方封裝的 \think\Controller 類或者其他的控制器類。
一個典型的控制器類定義如下:
<?php
namespace app\index\controller;
class Blog
{
public function index()
{
return view('index');
}
}
控制器類檔案的實際位置是 application\index\controller\Blog.php。
控制器類可以無需繼承任何類,命名空間預設以 app 為根命名空間。
預設情況下,控制器的輸出全部采用 return 的方式,無需進行任何的手動輸出,系統會自動完成渲染内容的輸出。
ThinkPHP 5.0 中,控制器主要分為以下幾種:
- 通路控制器(主要制器)
- 空控制器
- 多級控制器
- 分層控制器
- Rest 控制器
- 資源控制器
通路控制器
可通過 URL 直接通路的控制器就是通路控制器(Controller)或者主要制器,通路控制器是由 \think\App 類負責調用和執行個體化的,無需手動執行個體化。
URL 解析和路由後,會把目前的 URL 位址解析到 [ 子產品/控制器/操作 ],其實也就是執行某個控制器類的某個操作方法。
上面的一段代碼,就是一個通路控制器的例子。可通路的 URL 為:http://serverName/index/blog/index
空控制器
空控制器是指當系統找不到指定的控制器名稱的時候,系統會嘗試定位到空控制器(Error),利用這個機制可以用來定制錯誤頁面和URL優化。
預設的空控制器的名稱為 Error。
我們給項目定義一個Error控制器類。
<?php
namespace app\index\controller;
use think\Request;
class Error
{
public function index(Request $request)
{
$controllerName = $request->controller();
return $controllerName.'不存在';
}
}
多級控制器
多級控制器是指在application\index\controller目錄中,建立子目錄,用于存放控制器類檔案。
ThinkPHP5.0 支援任意層次級别的控制器,并且支援路由。例如:
<?php
namespace app\index\controller\api;
class Blog
{
public function index()
{
return view('index');
}
}
該控制器類的檔案位置為:application/index/controller/api/Blog.php。
可通路的URL為:http://serverName/index.php/index/api.blog/index
修改配置檔案,設定controller_auto_search參數開啟自動定位控制器,便于URL通路。
'controller_auto_search' => true,
之後,就可以使用這個URL位址:http://serverName/index.php/index/api/blog/index
分層控制器
分層控制器是對外隔離的,不能被URL直接通路,隻能在通路控制器、模型類的内部,或者視圖模闆檔案中進行調用。
分層控制器的目錄和通路控制器的目錄平級。
分層控制器可用于實作邏輯層控制器,給通路控制器調用;或者用于實作widget(挂件)功能,給視圖模闆調用,如更改網站皮膚、顯示菜單、面包屑、公共頭中的資訊、廣告位等等。
邏輯控制器
利用分層控制器的機制,我們定義Blog邏輯控制器。
<?php
namespace app\index\logic;
class Blog
{
public function insert($data)
{
// 邏輯層代碼
return true;
}
}
在通路控制器或模型類中的調用方式如下:
$logic = \think\Loader::controller('Blog', 'logic');
$logic->insert($data);
或
$logic = controller('Blog', 'logic');
$logic->insert($data);
或
action('Blog/insert', ['data' => $data], 'logic');
支援跨子產品調用,例如:
$logic = controller('Admin/Blog', 'logic');
$logic->insert($data);
widget 挂件控制器
利用分層控制器的機制,我們定義widget挂件控制器。
<?php
namespace app\index\widget;
class User
{
public function info()
{
$user_id = session('user.id'); // 擷取使用者的id
$userinfo = db('user')->where('id', $user_id)->find();
return view("widget/info", ['userinfo' => $userinfo])->getContent();
}
}
在模闆中的調用方式如下:
{:action('User/info', '', 'widget')}
或
{:widget('User/info')}
Rest 控制器
如果需要讓你的控制器支援 RESTful 的話,可以使用 Rest 控制器,在定義通路控制器的時候直接繼承 think\controller\Rest 即可。
新版不再推薦使用 Rest 控制器,建議用資源控制器替代。下一個大版本即将廢棄 Rest 控制器。
配合示例需要,首先在應用配置檔案中添加:
// URL僞靜态字尾
'url_html_suffix' => 'html|xml|json|jsonp',
RESTFul方法和标準模式的操作方法定義主要差別在于,需要對請求類型和資源類型進行判斷,大多數情況下,通過路由定義可以把操作方法綁定到某個請求類型和資源類型。如果你沒有定義路由的話,需要自己在操作方法裡面添加判斷代碼,示例:
<?php
namespace app\index\controller;
use think\controller\Rest;
class Blog extends Rest
{
public function index()
{
switch ($this->method){
case 'get': // get請求處理代碼
if ($this->type == 'json'){
}elseif ($this->type == 'xml'){
}
break;
case 'post': // post請求處理代碼
break;
case 'put': // put請求處理代碼
break;
default:
break;
}
}
}
在Rest操作方法中,可以使用$this->type擷取目前通路的資源類型,用$this->method擷取目前的請求類型。
RESTFul 輸出,有以下三種方式:
使用Rest類提供的 response 方法,進行輸出:
$this->response($data, 'json', );
使用think\Response類中的方法,進行輸出:
Response::create($data, 'json')->code();
使用助手函數,進行輸出:
資源控制器
資源控制器可以輕松的建立 RESTFul 資源控制器,可以通過指令行建立資源控制器。
// 生成 index 子產品的 Blog 資源控制器
php think make:controller index/Blog
或者使用完整的命名空間生成。
php think make:controller app\index\controller\Blog
為資源控制器注冊一個資源路由。
Route::resource('blog','index/Blog');
設定後會自動注冊 7 個路由規則,如下:
請求類型 | 路由規則 | 對應的方法 | 說明 |
---|---|---|---|
GET | blog | index | 文章清單頁(首頁) |
GET | blog/create | create | 建立新文章的界面 |
POST | blog | save | 執行建立新文章 |
GET | blog/:id | read | 檢視指定的文章 |
GET | blog/:id/edit | edit | 更新文章的界面 |
PUT | blog/:id | update | 執行更新文章 |
DELETE | blog/:id | delete | 執行删除文章 |
推薦使用資源控制器,來進行增、删、改、查的操作。