이벤트 시스템
ㅋㅋ 단, 이벤트 시스템
- 이벤트 및 리스너 등록
- 이벤트 및 리스너 생성
- 이벤트 수동 등록
- 와일드카드 이벤트 리스너
- 큐에 대한 수동 액세스
- 리스너 정의
- 이벤트 전파 중지
- 이벤트 모니터링 리스너 큐
- 실패한 작업 처리
- 이벤트 구독자 쓰기
- 이벤트 구독자 등록
이벤트 시스템
이벤트 시스템 소개
Laravel의 이벤트는 애플리케이션에서 발생하는 다양한 이벤트를 구독하고 모니터링할 수 있는 간단한 관찰자 구현을 제공합니다. 이벤트 클래스는 일반적으로
app/Events
디렉토리에 저장되며, 이러한 이벤트 클래스의 리스너는app/Listeners
디렉토리에 저장됩니다. 애플리케이션에서 이러한 디렉토리가 보이지 않더라도 걱정하지 마세요. Artisan 콘솔 명령을 사용하여 이벤트와 리스너를 생성할 때 디렉토리가 자동으로 생성됩니다.app/Events
目录下,而这些事件类的监听器则存放在app/Listeners
目录下。如果在你的应用中你没有看到这些目录,不用担心,它们会在你使用 Artisan 控制台命令生成事件与监听器的时候自动创建。事件系统为应用各个方面的解耦提供了非常棒的方法,因为单个事件可以拥有多个互不依赖的监听器。举个例子,你可能希望每次订单发货时向用户推送一个 Slack 通知。你可以简单地发起一个可以被监听器接收并转化为 Slack 通知的
OrderShipped
事件,而不是将订单处理代码和 Slack 通知代码耦合在一起。注册事件和监听器
Laravel 应用中的
이벤트 시스템은 애플리케이션의 다양한 측면을 분리하는 훌륭한 방법을 제공합니다. 단일 이벤트에는 서로 독립적인 여러 리스너가 있을 수 있기 때문입니다. 예를 들어 주문이 배송될 때마다 사용자에게 Slack 알림을 푸시할 수 있습니다. 주문 처리 코드와 Slack 알림 코드를 함께 결합하는 대신 리스너가 수신하여 Slack 알림으로 변환할 수 있는EventServiceProvider
为注册所有的事件监听器提供了一个便利的场所。其中,listen
属性包含了所有事件 (键) 以及事件对应的监听器 (值) 的数组。当然,你可以根据应用的需要,添加多个事件到listen
属性包含的数组中。举个例子,我们来添加一个OrderShipped
OrderShipped
이벤트를 발생시키기만 하면 됩니다.이벤트 및 리스너 등록 🎜🎜Laravel 애플리케이션의 EventServiceProvider code> 모든 이벤트 리스너를 등록할 수 있는 편리한 장소를 제공합니다. 그 중
listen
속성에는 모든 이벤트(키)와 해당 이벤트에 해당하는 리스너(값)의 배열이 포함됩니다. 물론 애플리케이션의 필요에 따라listen
속성에 포함된 배열에 여러 이벤트를 추가할 수 있습니다. 예를 들어OrderShipped
이벤트를 추가해 보겠습니다. 🎜/** * 应用程序的事件监听器映射 * * @var array */ protected $listen = [ 'App\Events\OrderShipped' => [ 'App\Listeners\SendShipmentNotification', ], ];
🎜🎜🎜🎜🎜🎜이벤트 및 리스너 생성
물론 이벤트 및 리스너 파일을 수동으로 생성하는 것은 번거로운 작업입니다. 여기서는
EventServiceProvider
에 리스너와 이벤트를 추가한 다음event:generate
명령을 사용하면 됩니다. 이 명령은EventServiceProvider
에 나열된 모든 이벤트와 리스너를 생성합니다. 물론 기존 이벤트와 청취자는 변경되지 않습니다.EventServiceProvider
中,而后使用event:generate
命令。这个命令会生成在EventServiceProvider
中列出的所有事件和监听器。当然,已经存在的事件和监听器将保持不变:php artisan event:generate
手动注册事件
通常,事件是在
EventServiceProvider
的$listen
数组中注册;然而,你也可以在EventServiceProvider
的boot
方法中手动注册基于闭包的这些事件:/** * 注册应用中的其它事件 * * @return void */ public function boot(){ parent::boot(); Event::listen('event.name', function ($foo, $bar) { // }); }
通配符事件监听器
你可以在注册监听器时使用
*
作为通配符参数,这样可以在同一个监听器上捕获多个事件。通配符监听器接收事件名作为其第一个参数,并将整个事件数据数组作为其第二个参数:Event::listen('event.*', function ($eventName, array $data) { // });
定义事件
事件类是一个保存与事件相关信息的容器。例如,假设我们生成的
OrderShipped
事件接收一个 Eloquent ORM 对象:<?php namespace App\Events; use App\Order; use Illuminate\Queue\SerializesModels; class OrderShipped{ use SerializesModels; public $order; /** * 创建一个事件实例。 * * @param \App\Order $order * @return void */ public function __construct(Order $order) { $this->order = $order; } }
如你所见,这个事件类中没有包含其它逻辑。它只是一个购买的
Order
的实例的容器。如果使用 PHP 的serialize
函数序列化事件对象,事件使用的SerializesModels
trait 将会优雅地序列化任何 Eloquent 模型。定义监听器
接下来,让我们看一下例子中事件的监听器。事件监听器在
handle
方法中接收实例。event:generate
命令会自动加载正确的事件类,并且在handle
方法中加入事件的类型提示。在handle
方法中,你可以执行任何必要的响应事件的操作:<?php namespace App\Listeners; use App\Events\OrderShipped; class SendShipmentNotification{ /** * 创建事件监听器。 * * @return void */ public function __construct() { // } /** * 处理事件。 * * @param \App\Events\OrderShipped $event * @return void */ public function handle(OrderShipped $event) { // 使用 $event->order 来访问 order ... } }
{tip} 你的事件监听器也可以在构造函数中加入任何依赖关系的类型提示。所有的事件监听器都是通过 Laravel 的 服务容器 来解析的,因此所有的依赖都将会被自动注入。
停止事件传播
有时,你可以通过在监听器的
handle
方法中返回false
<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ // }
수동 등록 이벤트EventServiceProvider
의$listen
배열에 등록되지만EventServiceProvider
의에 등록할 수도 있습니다. boot< /code> 메소드의 클로저에 따라 이러한 이벤트를 수동으로 등록합니다: 🎜
<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ /** * The name of the connection the job should be sent to. * * @var string|null */ public $connection = 'sqs'; /** * The name of the queue the job should be sent to. * * @var string|null */ public $queue = 'listeners'; /** * The time (seconds) before the job should be processed. * * @var int */ public $delay = 60; }
🎜와일드카드 이벤트 리스너
🎜리스너를 등록할 수 있습니다 동일한 리스너에서 여러 이벤트를 캡처하려면*
를 와일드카드 매개변수로 사용하세요. 와일드카드 리스너는 이벤트 이름을 첫 번째 인수로 받고 전체 이벤트 데이터 배열을 두 번째 인수로 받습니다. 🎜<?php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ use InteractsWithQueue; /** * 处理事件。 * * @param \App\Events\OrderShipped $event * @return void */ public function handle(OrderShipped $event) { if (true) { $this->release(30); } } }
🎜🎜🎜🎜이벤트 정의
🎜이벤트 클래스는 이벤트와 관련된 정보를 저장하는 컨테이너입니다. 예를 들어, 우리가 생성한OrderShipped
이벤트가 Eloquent ORM 객체를 수신한다고 가정합니다: 🎜<?php namespace App\Listeners;use App\Events\OrderShipped; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue{ use InteractsWithQueue; /** * 处理事件。 * * @param \App\Events\OrderShipped $event * @return void */ public function handle(OrderShipped $event) { // } /** * 处理失败任务。 * * @param \App\Events\OrderShipped $event * @param \Exception $exception * @return void */ public function failed(OrderShipped $event, $exception) { // } }
🎜보시다시피 이 이벤트 클래스에는 다른 로직이 포함되어 있지 않습니다. 이는 단순히Order
의 구매 인스턴스를 위한 컨테이너입니다. 이벤트 객체를 직렬화하기 위해 PHP의serialize
함수를 사용하는 경우, 이벤트에서 사용되는SerializesModels
특성은 모든 Eloquent 모델을 우아하게 직렬화합니다. 🎜🎜🎜🎜🎜리스너 정의
🎜다음으로 예제 이벤트를 살펴보겠습니다. 경청자. 이벤트 리스너는handle
메서드에서 인스턴스를 수신합니다.event:generate
명령은 올바른 이벤트 클래스를 자동으로 로드하고handle
메서드에 이벤트 유형 힌트를 추가합니다.handle
메서드에서는 이벤트에 대한 응답으로 필요한 작업을 수행할 수 있습니다. 🎜<?php namespace App\Http\Controllers; use App\Order;use App\Events\OrderShipped; use App\Http\Controllers\Controller; class OrderController extends Controller{ /** * 将传递过来的订单发货 * * @param int $orderId * @return Response */ public function ship($orderId) { $order = Order::findOrFail($orderId); // 订单发货逻辑 ... event(new OrderShipped($order)); } }
🎜{tip} 이벤트 리스너는 생성자의 모든 종속성에 대한 유형 힌트를 추가할 수도 있습니다. 모든 이벤트 리스너는 Laravel의 서비스 컨테이너를 통해 확인되므로 모든 종속성이 자동으로 주입됩니다. 🎜
🎜이벤트 전파 중지
🎜때때로 리스너에서handle
메소드를 전달할 수 있습니다 다른 리스너가 이벤트를 획득하지 못하도록 하려면false
를 반환하세요. 🎜🎜🎜🎜🎜🎜🎜이벤트 리스너 대기열
리스너가 이메일 전송이나 HTTP 요청과 같은 느린 작업을 수행해야 하는 경우 처리를 위해 대기열에 넣도록 선택할 수 있습니다. 대기열 수신기 사용을 시작하기 전에 서버 또는 로컬 개발 환경에서 대기열을 구성하고 대기열 수신기를 시작할 수 있는지 확인하십시오.
큐를 시작하는 리스너를 지정하려면 리스너 클래스에
ShouldQueue
인터페이스를 추가하면 됩니다. Artisan 명령어event:generate
로 생성된 리스너는 이 인터페이스를 현재 네임스페이스로 가져오므로 직접 사용할 수 있습니다:ShouldQueue
接口。由 Artisan 命令event:generate
生成的监听器已经将此接口导入到当前命名空间中,因此你可以直接使用:<?php namespace App\Listeners; class UserEventSubscriber{ /** * 处理用户登录事件。 */ public function onUserLogin($event) {} /** * 处理用户注销事件。 */ public function onUserLogout($event) {} /** * 为订阅者注册监听器 * * @param \Illuminate\Events\Dispatcher $events */ public function subscribe($events) { $events->listen( 'Illuminate\Auth\Events\Login', 'App\Listeners\UserEventSubscriber@onUserLogin' ); $events->listen( 'Illuminate\Auth\Events\Logout', 'App\Listeners\UserEventSubscriber@onUserLogout' ); } }
就是这个!当这个监听器被事件调用时,事件调度器会自动使用 Laravel 的 队列系统。如果在队列中执行监听器时没有抛出异常,任务会在执行完成后自动从队列中删除。
自定义队列连接 & 队列名称
如果你想要自定义事件监听器所使用的队列的连接和名称,你可以在监听器类中定义
$connection
,$queue
或$delay
属性:<?php namespace App\Providers; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider{ /** * 应用中事件监听器的映射。 * * @var array */ protected $listen = [ // ]; /** * 需要注册的订阅者类。 * * @var array */ protected $subscribe = [ 'App\Listeners\UserEventSubscriber', ]; }
手动访问队列
如果你需要手动访问监听器下面队列任务的
rrreeedelete
和release
方法,你可以通过使用IlluminateQueueInteractsWithQueue
trait 来实现。这个 trait 会默认加载到生成的监听器中,并提供对这些方法的访问:处理失败任务
有时事件监听器的队列任务可能会失败。如果监听器的队列任务超过了队列中定义的最大尝试次数,则会在监听器上调用
rrreeefailed
方法。failed
方法接收事件实例和导致失败的异常作为参数:分发事件
如果要分发事件,你可以将事件实例传递给辅助函数
그렇습니다! 이 리스너가 이벤트에 의해 호출되면 이벤트 디스패처는 자동으로 Laravel의 대기열 시스템을 사용합니다. 대기열에서 리스너를 실행할 때 예외가 발생하지 않으면 실행이 완료된 후 작업이 대기열에서 자동으로 삭제됩니다.event
。该辅助函数将会把事件分发到所有该事件相应的已经注册了的监听器上。event
rrreee사용자 정의 대기열 연결 및 대기열 이름
이벤트 리스너에서 사용하는 대기열의 연결 및 이름을 사용자 정의하려면 리스너 클래스에서$connection
,$queue
또는$delay
속성을 정의할 수 있습니다: rrreee대기열에 대한 수동 액세스
rrreee대기열 작업 삭제에 수동으로 액세스해야 하는 경우 리스너
및release
메소드에서IlluminateQueueInteractsWithQueue
특성을 사용하여 이를 달성할 수 있습니다. 이 특성은 기본적으로 생성된 리스너에 로드되며 다음 메서드에 대한 액세스를 제공합니다:실패한 작업 처리
때때로 이벤트 리스너의 대기열 작업이 실패할 수 있습니다. 리스너의 대기열에 있는 작업이 대기열에 정의된 최대 시도 횟수를 초과하는 경우 리스너에서failed
메서드가 호출됩니다.failed
메소드는 이벤트 인스턴스와 실패를 유발한 예외를 매개변수로 받습니다: rrreee🎜🎜🎜이벤트 배포🎜🎜이벤트를 배포하려면 이벤트 인스턴스를 도우미 함수event
에 전달할 수 있습니다. 이 도우미 함수는 이벤트에 해당하는 모든 등록된 리스너에 이벤트를 배포합니다.event
도우미 함수는 전역적으로 사용할 수 있으며 애플리케이션의 어느 곳에서나 호출할 수 있습니다. 🎜rrreee🎜🎜{tip} 테스트할 때 실제로 트리거하지 않고 특정 이벤트가 전달된다고 주장하기만 하면 됩니다. 경청자. Laravel에 내장된 테스트 도우미를 사용하면 이를 쉽게 수행할 수 있습니다. 🎜🎜🎜🎜🎜🎜🎜🎜🎜이벤트 구독자🎜🎜🎜🎜🎜🎜🎜이벤트 구독자 작성
이벤트 구독자는 자체적으로 여러 이벤트를 구독할 수 있는 클래스입니다. 즉, 단일 클래스에서 여러 이벤트 핸들러를 정의할 수 있습니다. 구독자는 이벤트 디스패처 인스턴스를 수신하는
rrreeesubscribe
메소드를 정의해야 합니다. 특정 이벤트 디스패처에서listen
메소드를 호출하여 이벤트 리스너를 등록할 수 있습니다:subscribe
方法,这个方法接收一个事件分发器实例。你可以调用给定事件分发器上的listen
方法来注册事件监听器:注册事件订阅者
在编写完订阅者之后,就可以通过事件分发器对订阅者进行注册。你可以在
🎜구독자 작성 후, 이벤트 배포자를 통해 구독자를 등록하실 수 있습니다.EventServiceProvider
中的$subscribe
属性中注册订阅者。例如,让我们将UserEventSubscriber
rrreeeEventServiceProvider
의$subscribe
속성에 구독자를 등록할 수 있습니다. 예를 들어 배열 목록에UserEventSubscriber
를 추가해 보겠습니다. 🎜rrreee🎜이 기사는 🎜LearnKu.com🎜 웹사이트에 처음 게재되었습니다. 🎜🎜