hldh214 4年前

修改理由:

的的 -> 的

相关信息:


此投稿已在 4年前 合并。

内容修改:

红色背景 为原始内容

绿色背景 为新增或者修改的内容

OldNewDifferences
1 # Laravel 的事件系统
 1# Laravel 的事件系统
 2
 3- [简介](#introduction)
 4- [注册事件与监听器](#registering-events-and-listeners)
 5   - [生成事件 & 监听器](#generating-events-and-listeners)
 6   - [手动注册事件](#manually-registering-events)
 7- [定义事件](#defining-events)
 8- [定义监听器](#defining-listeners)
 9- [事件监听器队列](#queued-event-listeners)
 10   - [手动访问队列](#manually-accessing-the-queue)
 11   - [处理失败任务](#handling-failed-jobs)
 12- [分发事件](#dispatching-events)
 13- [事件订阅者](#event-subscribers)
 14   - [编写事件订阅者](#writing-event-subscribers)
 15   - [注册事件订阅者](#registering-event-subscribers)
 16
 17<a name="introduction"></a>
 18## 简介
 19
 20Laravel 的事件提供了一个简单的观察者实现,能够订阅和监听应用中发生的各种事件。事件类保存在 `app/Events` 目录中,而这些事件的监听器则被保存在 `app/Listeners` 目录下。这些目录只有当你使用 Artisan 命令来生成事件和监听器时才会被自动创建。
 21
 22事件机制是一种很好的应用解耦方式,因为一个事件可以拥有多个互不依赖的监听器。例如,如果你希望每次订单发货时向用户发送一个 Slack 通知。你可以简单地发起一个 `OrderShipped` 事件,让监听器接收之后转化成一个 Slack 通知,这样你就可以不用把订单的业务代码跟 Slack 通知的代码耦合在一起了。
 23
 24<a name="registering-events-and-listeners"></a>
 25## 注册事件和监听器
 26
 27Laravel 应用中的 `EventServiceProvider` 有个 `listen` 数组包含所有的事件(键)以及事件对应的监听器(值)来注册所有的事件监听器,可以灵活地根据需求来添加事件。例如,让我们增加一个 `OrderShipped` 事件:
 28
 29````
 30/**
 31* 应用程序的事件监听器映射。
 32*
 33* @var array
 34*/
 35protected $listen = [
 36   'App\Events\OrderShipped' => [
 37       'App\Listeners\SendShipmentNotification',
 38   ],
 39];
 40````
 41
 42<a name="generating-events-and-listeners"></a>
 43### 生成事件 & 监听器
 44
 45为每个事件和监听器手动创建文件是件很麻烦的事情,而在这里,你只需将监听器和事件添加到 `EventServiceProvider` 中,再使用 `event:generate` 命令即可。这个命令会生成在 `EventServiceProvider` 中列出的所有事件和监听器。当然,已经存在的事件和监听器将保持不变:
 46
 47````
 48php artisan event:generate
 49````
 50
 51<a name="manually-registering-events"></a>
 52### 手动注册事件
 53
 54事件通常是在 `EventServiceProvider` 类的 `$listen` 数组中注册,但是,你也可以在 `EventServiceProvider` 类的 `boot` 方法中注册基于事件的闭包。
 55
 56````
 57/**
 58* 注册应用程序中的任何其他事件。
 59*
 60* @return void
 61*/
 62public function boot()
 63{
 64   parent::boot();
 65
 66   Event::listen('event.name', function ($foo, $bar) {
 67       //
 68   });
 69}
 70````
 71
 72#### 通配符事件监听器
 73
 74你可以在注册监听器时使用 `*` 通配符参数,这样能够在同一个监听器上捕获多个事件。通配符监听器接受事件名称作为其第一个参数,并将整个事件数据数组作为其第二个参数:
 75
 76````
 77Event::listen('event.*', function ($eventName, array $data) {
 78   //
 79});
 80````
 81
 82<a name="defining-events"></a>
 83## 定义事件
 84
 85事件类其实就只是一个保存与事件相关的信息的数据容器。例如,假设我们生成的 `OrderShipped` 事件接收一个 [Eloquent ORM](/docs/{{version}}/eloquent) 对象:
 86
 87````
 88<?php
 89
 90namespace App\Events;
 91
 92use App\Order;
 93use Illuminate\Queue\SerializesModels;
 94
 95class OrderShipped
 96{
 97   use SerializesModels;
 98
 99   public $order;
 100
 101   /**
 102    * 创建一个事件实例。
 103    *
 104    * @param Order $order
 105    * @return void
 106    */
 107   public function __construct(Order $order)
 108   {
 109       $this->order = $order;
 110   }
 111}
 112````
 113
 114正如你所见,这个事件类中没有包含其它逻辑。它只是一个被构建的 `Order` 对象的容器。如果使用 PHP 的 `serialize` 函数序列化事件对象,事件使用的 `SerializesModels` trait 将会优雅地序列化任何 Eloquent 模型。
 115
 116<a name="defining-listeners"></a>
 117## 定义监听器
 118
 119接下来,让我们看一下例子中事件的监听器。事件监听器在 `handle` 方法中接收事件实例。 `event:generate` 命令会自动加载正确的事件类和在 `handle` 加入的类型提示。在 `handle` 方法中,你可以执行任何必要的响应事件的操作:
 120
 121````
 122<?php
 123
 124namespace App\Listeners;
 125
 126use App\Events\OrderShipped;
 127
 128class SendShipmentNotification
 129{
 130   /**
 131    * 创建事件监听器。
 132    *
 133    * @return void
 134    */
 135   public function __construct()
 136   {
 137       //
 138   }
 139
 140   /**
 141    * 处理事件
 142    *
 143    * @param OrderShipped $event
 144    * @return void
 145    */
 146   public function handle(OrderShipped $event)
 147   {
 148       // 使用 $event->order 来访问 order ...
 149   }
 150}
 151````
 152
 153> {tip} 你的事件监听器也可以在构造函数中加入任何依赖关系的类型提示。所有的事件监听器都是通过 Laravel 的 [服务容器](/docs/{{version}}/container) 来解析的,因此所有的依赖都将会被自动注入。
 154
 155#### 停止事件传播
 156
 157你可以通过在监听器的 `handle` 方法中返回 `false` 来阻止事件被其他的监听器获取。
 158
 159<a name="queued-event-listeners"></a>
 160## 事件监听器队列
 161
 162如果你的监听器中要执行诸如发送邮件或者进行 HTTP 请求等比较慢的任务,你可以选择将其丢给队列处理。在开始使用监听器队列之前,请确保在你的服务器或本地开发环境中能够配置并启动 [队列](/docs/{{version}}/queues) 监听器。
 163
 164要指定监听器启动队列,只需将 `ShouldQueue` 接口添加到监听器类。由 Artisan 命令 `event:generate` 生成的监听器已经将此接口导入到当前命名空间中,因此你可以直接使用它:
 165
 166````
 167<?php
 168
 169namespace App\Listeners;
 170
 171use App\Events\OrderShipped;
 172use Illuminate\Contracts\Queue\ShouldQueue;
 173
 174class SendShipmentNotification implements ShouldQueue
 175{
 176   //
 177}
 178````
 179
 180当这个监听器被事件调用时,事件调度器会自动使用 Laravel 的 [队列系统](/docs/{{version}}/queues)。如果在队列中执行监听器时没有抛出异常,任务会在执行完成后自动从队列中删除。
 181
 182#### 自定义队列的连接和名称
 183
 184如果你想要自定义事件监听器使用的队列的连接和名称,可以在监听器类中定义 `$connection` 和 `$queue` 属性。
 185
 186````
 187<?php
 188
 189namespace App\Listeners;
 190
 191use App\Events\OrderShipped;
 192use Illuminate\Contracts\Queue\ShouldQueue;
 193
 194class SendShipmentNotification implements ShouldQueue
 195{
 196   /**
 197    * 任务应该发送到的队列的连接的名称
 198    *
 199    * @var string|null
 200    */
 201   public $connection = 'sqs';
 202
 203   /**
 204    * 任务应该发送到的队列的名称
 205    *
 206    * @var string|null
 207    */
 208   public $queue = 'listeners';
 209}
 210````
 211
 212<a name="manually-accessing-the-queue"></a>
 213### 手动访问队列
 214
 215如果你需要手动访问监听器下面队列任务的 `delete` 和 `release` 方法,你可以添加 `Illuminate\Queue\InteractsWithQueue` trait 来实现。这个 trait 会默认加载到生成的监听器中,并提供对这些方法的访问:
 216
 217````
 218<?php
 219
 220namespace App\Listeners;
 221
 222use App\Events\OrderShipped;
 223use Illuminate\Queue\InteractsWithQueue;
 224use Illuminate\Contracts\Queue\ShouldQueue;
 225
 226class SendShipmentNotification implements ShouldQueue
 227{
 228   use InteractsWithQueue;
 229
 230   /**
 231    * Handle the event.
 232    *
 233    * @param \App\Events\OrderShipped $event
 234    * @return void
 235    */
 236   public function handle(OrderShipped $event)
 237   {
 238       if (true) {
 239           $this->release(30);
 240       }
 241}
 242````
 243
 244<a name="handling-failed-jobs"></a>
 245### 处理失败任务
 246
 247事件监听器的队列任务可能会失败,而如果监听器的队列任务超过了队列中定义的最大尝试次数,则会监听器上调用 `failed` 方法。`failed` 方法接受接收事件实例和导致失败的异常作为参数:
 248
 249````
 250<?php
 251
 252namespace App\Listeners;
 253
 254use App\Events\OrderShipped;
 255use Illuminate\Queue\InteractsWithQueue;
 256use Illuminate\Contracts\Queue\ShouldQueue;
 257
 258class SendShipmentNotification implements ShouldQueue
 259{
 260   use InteractsWithQueue;
 261
 262   /**
 263    * 处理事件
 264    *
 265    * @param \App\Events\OrderShipped $event
 266    * @return void
 267    */
 268   public function handle(OrderShipped $event)
 269   {
 270       //
 271   }
 272
 273   /**
 274    * 处理任务失败
 275    *
 276    * @param \App\Events\OrderShipped $event
 277    * @param \Exception $exception
 278    * @return void
 279    */
 280   public function failed(OrderShipped $event, $exception)
 281   {
 282       //
 283   }
 284}
 285````
 286
 287<a name="dispatching-events"></a>
 288## 分发事件
 289
 290如果要分发事件,你可以将事件实例传递给辅助函数 `event`。这个函数将会把事件分发到所有已经注册的监听器上。因为辅助函数 `event` 是全局可访问的,所以你可以在应用中的任何地方调用它:
 291
 292````
 293<?php
 294
 295namespace App\Http\Controllers;
 296
 297use App\Order;
 298use App\Events\OrderShipped;
 299use App\Http\Controllers\Controller;
 300
 301class OrderController extends Controller
 302{
 303   /**
 304    * 将传递过来的订单发货。
 305    *
 306    * @param int $orderId
 307    * @return Response
 308    */
 309   public function ship($orderId)
 310   {
 311       $order = Order::findOrFail($orderId);
 312
 313       // 订单的发货逻辑...
 314
 315       event(new OrderShipped($order));
 316   }
 317}
 318````
 319
 320> {tip} 在测试时,Laravel [内置的测试辅助函数](/docs/{{version}}/mocking#mocking-events) 能不需要实际触发监听器就能对事件类型断言。
 321
 322<a name="event-subscribers"></a>
 323## 事件订阅者
 324
 325<a name="writing-event-subscribers"></a>
 326### 编写事件订阅者
 327
 328事件订阅者是一个可以在自身内部订阅多个事件的类,即能够在单个类中定义多个事件处理器。订阅者应该定义一个 `subscribe` 方法,这个方法接受一个事件分发器的实例。你可以调用给定的事件分发器上的 `listen` 方法来注册事件监听器:
 329
 330````
 331<?php
 332
 333namespace App\Listeners;
 334
 335class UserEventSubscriber
 336{
 337   /**
 338    * 处理用户登录事件。
 339    */
 340   public function onUserLogin($event) {}
 341
 342   /**
 343    * 处理用户注销事件。
 344    */
 345   public function onUserLogout($event) {}
 346
 347   /**
 348    * 为订阅者注册监听器。
 349    *
 350    * @param Illuminate\Events\Dispatcher $events
 351    */
 352   public function subscribe($events)
 353   {
 354       $events->listen(
 355           'Illuminate\Auth\Events\Login',
 356           'App\Listeners\UserEventSubscriber@onUserLogin'
 357       );
 358
 359       $events->listen(
 360           'Illuminate\Auth\Events\Logout',
 361           'App\Listeners\UserEventSubscriber@onUserLogout'
 362       );
 363   }
 364
 365}
 366````
 367
 368<a name="registering-event-subscribers"></a>
 369### 注册事件订阅者
 370
 371订阅者写好后,就将其注册到事件分发器中。你可以在 `EventServiceProvider` 类的 `$subscribe` 属性中注册订阅者。例如,将 `UserEventSubscriber` 添加到数组列表中:
 372
 373````
 374<?php
 375
 376namespace App\Providers;
 377
 378use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
 379
 380class EventServiceProvider extends ServiceProvider
 381{
 382   /**
 383    * 应用中事件监听器的映射。
 384    *
 385    * @var array
 386    */
 387   protected $listen = [
 388       //
 389   ];
 390
 391   /**
 392    * 需要注册的订阅者类。
 393    *
 394    * @var array
 395    */
 396   protected $subscribe = [
 397       'App\Listeners\UserEventSubscriber',
 398   ];
 399}
 400````
 401
 402## 译者署名
 403
 404| 用户名 | 头像 | 职能 | 签名 |
 405|---|---|---|---|
 406| [@JokerLinly](https://learnku.com/users/5350) | <img class="avatar-66 rm-style" src="https://cdn.learnku.com/uploads/avatars/5350_1481857380.jpg"> | 翻译 | Stay Hungry. Stay Foolish. |
 407
 408---
 409
 410> {note} 欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
 411>
 412> 转载请注明:本文档由 Laravel China 社区 [laravel-china.org](https://laravel-china.org) 组织翻译,详见 [翻译召集帖](https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation)。
 413>
 414> 文档永久地址: https://learnku.com/docs/laravel
2415
3 - [简介](#introduction) 
4 - [注册事件与监听器](#registering-events-and-listeners) 
5    - [生成事件 & 监听器](#generating-events-and-listeners) 
6    - [手动注册事件](#manually-registering-events) 
7 - [定义事件](#defining-events) 
8 - [定义监听器](#defining-listeners) 
9 - [事件监听器队列](#queued-event-listeners) 
10    - [手动访问队列](#manually-accessing-the-queue) 
11    - [处理失败任务](#handling-failed-jobs) 
12 - [分发事件](#dispatching-events) 
13 - [事件订阅者](#event-subscribers) 
14    - [编写事件订阅者](#writing-event-subscribers) 
15    - [注册事件订阅者](#registering-event-subscribers) 
16  
17 <a name="introduction"></a> 
18 ## 简介 
19  
20 Laravel 的事件提供了一个简单的观察者实现,能够订阅和监听应用中发生的各种事件。事件类保存在 `app/Events` 目录中,而这些事件的的监听器则被保存在 `app/Listeners` 目录下。这些目录只有当你使用 Artisan 命令来生成事件和监听器时才会被自动创建。 
21  
22 事件机制是一种很好的应用解耦方式,因为一个事件可以拥有多个互不依赖的监听器。例如,如果你希望每次订单发货时向用户发送一个 Slack 通知。你可以简单地发起一个 `OrderShipped` 事件,让监听器接收之后转化成一个 Slack 通知,这样你就可以不用把订单的业务代码跟 Slack 通知的代码耦合在一起了。 
23  
24 <a name="registering-events-and-listeners"></a> 
25 ## 注册事件和监听器 
26  
27 Laravel 应用中的 `EventServiceProvider` 有个 `listen` 数组包含所有的事件(键)以及事件对应的监听器(值)来注册所有的事件监听器,可以灵活地根据需求来添加事件。例如,让我们增加一个 `OrderShipped` 事件: 
28  
29 ```` 
30 /** 
31 * 应用程序的事件监听器映射。 
32 * 
33 * @var array 
34 */ 
35 protected $listen = [ 
36    'App\Events\OrderShipped' => [ 
37        'App\Listeners\SendShipmentNotification', 
38    ], 
39 ]; 
40 ```` 
41  
42 <a name="generating-events-and-listeners"></a> 
43 ### 生成事件 & 监听器 
44  
45 为每个事件和监听器手动创建文件是件很麻烦的事情,而在这里,你只需将监听器和事件添加到 `EventServiceProvider` 中,再使用 `event:generate` 命令即可。这个命令会生成在 `EventServiceProvider` 中列出的所有事件和监听器。当然,已经存在的事件和监听器将保持不变: 
46  
47 ```` 
48 php artisan event:generate 
49 ```` 
50  
51 <a name="manually-registering-events"></a> 
52 ### 手动注册事件 
53  
54 事件通常是在 `EventServiceProvider` 类的 `$listen` 数组中注册,但是,你也可以在 `EventServiceProvider` 类的 `boot` 方法中注册基于事件的闭包。 
55  
56 ```` 
57 /** 
58 * 注册应用程序中的任何其他事件。 
59 * 
60 * @return void 
61 */ 
62 public function boot() 
63 { 
64    parent::boot(); 
65  
66    Event::listen('event.name', function ($foo, $bar) { 
67        // 
68    }); 
69 } 
70 ```` 
71  
72 #### 通配符事件监听器 
73  
74 你可以在注册监听器时使用 `*` 通配符参数,这样能够在同一个监听器上捕获多个事件。通配符监听器接受事件名称作为其第一个参数,并将整个事件数据数组作为其第二个参数: 
75  
76 ```` 
77 Event::listen('event.*', function ($eventName, array $data) { 
78    // 
79 }); 
80 ```` 
81  
82 <a name="defining-events"></a> 
83 ## 定义事件 
84  
85 事件类其实就只是一个保存与事件相关的信息的数据容器。例如,假设我们生成的 `OrderShipped` 事件接收一个 [Eloquent ORM](/docs/{{version}}/eloquent) 对象: 
86  
87 ```` 
88 <?php 
89  
90 namespace App\Events; 
91  
92 use App\Order; 
93 use Illuminate\Queue\SerializesModels; 
94  
95 class OrderShipped 
96 { 
97    use SerializesModels; 
98  
99    public $order; 
100  
101    /** 
102     * 创建一个事件实例。 
103     * 
104     * @param Order $order 
105     * @return void 
106     */ 
107    public function __construct(Order $order) 
108    { 
109        $this->order = $order; 
110    } 
111 } 
112 ```` 
113  
114 正如你所见,这个事件类中没有包含其它逻辑。它只是一个被构建的 `Order` 对象的容器。如果使用 PHP 的 `serialize` 函数序列化事件对象,事件使用的 `SerializesModels` trait 将会优雅地序列化任何 Eloquent 模型。 
115  
116 <a name="defining-listeners"></a> 
117 ## 定义监听器 
118  
119 接下来,让我们看一下例子中事件的监听器。事件监听器在 `handle` 方法中接收事件实例。 `event:generate` 命令会自动加载正确的事件类和在 `handle` 加入的类型提示。在 `handle` 方法中,你可以执行任何必要的响应事件的操作: 
120  
121 ```` 
122 <?php 
123  
124 namespace App\Listeners; 
125  
126 use App\Events\OrderShipped; 
127  
128 class SendShipmentNotification 
129 { 
130    /** 
131     * 创建事件监听器。 
132     * 
133     * @return void 
134     */ 
135    public function __construct() 
136    { 
137        // 
138    } 
139  
140    /** 
141     * 处理事件 
142     * 
143     * @param OrderShipped $event 
144     * @return void 
145     */ 
146    public function handle(OrderShipped $event) 
147    { 
148        // 使用 $event->order 来访问 order ... 
149    } 
150 } 
151 ```` 
152  
153 > {tip} 你的事件监听器也可以在构造函数中加入任何依赖关系的类型提示。所有的事件监听器都是通过 Laravel 的 [服务容器](/docs/{{version}}/container) 来解析的,因此所有的依赖都将会被自动注入。 
154  
155 #### 停止事件传播 
156  
157 你可以通过在监听器的 `handle` 方法中返回 `false` 来阻止事件被其他的监听器获取。 
158  
159 <a name="queued-event-listeners"></a> 
160 ## 事件监听器队列 
161  
162 如果你的监听器中要执行诸如发送邮件或者进行 HTTP 请求等比较慢的任务,你可以选择将其丢给队列处理。在开始使用监听器队列之前,请确保在你的服务器或本地开发环境中能够配置并启动 [队列](/docs/{{version}}/queues) 监听器。 
163  
164 要指定监听器启动队列,只需将 `ShouldQueue` 接口添加到监听器类。由 Artisan 命令 `event:generate` 生成的监听器已经将此接口导入到当前命名空间中,因此你可以直接使用它: 
165  
166 ```` 
167 <?php 
168  
169 namespace App\Listeners; 
170  
171 use App\Events\OrderShipped; 
172 use Illuminate\Contracts\Queue\ShouldQueue; 
173  
174 class SendShipmentNotification implements ShouldQueue 
175 { 
176    // 
177 } 
178 ```` 
179  
180 当这个监听器被事件调用时,事件调度器会自动使用 Laravel 的 [队列系统](/docs/{{version}}/queues)。如果在队列中执行监听器时没有抛出异常,任务会在执行完成后自动从队列中删除。 
181  
182 #### 自定义队列的连接和名称 
183  
184 如果你想要自定义事件监听器使用的队列的连接和名称,可以在监听器类中定义 `$connection` 和 `$queue` 属性。 
185  
186 ```` 
187 <?php 
188  
189 namespace App\Listeners; 
190  
191 use App\Events\OrderShipped; 
192 use Illuminate\Contracts\Queue\ShouldQueue; 
193  
194 class SendShipmentNotification implements ShouldQueue 
195 { 
196    /** 
197     * 任务应该发送到的队列的连接的名称 
198     * 
199     * @var string|null 
200     */ 
201    public $connection = 'sqs'; 
202  
203    /** 
204     * 任务应该发送到的队列的名称 
205     * 
206     * @var string|null 
207     */ 
208    public $queue = 'listeners'; 
209 } 
210 ```` 
211  
212 <a name="manually-accessing-the-queue"></a> 
213 ### 手动访问队列 
214  
215 如果你需要手动访问监听器下面队列任务的 `delete` 和 `release` 方法,你可以添加 `Illuminate\Queue\InteractsWithQueue` trait 来实现。这个 trait 会默认加载到生成的监听器中,并提供对这些方法的访问: 
216  
217 ```` 
218 <?php 
219  
220 namespace App\Listeners; 
221  
222 use App\Events\OrderShipped; 
223 use Illuminate\Queue\InteractsWithQueue; 
224 use Illuminate\Contracts\Queue\ShouldQueue; 
225  
226 class SendShipmentNotification implements ShouldQueue 
227 { 
228    use InteractsWithQueue; 
229  
230    /** 
231     * Handle the event. 
232     * 
233     * @param \App\Events\OrderShipped $event 
234     * @return void 
235     */ 
236    public function handle(OrderShipped $event) 
237    { 
238        if (true) { 
239            $this->release(30); 
240        } 
241 } 
242 ```` 
243  
244 <a name="handling-failed-jobs"></a> 
245 ### 处理失败任务 
246  
247 事件监听器的队列任务可能会失败,而如果监听器的队列任务超过了队列中定义的最大尝试次数,则会监听器上调用 `failed` 方法。`failed` 方法接受接收事件实例和导致失败的异常作为参数: 
248  
249 ```` 
250 <?php 
251  
252 namespace App\Listeners; 
253  
254 use App\Events\OrderShipped; 
255 use Illuminate\Queue\InteractsWithQueue; 
256 use Illuminate\Contracts\Queue\ShouldQueue; 
257  
258 class SendShipmentNotification implements ShouldQueue 
259 { 
260    use InteractsWithQueue; 
261  
262    /** 
263     * 处理事件 
264     * 
265     * @param \App\Events\OrderShipped $event 
266     * @return void 
267     */ 
268    public function handle(OrderShipped $event) 
269    { 
270        // 
271    } 
272  
273    /** 
274     * 处理任务失败 
275     * 
276     * @param \App\Events\OrderShipped $event 
277     * @param \Exception $exception 
278     * @return void 
279     */ 
280    public function failed(OrderShipped $event, $exception) 
281    { 
282        // 
283    } 
284 } 
285 ```` 
286  
287 <a name="dispatching-events"></a> 
288 ## 分发事件 
289  
290 如果要分发事件,你可以将事件实例传递给辅助函数 `event`。这个函数将会把事件分发到所有已经注册的监听器上。因为辅助函数 `event` 是全局可访问的,所以你可以在应用中的任何地方调用它: 
291  
292 ```` 
293 <?php 
294  
295 namespace App\Http\Controllers; 
296  
297 use App\Order; 
298 use App\Events\OrderShipped; 
299 use App\Http\Controllers\Controller; 
300  
301 class OrderController extends Controller 
302 { 
303    /** 
304     * 将传递过来的订单发货。 
305     * 
306     * @param int $orderId 
307     * @return Response 
308     */ 
309    public function ship($orderId) 
310    { 
311        $order = Order::findOrFail($orderId); 
312  
313        // 订单的发货逻辑... 
314  
315        event(new OrderShipped($order)); 
316    } 
317 } 
318 ```` 
319  
320 > {tip} 在测试时,Laravel [内置的测试辅助函数](/docs/{{version}}/mocking#mocking-events) 能不需要实际触发监听器就能对事件类型断言。 
321  
322 <a name="event-subscribers"></a> 
323 ## 事件订阅者 
324  
325 <a name="writing-event-subscribers"></a> 
326 ### 编写事件订阅者 
327  
328 事件订阅者是一个可以在自身内部订阅多个事件的类,即能够在单个类中定义多个事件处理器。订阅者应该定义一个 `subscribe` 方法,这个方法接受一个事件分发器的实例。你可以调用给定的事件分发器上的 `listen` 方法来注册事件监听器: 
329  
330 ```` 
331 <?php 
332  
333 namespace App\Listeners; 
334  
335 class UserEventSubscriber 
336 { 
337    /** 
338     * 处理用户登录事件。 
339     */ 
340    public function onUserLogin($event) {} 
341  
342    /** 
343     * 处理用户注销事件。 
344     */ 
345    public function onUserLogout($event) {} 
346  
347    /** 
348     * 为订阅者注册监听器。 
349     * 
350     * @param Illuminate\Events\Dispatcher $events 
351     */ 
352    public function subscribe($events) 
353    { 
354        $events->listen( 
355            'Illuminate\Auth\Events\Login', 
356            'App\Listeners\UserEventSubscriber@onUserLogin' 
357        ); 
358  
359        $events->listen( 
360            'Illuminate\Auth\Events\Logout', 
361            'App\Listeners\UserEventSubscriber@onUserLogout' 
362        ); 
363    } 
364  
365 } 
366 ```` 
367  
368 <a name="registering-event-subscribers"></a> 
369 ### 注册事件订阅者 
370  
371 订阅者写好后,就将其注册到事件分发器中。你可以在 `EventServiceProvider` 类的 `$subscribe` 属性中注册订阅者。例如,将 `UserEventSubscriber` 添加到数组列表中: 
372  
373 ```` 
374 <?php 
375  
376 namespace App\Providers; 
377  
378 use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; 
379  
380 class EventServiceProvider extends ServiceProvider 
381 { 
382    /** 
383     * 应用中事件监听器的映射。 
384     * 
385     * @var array 
386     */ 
387    protected $listen = [ 
388        // 
389    ]; 
390  
391    /** 
392     * 需要注册的订阅者类。 
393     * 
394     * @var array 
395     */ 
396    protected $subscribe = [ 
397        'App\Listeners\UserEventSubscriber', 
398    ]; 
399 } 
400 ```` 
401  
402 ## 译者署名 
403  
404 | 用户名 | 头像 | 职能 | 签名 | 
405 |---|---|---|---| 
406 | [@JokerLinly](https://learnku.com/users/5350) | <img class="avatar-66 rm-style" src="https://cdn.learnku.com/uploads/avatars/5350_1481857380.jpg"> | 翻译 | Stay Hungry. Stay Foolish. | 
407  
408 --- 
409  
410 > {note} 欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。 
411 > 
412 > 转载请注明:本文档由 Laravel China 社区 [laravel-china.org](https://laravel-china.org) 组织翻译,详见 [翻译召集帖](https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation)。 
413 > 
414 > 文档永久地址: https://learnku.com/docs/laravel 
415