訪問控制器

ThinkPHP引入了分層控制器的概念,通過URL訪問的控制器為訪問控制器層(Controller)或者主控制器,訪問控制器是由\think\App類負(fù)責(zé)調(diào)用和實例化的,無需手動實例化。

URL解析和路由后,會把當(dāng)前的URL地址解析到 [ 模塊/控制器/操作 ],其實也就是執(zhí)行某個控制器類的某個操作方法,下面是一個示例:

namespace app\index\controller;

class Blog 
{
    public function index()
    {
        return 'index';
    }
    
    public function add()
    {
        return 'add';
    }
    
    public function edit($id)
    {
        return 'edit:'.$id;
    }
}

當(dāng)前定義的主控制器位于index模塊下面,所以當(dāng)訪問不同的URL地址的頁面輸出如下:

http://serverName/index/blog/index // 輸出 index
http://serverName/index/blog/add     // 輸出 add
http://serverName/index/blog/edit/id/5 // 輸出 edit:5

新版的控制器可以不需要繼承任何基類,當(dāng)然,你可以定義一個公共的控制器基礎(chǔ)類來被繼承,也可以通過控制器擴(kuò)展來完成不同的功能(例如Restful實現(xiàn))。

如果不經(jīng)過路由訪問的話,URL中的控制器名會首先強(qiáng)制轉(zhuǎn)為小寫,然后再解析為駝峰法實例化該控制器。

分層控制器

除了訪問控制器外,我們還可以定義其他分層控制器類,這些分層控制器是不能夠被URL訪問直接調(diào)用到的,只能在訪問控制器、模型類的內(nèi)部,或者視圖模板文件中進(jìn)行調(diào)用。

例如,我們定義Blog事件控制器如下:

namespace app\index\event;

class Blog 
{
    public function insert()
    {
        return 'insert';
    }
    
    public function update($id)
    {
        return 'update:'.$id;
    }
    
    public function delete($id)
    {
        return 'delete:'.$id;
    }
}

定義完成后,就可以用下面的方式實例化并調(diào)用方法了:

$event = \think\Loader::controller('Blog', 'event');
echo $event->update(5); // 輸出 update:5
echo $event->delete(5); // 輸出 delete:5

為了方便調(diào)用,系統(tǒng)提供了controller助手函數(shù)直接實例化多層控制器,例如:

$event = controller('Blog', 'event');
echo $event->update(5); // 輸出 update:5
echo $event->delete(5); // 輸出 delete:5

支持跨模塊調(diào)用,例如:

$event = controller('Admin/Blog', 'event');
echo $event->update(5); // 輸出 update:5

表示實例化Admin模塊的Blog控制器類,并執(zhí)行update方法。

除了實例化分層控制器外,還可以直接調(diào)用分層控制器類的某個方法,例如:

echo \think\Loader::action('Blog/update', ['id' => 5], 'event'); // 輸出 update:5

也可以使用助手函數(shù)action實現(xiàn)相同的功能:

echo action('Blog/update', ['id' => 5], 'event'); // 輸出 update:5

利用分層控制器的機(jī)制,我們可以用來實現(xiàn)Widget(其實就是在模板中調(diào)用分層控制器),例如:
定義index\widget\Blog控制器類如下:

namespace app\index\widget;

class Blog {
    public function header()
    {
        return 'header';
    }
    
    public function left()
    {
        return 'left';
    }
    
    public function menu($name)
    {
        return 'menu:'.$name;
    }
}

我們在模板文件中就可以直接調(diào)用app\index\widget\Blog分層控制器了,
使用助手函數(shù)action

{:action('Blog/header', '', 'widget')}
{:action('Blog/menu', ['name' => 'think'], 'widget')}

框架還提供了widget函數(shù)用于簡化Widget控制器的調(diào)用,
可以直接使用助手函數(shù)widget

{:widget('Blog/header')}
{:widget('Blog/menu', ['name' => 'think'])}