Laravel 的事件监听器与服务提供者和服务容器的二三事

一. Laravel 的事件监听器与服务提供者和服务容器有密切的关系。

服务提供者用于注册服务、绑定依赖关系以及执行框架的初始化设置。在服务提供者的 register 方法中,可以注册事件和事件监听器。

服务容器则负责管理对象的创建和依赖注入。事件监听器通常会被注册到服务容器中,以便在需要时能够正确地实例化和调用。

例如,当某个事件被触发时,Laravel 会通过服务容器获取对应的事件监听器实例,并执行其处理逻辑。

通过服务提供者将事件和监听器与服务容器进行关联和配置,使得整个框架能够高效地处理事件驱动的逻辑。

案例:

比如有个 UserRegistered 事件,表示用户注册成功。在服务提供者中,可以这样注册监听器:
public function register()
{Event::listen(UserRegistered::class, [UserRegisteredListener::class, 'handle']);
}

当 UserRegistered 事件被触发时,服务容器会实例化 UserRegisteredListener 并调用 handle 方法来处理事件。

再比如说,假设我们有一个 OrderPlaced 事件,表示订单已被下单。

首先创建事件类 OrderPlaced

<?phpnamespace App\Events;use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;class OrderPlaced
{use Dispatchable, InteractsWithSockets, SerializesModels;public $order;public function __construct($order){$this->order = $order;}
}

然后创建对应的事件监听器 OrderPlacedListener

