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 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中文网其他相关文章!

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

PHP不是在消亡,而是在不断适应和进化。1)PHP从1994年起经历多次版本迭代,适应新技术趋势。2)目前广泛应用于电子商务、内容管理系统等领域。3)PHP8引入JIT编译器等功能,提升性能和现代化。4)使用OPcache和遵循PSR-12标准可优化性能和代码质量。

PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。

在PHP中,trait适用于需要方法复用但不适合使用继承的情况。1)trait允许在类中复用方法,避免多重继承复杂性。2)使用trait时需注意方法冲突,可通过insteadof和as关键字解决。3)应避免过度使用trait,保持其单一职责,以优化性能和提高代码可维护性。

依赖注入容器(DIC)是一种管理和提供对象依赖关系的工具,用于PHP项目中。DIC的主要好处包括:1.解耦,使组件独立,代码易维护和测试;2.灵活性,易替换或修改依赖关系;3.可测试性,方便注入mock对象进行单元测试。

SplFixedArray在PHP中是一种固定大小的数组,适用于需要高性能和低内存使用量的场景。1)它在创建时需指定大小,避免动态调整带来的开销。2)基于C语言数组,直接操作内存,访问速度快。3)适合大规模数据处理和内存敏感环境,但需谨慎使用,因其大小固定。

PHP通过$\_FILES变量处理文件上传,确保安全性的方法包括:1.检查上传错误,2.验证文件类型和大小,3.防止文件覆盖,4.移动文件到永久存储位置。

JavaScript中处理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。1.??返回第一个非null或非undefined的操作数。2.??=将变量赋值为右操作数的值,但前提是该变量为null或undefined。这些操作符简化了代码逻辑,提高了可读性和性能。


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

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

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 英文版
推荐:为Win版本,支持代码提示!