如何以及何时在 Laravel 实用代码示例中使用事件监听器
Laravel 的事件系统在处理 Web 应用程序中的复杂数据方面非常出色,因为它是构建解耦且绝对复杂的应用程序的基石。本指南讲述了有关事件监听的实现和利用的极其详细的要点,尤其是在 2024 年,通过 Laravel 11 中最广泛的内容和详细的代码示例事件监听器提供了全新的视角。
*(A) 理解事件和监听器背后的核心
*
那么,让我们来分解一下,Laravel 中的事件确实代表了应用程序内的特定事件。侦听器是响应所有此类应用程序事件的类。这种模式不断促进关注点分离,并允许更多模块化和可测试的代码。
*(B) 创建活动
*
让我们首先创建一个复杂的事件,我们将使用 Artisan 命令来更好地解释我们强烈建议您也这样做
php artisan make:event OrderPlaced
此命令将在 app/Events 目录中生成一个新的事件类。让我们看一下更详细的事件类
`命名空间 AppEvents;
使用AppModelsOrder;
使用 AppModelsUser;
使用 IlluminateFoundationEventsDispatchable;
使用 IlluminateQueueSerializesModels;
使用 IlluminateBroadcastingInteractsWithSockets;
使用 IlluminateBroadcastingPrivateChannel;
使用 IlluminateContractsBroadcastingShouldBroadcast;
类 OrderPlaced 实现 ShouldBroadcast
{
使用 Dispatchable、InteractsWithSockets、SerializesModels;
public $order; public $user; /** * Create a new event instance. * * @param \App\Models\Order $order * @param \App\Models\User $user * @return void */ public function __construct(Order $order, User $user) { $this->order = $order; $this->user = $user; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new PrivateChannel('orders.'.$this->user->id); } /** * The event's broadcast name. * * @return string */ public function broadcastAs() { return 'order.placed'; }
}`
在这个扩展示例中,我们同时包含了 Order 和 User 模型。 SerializesModels 特征一直确保当事件传递给排队的侦听器时,我们的 Eloquent 模型能够正确序列化和反序列化。我们还实现了 ShouldBroadcast 接口,并定义了 broadcastOn 和 broadcastAs 方法,允许将此事件广播到 websockets 进行实时更新。
*创建多个监听器
*
对于单个事件,我们可能需要多个侦听器。让我们为 OrderPlaced 事件创建两个侦听器以进一步扩展示例。我只是希望你们能确保掌握一切的要点。因此,请参阅下面的代码示例
php artisan make:listener SendOrderConfirmation --event=OrderPlaced
php artisan make:listener UpdateInventory --event=OrderPlaced
现在你应该明白这个命令行会在我们的 app/Listeners 目录中为我们提供几个新的监听器类。现在的问题是,在下面,我们将检查 SendOrderConfirmation 侦听器,看看它如何进一步进行
`命名空间 AppListeners;
使用AppEventsOrderPlaced;
使用AppMailOrderConfirmation;
使用 IlluminateContractsQueueShouldQueue;
使用 IlluminateQueueInteractsWithQueue;
使用 IlluminateSupportFacadesMail;
使用 IlluminateSupportFacadesLog;
SendOrderConfirmation 类实现 ShouldQueue
{
使用 InteractsWithQueue;
/** * The number of times the job may be attempted. * * @var int */ public $tries = 3; /** * Handle the event. * * @param \App\Events\OrderPlaced $event * @return void */ public function handle(OrderPlaced $event) { $order = $event->order; $user = $event->user; try { Mail::to($user->email)->send(new OrderConfirmation($order)); Log::info('Order confirmation email sent', ['order_id' => $order->id, 'user_id' => $user->id]); } catch (\Exception $e) { Log::error('Failed to send order confirmation email', ['order_id' => $order->id, 'user_id' => $user->id, 'error' => $e->getMessage()]); $this->fail($e); } } /** * Handle a job failure. * * @param \App\Events\OrderPlaced $event * @param \Throwable $exception * @return void */ public function failed(OrderPlaced $event, $exception) { Log::error('Order confirmation listener failed', ['order_id' => $event->order->id, 'user_id' => $event->user->id, 'error' => $exception->getMessage()]); }
}`
这个监听器已经实现了ShouldQueue接口,表明它应该排队。我们添加了错误处理、日志记录,并定义了失败方法来处理失败。 $tries 属性将设置为允许在失败时进行多次尝试。
现在,让我们看看 UpdateInventory 监听器
`命名空间 AppListeners;
使用AppEventsOrderPlaced;
使用 IlluminateContractsQueueShouldQueue;
使用 IlluminateQueueInteractsWithQueue;
使用 IlluminateSupportFacadesDB;
使用 IlluminateSupportFacadesLog;
类 UpdateInventory 实现 ShouldQueue
{
使用 InteractsWithQueue;
/** * Handle the event. * * @param \App\Events\OrderPlaced $event * @return void */ public function handle(OrderPlaced $event) { $order = $event->order; DB::transaction(function () use ($order) { foreach ($order->items as $item) { $product = $item->product; if ($product->stock < $item->quantity) { throw new \Exception("Insufficient stock for product: {$product->id}"); } $product->decrement('stock', $item->quantity); Log::info("Inventory updated", ['product_id' => $product->id, 'quantity' => $item->quantity]); } }); } /** * Handle a job failure. * * @param \App\Events\OrderPlaced $event * @param \Throwable $exception * @return void */ public function failed(OrderPlaced $event, $exception) { Log::error('Failed to update inventory', ['order_id' => $event->order->id, 'error' => $exception->getMessage()]); }
}`
现在,您应该明白了,这个侦听器的存在是出于一些原因,例如根据订单商品升级库存等。我们将库存更新包装在数据库事务中以确保数据一致性。我们还添加了错误检查以防止负库存,并包括成功更新和失败的日志记录。
*注册事件和听众
*
我们将在 EventServiceProvider
`使用 AppEventsOrderPlaced;
使用 AppListenersSendOrderConfirmation;
使用 AppListenersUpdateInventory;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
OrderPlaced::class => [
SendOrderConfirmation::class,
UpdateInventory::class,
],
];
/** * Register any events for your application. * * @return void */ public function boot() { parent::boot(); // }
}`
Dispatching Events:
We can dispatch the event from a controller or service class
`use App\Events\OrderPlaced;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class OrderController extends Controller
{
/**
* Place a new order.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function placeOrder(Request $request)
{
$user = auth()->user();
DB::transaction(function () use ($request, $user) { $order = Order::create($request->all()); $order->user()->associate($user); $order->save(); event(new OrderPlaced($order, $user)); }); return response()->json(['message' => 'Order placed successfully', 'order_id' => $order->id]); }
}`
In this example, we have wrapped the order creation and event dispatching in a database transaction to ensure that both occur successfully or not at all.
以上是如何以及何时在 Laravel 实用代码示例中使用事件监听器的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)