<?phpnamespace App\Listeners;use App\Events\OrderPlaced;class OrderPlacedListener
{public function handle(OrderPlaced $event){// 在此处处理订单下单后的逻辑,比如发送通知邮件$order = $event->order;// 具体的处理逻辑//...}
}

在服务提供者 EventServiceProvider 中注册事件和监听器:

<?phpnamespace App\Providers;use App\Events\OrderPlaced;
use App\Listeners\OrderPlacedListener;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;class EventServiceProvider extends ServiceProvider
{protected $listen = [OrderPlaced::class => [OrderPlacedListener::class],];public function boot(){parent::boot();}
}

当订单下单触发 OrderPlaced 事件时,Laravel 的服务容器会自动实例化 OrderPlacedListener 并调用其 handle 方法来处理相关逻辑。

再比如,有一个 ArticlePublished 事件,表示文章已发布。

事件类 ArticlePublished

<?phpnamespace App\Events;use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;class ArticlePublished
{use Dispatchable, InteractsWithSockets, SerializesModels;public $article;public function __construct($article){$this->article = $article;}
}

监听器 ArticlePublishedListener

<?phpnamespace App\Listeners;use App\Events\ArticlePublished;class ArticlePublishedListener
{public function handle(ArticlePublished $event){// 处理文章发布后的逻辑,比如更新相关统计数据$article = $event->article;// 具体的处理逻辑//...}
}

在服务提供者中注册:

<?phpnamespace App\Providers;use App\Events\ArticlePublished;
use App\Listeners\ArticlePublishedListener;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;class EventServiceProvider extends ServiceProvider
{protected $listen = [ArticlePublished::class => [ArticlePublishedListener::class],];public function boot(){parent::boot();}
}

这样,当 ArticlePublished 事件被触发时,服务容器会按照注册的关系来处理相应的逻辑。

在Laravel中,事件监听器的工作原理基于观察者模式。当一个事件被触发时,Laravel会通知所有注册的监听器,监听器会执行相应的操作。

二. Laravel中事件监听器的详细工作原理:
  1. 事件的定义:事件是一个类,通常位于app/Events目录下。事件类可以包含与事件相关的数据。
  2. 监听器的定义:监听器是一个类,通常位于app/Listeners目录下。监听器类包含处理事件的逻辑。
  3. 注册事件和监听器:在Laravel中,可以在EventServiceProvider类的$listen属性中注册事件和监听器。$listen属性是一个数组,其中键是事件的名称,值是监听器的类名。
  4. 触发事件:在应用程序的任何地方,可以使用event()函数触发事件。event()函数接受一个事件类的实例作为参数。
  5. 通知监听器:当事件被触发时,Laravel会遍历注册的监听器,并执行每个监听器的handle()方法。handle()方法接受一个事件类的实例作为参数,可以在该方法中处理事件。

通过使用事件和监听器,可以将应用程序中的不同部分解耦,使得代码更加易于维护和扩展。

三. 如何在Laravel中定义监听器?

在 Laravel 中定义监听器,您可以按照以下步骤进行:

  1. 创建监听器类

    • 在 app/Listeners 目录下创建一个新的 PHP 类文件。
    • 例如,创建一个名为 OrderPlacedListener.php 的文件。
  2. 编写监听器类的内容

    • 监听器类需要继承 Illuminate\Contracts\Queue\ShouldQueue 接口(如果您希望监听器在队列中异步处理)或不继承(如果要同步处理)。
    • 类中包含一个 handle 方法,用于处理事件。

以下是一个简单的同步监听器示例:

<?phpnamespace App\Listeners;use App\Events\OrderPlaced;class OrderPlacedListener
{/*** 处理订单放置事件** @param  OrderPlaced  $event* @return void*/public function handle(OrderPlaced $event){// 在这里编写处理事件的逻辑$order = $event->order;// 进行相关操作,如发送通知、更新数据库等}
}

如果您希望监听器异步处理,示例如下:

<?phpnamespace App\Listeners;use App\Events\OrderPlaced;
use Illuminate\Contracts\Queue\ShouldQueue;class OrderPlacedListener extends ShouldQueue
{/*** 处理订单放置事件** @param  OrderPlaced  $event* @return void*/public function handle(OrderPlaced $event){// 异步处理的逻辑}
}

这样就完成了一个监听器的定义。然后,您需要在服务提供者中注册这个监听器来使其生效。

在Laravel中,监听器的生命周期由Laravel框架自动管理。当一个事件被触发时,Laravel会自动查找并执行与该事件相关联的监听器。

四. 在 Laravel中,监听器的生命周期是如何管理的?

具体来说,Laravel的事件系统基于观察者模式。当一个事件被触发时,Laravel会通知所有注册的监听器,监听器可以执行相应的操作。监听器可以是一个类或一个闭包函数,它们通过注册到Laravel的事件系统中来接收事件通知。

在Laravel中,你可以使用以下方式来注册监听器:

  • 在服务提供者的boot方法中注册监听器。
  • 在模型的boot方法中注册监听器。
  • 使用Event::listen方法注册监听器。

当你注册监听器后,Laravel会在事件被触发时自动执行监听器的代码。监听器的执行顺序是不确定的,但是它们会按照注册的顺序依次执行。

如果你需要在监听器中执行一些耗时的操作,例如发送邮件或进行数据库操作,你可以将监听器放在队列中异步执行,以提高应用的性能。

五. 在 Laravel中,监听器的执行顺序是怎样的?

在 Laravel 中,监听器的执行顺序是不确定的,但是它们会按照注册的顺序依次执行。

如果你需要在监听器中执行一些耗时的操作,例如发送邮件或进行数据库操作,你可以将监听器放在队列中异步执行,以提高应用的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/30239.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能和机器学习的应用日益广泛,在医疗健康领域的具体应用是什么?

人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;在医疗健康领域的应用日益广泛&#xff0c;涵盖了从疾病预测、辅助诊断、药物研发到健康管理等多个方面。以下是一些具体的应用实例和成功案例&#xff1a; 疾病预测与辅助诊断&#xff1a;机器学习算…

实现Spring Boot中多数据源配置的解决方案

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f525; 微信&#xff1a;zsqtcyw 联系我领取学习资料 …

python实现进度条的方法和实现代码

在Python中&#xff0c;有多种方式可以实现进度条。这里&#xff0c;我将介绍七种常见的方法&#xff1a;使用tqdm&#xff08;这是一个外部库&#xff0c;非常流行且易于使用&#xff09;、rich、click、progressbar2等库以及纯Python的print函数与time库来模拟进度条。 目录…

《STM32 HAL库》小米微电机控制例程——通信协议分析及驱动库

之前有段时间因为机器狗项目的缘故&#xff0c;一直在使用小米微电机&#xff0c;但是苦于没有一个详尽的奶妈级教程&#xff0c;在控制电机的学习中踩了不少的坑。今天咱们就从头至尾一步一步的实现使用按键控制小米微电机。本文将会分析小米电机驱动库&#xff0c;并简要介绍…

Spring Boot 项目中的如何序列化日期格式字符串(对象转JSON的日期字符串格式)

在Spring Boot 项目中, 将Bean序列化为一个JSON字符串的时候, 对于日期类型的属性, 可以直接在属性上使用@JsonFormat即可达成, 但是如果属性本身就是一个日期的字符串, 要输出为另外格式字符串要如何实现呢? @JsonFormat 转换 Timestamp 类型的属性 @JsonFormat注…

linux系统中,pwd获取当前路径,dirname获取上一层路径;不使用 ../获取上一层路径

在实际项目中&#xff0c;我们通常可以使用 pwd 来获取当前路径&#xff0c;但是如果需要获取上一层路径&#xff0c;有不想使用 …/ 的方式&#xff0c;可以尝试使用 dirname指令 测试shell脚本 #!/bin/bash# 获取当前路径 CURRENT_PATH$PWD echo "CURRENT_PATH$CURREN…

练手代码之使用Python实现合并PDF文件

如果你有合并PDF的需要&#xff0c;你会怎么办 我们无所不能的程序员会选择写一个Python代码来实现&#xff08;谁会这么无聊&#xff1f;是我&#xff09;&#xff0c;如果真的有PDF操作需要&#xff0c;我推荐你使用PDF Expert这个软件哈~ 话不多说直接上代码&#xff1a; …

【Ruby简单脚本01】查看wifi密码

脚本 # 使用io库 def get_cmd_result(cmd) IO.popen(cmd,:external_encoding>GBK).read.encode("utf-8") end def list_wifi wifi_pwds Hash.new # 获取所有wifi文件 o1 get_cmd_result("netsh wlan show profiles") # 获取所有匹配结果 …

Linux操作系统学习:day05

内容来自&#xff1a;Linux介绍 视频推荐&#xff1a;[Linux基础入门教程-linux命令-vim-gcc/g -动态库/静态库 -makefile-gdb调试]( 目录 day0530、删除用户31、添加和删除用户组创建用户组删除用户组 32、修改密码33、使用tar工具进行压缩和解压缩压缩解压缩 34、使用zip u…

增强大型语言模型(LLM)可访问性:深入探究在单块AMD GPU上通过QLoRA微调Llama 2的过程

Enhancing LLM Accessibility: A Deep Dive into QLoRA Through Fine-tuning Llama 2 on a single AMD GPU — ROCm Blogs 基于之前的博客《使用LoRA微调Llama 2》的内容&#xff0c;我们深入研究了一种称为量化低秩调整&#xff08;QLoRA&#xff09;的参数高效微调&#xff0…

单片机第五季-第八课:STM32CubeMx和FreeRTOS

1&#xff0c;FreeRTOS背景介绍 RTOS简介&#xff1a; 实时操作系统&#xff0c;本用于追求实时性的嵌入式系统&#xff0c;典型&#xff1a;ucos/uclinux/vxworks&#xff1b; 特点&#xff1a;中断响应快、一般可嵌套中断、使用实地址、多任务&#xff1b; &#xff08;实…

Qt6视频播放器项目框架代码

视频播放的关键代码如下: 使用Qt6的QMediaPlayer,QVideoWidget实现 void FunnyWidget::initVideo() {player = new QMediaPlayer(this);videoWidget = new QVideoWidget(this);playButton = new QPushButton("Play", this);pauseButton = new QPushButton("…

项目的打包

一:打包到微信小程序 1)vscode打包 2)在微信小程序开发工具中打开路径,上传. 疑问:为什么pnpm bulid:mp-weixin用于打包,pnpm dev:mp-weixin也可生成对应路径下的文件?? 打包的是没有热重载,且打包体积更小. 二:条件编译 vscode可以打包成能在不同平台上运行的代码.但是有…

404、左叶子之和

题解&#xff1a;可以采用后序递归遍历的方式&#xff0c;先将左右子树的左叶子节点值计算出来&#xff0c;最后相加。 当遍历到左叶子节点的父节点时就开始处理&#xff0c;将左叶子节点的值记录下来。 代码如下&#xff1a; class Solution { public:int sumOfLeftLeaves(…

算法金 | 再见!!!梯度下降(多图)

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 接前天 李沐&#xff1a;用随机梯度下降来优化人生&#xff01; 今天把达叔 6 脉神剑给佩奇了&#xff0c;上 吴恩达&#xff1a;机器…

利用 Qwen-VL 进行私有化部署第一个 AI 多模态大模型

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

【profinet】从站开发要点

目录 0、常见缩写及关键字注释 1、profinet简介 2、profinet协议栈 3、profinet数据帧 4、profinet网络解决方案示例 5、Application areas 注&#xff1a;本文主要简述profinet从站开发涉及到的知识点。【不足之处后续慢慢补充】。 0、常见缩写及关键字注释 MRP: Media…

Spring中IOC容器

IoC IOC容器 IoC是一种设计思想&#xff0c;面向对象编程 Spring通过IoC管理所有Java对象的实例化和初始化&#xff0c;控制对象之间依赖关系 将IoC容器管理的Java对象称为Spring Bean&#xff0c;与new创建的对象没有区别 控制反转&#xff08;IoC Inversion of Controle&a…

宏观必读:数智化、气候能源、多极化趋势并存,如何获得转型性增长?

关键词速读&#xff1a; 双转型——创新主导的 “新质生产力”正加速推动中国产业的数字化和绿色低碳“双转型”。 双引擎——企业借助“技术创新”和“生态创新”两大引擎&#xff0c;乘势而上&#xff0c;赢得未来机遇。 生成式 AI 与大模型爆发式发展正在引发计算、开发、交…