ThinkPHP 6 事件的基本使用

Moonshadow2333發表於2022-11-23

一、前言

TP 6 文件很簡潔,很多內容都沒有給出一個完整的例子,事件 這塊內容亦是如此,感覺對新手不是很友好。

二、部落格瀏覽量的例子

(一)前期準備:
1. 定義路由
Route::get('blogs/:id','Blogs/read');
2. 建立控制器

使用命令

php think make:controller Blogs
3. 建立模型

使用命令

php think make:model Blog
4. 建立 think_blog 表
CREATE TABLE `think_blog` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `content` varchar(255) NOT NULL,
  `views` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

表如下所示:
blog.png

5. 模型和控制器的程式碼

Blogs 控制器,引入 Blog 模型類和定義了 read 方法:

<?php
declare (strict_types = 1);

namespace app\controller;

use think\Request;
use app\model\Blog;
use app\handlers\JsonResponseHandler;
class Blogs
{

    /**
     * 顯示指定的資源
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function read($id)
    {
        $blog = Blog::findOrEmpty($id);
        if($blog->isEmpty()){
            return JsonResponseHandler::error('部落格不存在');
        }
        $data = [
            'title'   => $blog->title,
            'content' => $blog->content,
            'views'   => $blog->views
        ];
        return JsonResponseHandler::succ('查詢成功',$data);
    }
}

Blog 模型程式碼:

<?php
declare (strict_types = 1);

namespace app\model;

use think\Model;

/**
 * @mixin \think\Model
 */
class Blog extends Model
{
    protected $name = 'think_blog';
}
(二)事件
1. 定義事件

使用命令列

php think make:event BlogView

預設會生成一個 app\event\BlogView 事件類,修改該類,程式碼如下:

<?php
declare (strict_types = 1);

namespace app\event;
// 引入 Blog 模型
use app\model\Blog;
class BlogView
{
    public $blog;
    public function __construct(Blog $blog)
    {
        $this->blog = $blog;
    }
}
2. 繫結事件
在應用的 event.php 事件定義檔案中批次繫結。

event.php 檔案在 app 目錄下,繫結事件的程式碼如下:

<?php
// 事件定義檔案
return [
    'bind'      => [
        'BlogView' => 'app\event\BlogView',
    ],

    'listen'    => [
        'AppInit'  => [],
        'HttpRun'  => [],
        'HttpEnd'  => [],
        'LogLevel' => [],
        'LogWrite' => [],
    ],

    'subscribe' => [
    ],
];
3. 事件監聽

使用命令列生成事件監聽類:

php think make:listener BlogView

定義事件監聽處理

<?php
declare (strict_types = 1);

namespace app\listener;
class BlogView
{
    /**
     * 事件監聽處理
     *
     * @return mixed
     */
    public function handle($BlogView)
    {
        // 當事件觸發後,瀏覽量+1,並更新資料庫裡面的資料
        $blog = $BlogView->blog;
        $id = $blog->id;
        $views = $blog->views;
        $blog::update(['views'=>$views+1],['id'=>$id]);
    }
}
4. 繫結監聽

在之前提到的 event.php 檔案中進行繫結,具體程式碼如下:

<?php
// 事件定義檔案
return [
    'bind'      => [
        'BlogView' => 'app\event\BlogView',
    ],

    'listen'    => [
        'AppInit'  => [],
        'HttpRun'  => [],
        'HttpEnd'  => [],
        'LogLevel' => [],
        'LogWrite' => [],
        // 繫結監聽
        'BlogView' => ['app\listener\BlogView'],
    ],

    'subscribe' => [
    ],
];
5. 觸發事件

當使用者瀏覽部落格的時候,瀏覽量加一,所以觸發時機應該定義在 Blogs 控制器中的 read 方法,注意讀註釋:

<?php
declare (strict_types = 1);

namespace app\controller;

use think\Request;
use app\model\Blog;
// 引入 BlogView 事件
use app\event\BlogView;
use app\handlers\JsonResponseHandler;
class Blogs
{

    /**
     * 顯示指定的資源
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function read($id)
    {
        $blog = Blog::findOrEmpty($id);
        if($blog->isEmpty()){
            return JsonResponseHandler::error('部落格不存在');
        }
        // 觸發事件
        event(new BlogView($blog));
        $data = [
            'title'   => $blog->title,
            'content' => $blog->content,
            'views'   => $blog->views
        ];
        return JsonResponseHandler::succ('查詢成功',$data);
    }
}
6. 測試

查詢前 id 為 3 的文章的瀏覽數為零
blog.png
查詢
demo.png
查詢後
database-demo.png

參考資料

  1. TP6 文件-事件

相關文章