天天看點

ThinkPHP 5.0 中的控制器

簡介

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 執行删除文章

推薦使用資源控制器,來進行增、删、改、查的操作。