> 事件模式是一種經過了充分測試的可靠機制,是一種非常適用于解耦的機制,用于一個方法內部的復雜程序的解耦
[TOC]
## 安裝組件
~~~
composer require hyperf/event
~~~
## 定義一個事件
~~~
namespace App\Event;
class UserRegistered
{
// 建議這里定義成 public 屬性,以便監聽器對該屬性的直接使用,或者你提供該屬性的 Getter
public $uid;
public function __construct($uid)
{
$this->uid = $uid;
}
}
~~~
## 定義一個監聽器
~~~
namespace App\Listener;
use App\Event\UserRegistered;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
/**
* @Listener
*/
class UserRegisteredListener implements ListenerInterface
{
public function listen(): array
{
// 返回一個該監聽器要監聽的事件數組,可以同時監聽多個事件
return [
UserRegistered::class,
];
}
/**
* @param UserRegistered $event
*/
public function process(object $event)
{
// 事件觸發后該監聽器要執行的代碼寫在這里,比如該示例下的發送用戶注冊成功短信等
// 直接訪問 $event 的 uid 屬性獲得事件觸發時傳遞的參數值
echo 'listener process user:'.$event->uid;
}
}
~~~
## 方法內部解耦(觸發事件)
~~~
namespace App\Service;
use Hyperf\Di\Annotation\Inject;
use Psr\EventDispatcher\EventDispatcherInterface;
use App\Event\UserRegistered;
class UserService
{
/**
* @Inject
* @var EventDispatcherInterface
*/
private $eventDispatcher;
public function register()
{
// 我們假設存在 User 這個實體
$uid = 55;
// 完成賬號注冊的邏輯
// 這里 dispatch(object $event) 會逐個運行監聽該事件的監聽器
$this->eventDispatcher->dispatch(new UserRegistered($uid));
return true;
}
}
~~~
## Controller 調用測試
~~~
declare(strict_types=1);
namespace App\Controller;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController()
*/
class IndexController extends AbstractController
{
/**
* @Inject()
* @var \App\Service\UserService
*/
public $userService;
public function test2()
{
$result = $this->userService->register();
return $result;
}
}
~~~