当前位置: 首页 > news >正文

Thinkphp5 + Swoole实现邮箱异步通知

 在 ThinkPHP 中实现邮箱异步通知的常见做法是通过队列系统来处理异步任务,结合 Swoole 来处理异步发送邮件的请求。这样可以避免同步处理邮件发送导致的阻塞,提高响应速度。

以下是基于 ThinkPHP5 框架和 Swoole 的异步邮件通知实现步骤:

一、安装 Swoole

首先,你需要确保 Swoole 已经正确安装,可以通过 Composer 安装:

pecl install swoole

二、邮件发送配置

和 Redis 队列的方案一样,我们需要先配置邮件发送,还是使用 PHPMailer 或者其他的邮件库来发送邮件。

在项目的 config.php 中配置邮件相关信息:

return ['email' => ['host' => 'smtp.example.com','username' => 'your-email@example.com','password' => 'your-password','port' => 465,'from' => 'your-email@example.com','from_name' => 'Your Name',],
];

三、创建邮件服务类

邮件服务类 MailService 负责处理邮件发送的逻辑。这里使用 PHPMailer 作为邮件发送工具。

application/common/service/MailService.php

<?phpnamespace app\common\service;use PHPMailer\PHPMailer\PHPMailer;
use think\facade\Config;class MailService
{public static function sendMail($to, $subject, $body){$mail = new PHPMailer(true);try {$mail->isSMTP();$mail->Host       = Config::get('email.host');$mail->SMTPAuth   = true;$mail->Username   = Config::get('email.username');$mail->Password   = Config::get('email.password');$mail->SMTPSecure = 'ssl'; $mail->Port       = Config::get('email.port');$mail->setFrom(Config::get('email.from'), Config::get('email.from_name'));$mail->addAddress($to);$mail->isHTML(true);$mail->Subject = $subject;$mail->Body    = $body;$mail->send();return true;} catch (\Exception $e) {return $mail->ErrorInfo;}}
}

四、使用 Swoole 实现异步任务

1. 创建 Swoole Server

在项目的 command 目录下创建 SwooleServer.php,用于处理 Swoole 的服务和任务。

<?phpnamespace app\command;use Swoole\Server;
use app\common\service\MailService;
use think\console\Command;
use think\console\Input;
use think\console\Output;class SwooleServer extends Command
{protected function configure(){$this->setName('swoole:server')->setDescription('Start Swoole Server');}protected function execute(Input $input, Output $output){$server = new Server("127.0.0.1", 9501);// 设置 Swoole 的配置$server->set(['worker_num' => 4,'task_worker_num' => 4,]);// 当有客户端连接时触发$server->on('receive', function (Server $server, $fd, $reactor_id, $data) {// 处理客户端发送的任务数据$taskData = json_decode($data, true);if ($taskData && isset($taskData['to'], $taskData['subject'], $taskData['body'])) {// 投递任务给 Task Worker$server->task($taskData);}$server->send($fd, "Mail task received.");});// 处理异步任务$server->on('task', function (Server $server, $task_id, $from_worker_id, $data) {// 使用 MailService 发送邮件$result = MailService::sendMail($data['to'], $data['subject'], $data['body']);// 返回任务处理结果$server->finish($result);});// 任务处理完成时触发$server->on('finish', function (Server $server, $task_id, $data) {// 任务完成后的逻辑});$output->writeln('Swoole Server started.');// 启动 Swoole Server$server->start();}
}
2. 注册 Swoole 命令

application/command.php 中注册 SwooleServer 命令:

return ['app\command\SwooleServer',
];
3. 启动 Swoole Server

使用命令行启动 Swoole Server:

php think swoole:server

Swoole 服务器启动后,它将监听 127.0.0.1:9501,客户端可以通过这个端口向服务器发送任务请求。

五、在控制器中使用 Swoole 异步发送邮件

现在我们可以在控制器中通过向 Swoole Server 发送请求来处理异步邮件通知。

application/controller/UserController.php

<?phpnamespace app\controller;use Swoole\Client;
use think\Controller;class UserController extends Controller
{public function register(){// 用户注册逻辑$email = 'user@example.com';$subject = '欢迎注册';$body = '感谢您注册我们的网站!';// 创建一个 Swoole 客户端$client = new Client(SWOOLE_SOCK_TCP);// 连接到 Swoole Serverif ($client->connect('127.0.0.1', 9501, 0.5)) {// 发送任务数据到 Swoole Server$client->send(json_encode(['to' => $email,'subject' => $subject,'body' => $body]));// 接收 Swoole Server 的反馈$response = $client->recv();$client->close();return json(['message' => $response]);} else {return json(['error' => 'Unable to connect to Swoole Server']);}}
}

六、总结

通过 Swoole 实现的异步任务处理机制,可以将耗时操作如发送邮件等操作放入后台异步执行,提升用户体验和系统性能。Swoole 的 Task 机制非常适合处理这种场景,结合 ThinkPHP 使得开发异步任务更加简单高效。

相关文章:

Thinkphp5 + Swoole实现邮箱异步通知

在 ThinkPHP 中实现邮箱异步通知的常见做法是通过队列系统来处理异步任务&#xff0c;结合 Swoole 来处理异步发送邮件的请求。这样可以避免同步处理邮件发送导致的阻塞&#xff0c;提高响应速度。 以下是基于 ThinkPHP5 框架和 Swoole 的异步邮件通知实现步骤&#xff1a; 一…...

LLM - 理解 多模态大语言模型 (MLLM) 的预训练与相关技术 (三)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142063880 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 完备(F…...

工具篇之Joda-Time

在Java应用程序开发中&#xff0c;处理日期和时间是一项常见且复杂的任务。尽管Java标准库提供了基本的日期和时间操作类&#xff0c;但它们的使用常常不够直观和灵活。Joda-Time 是一个强大的日期和时间库&#xff0c;提供了丰富的API&#xff0c;用于简化日期和时间的操作。本…...

架构师应该懂得东西,软考应该具备的

架构师应该懂得知识 架构师作为软件系统设计和开发的关键角色&#xff0c;需要掌握广泛的知识和技能。具体来说&#xff0c;他们应该懂得以下几方面的知识&#xff1a; 编程语言&#xff1a;掌握至少一种编程语言&#xff0c;如Java、C、Python等&#xff0c;以便于进行系统设…...

图论篇--代码随想录算法训练营第五十一天打卡| 99. 岛屿数量(深搜版),99. 岛屿数量(广搜版),100. 岛屿的最大面积

99. 岛屿数量&#xff08;深搜版&#xff09; 题目链接&#xff1a;99. 岛屿数量 题目描述&#xff1a; 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而…...

什么是API网关(API Gateway)?

1. 什么是API网关&#xff08;API Gateway&#xff09;&#xff1f; 在微服务体系结构中&#xff0c;客户端可能与多个前端服务进行交互。 API 网关位于客户端与服务之间。 它充当反向代理&#xff0c;将来自客户端的请求路由到服务。 它还可以执行各种横切任务&#xff0c;例…...

对话:LLC磁集成能否成为充电桩模块电源常态产品?

编者按&#xff1a;在终端需求疲软的影响下&#xff0c;前两年火热的新能源汽车、光伏、储能等新能源领域也掀起了价格战&#xff0c;储能已正式进入0.5元时代&#xff0c;新能源汽车领域价格战更是一轮接一轮&#xff0c;成本管控成为2024年企业绕不开的话题。 接下来我们将围…...

基于SSM的二手物品交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的二手物品交易管理系统7拥有两种角色 管理员&#xff1a;用户管理、分类管理、商品管理、订单管理、系统管理等 用户&#xff1a;登录注册、充值、收货、评价、收藏、购物车、订…...

视觉语言模型中的人脸社会感知

本文研究了视觉语言模型CLIP在处理人脸图像时的社会感知能力及其潜在偏见。研究者们构建了一个名为CausalFace的合成人脸数据集&#xff0c;通过系统地独立变化年龄、性别、人种、面部表情、照明和姿势等六个维度来评估模型的社会感知。他们发现&#xff0c;尽管CLIP是在多样化…...

JAVA学习-练习试用Java实现“最小覆盖子串”

问题&#xff1a; 给定一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a;如果 s 中存在这样的子串&#xff0c;我们保证它是唯一的答案。 示例 1&…...

关于axios同步获取数据的问题

axios同步获取数据 Axios介绍问题代码修改 总结 Axios介绍 Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 X…...

java-在ANTLR中,如何从java文件中提取类名和方法名0.1.8

java-在ANTLR中&#xff0c;如何从java文件中提取类名和方法名0.1.0 目标java源文件java的g4文件生成antlr代码最终代码调测结果阶段性总结 2024年9月12日11:16:01----0.1.8 目标 从一个java文件中提取出类名和方法名 java源文件 文件名是main.java&#xff0c;具体内容如下…...

十大护眼灯钢琴灯品牌是智商税吗?十大钢琴灯品牌排行榜

十大护眼灯钢琴灯品牌是智商税吗&#xff1f;不良的光线不仅会使得孩子在读写用眼时眼睛不舒服&#xff0c;还会引起视觉疲劳伤眼视力健康&#xff0c;这个时候要能有一台可靠的护眼灯钢琴灯&#xff0c;那真是再好不过了。但是市面上护眼灯钢琴灯的种类太多&#xff0c;盲目挑…...

搜维尔科技:CyberGlove将实时捕捉运动信号和触觉反馈,将其重新定位到人形机器人进行驱动

CyberGlove将实时捕捉运动信号和触觉反馈&#xff0c;然后将其重新定位到人形机器人上。 这款18个传感器&#xff08;有18节点和22节点两个型号&#xff0c;22节点早期用于美国军事方面&#xff0c;支持无线通信、蓝牙、WiFi、射频&#xff09;数据手套的每个手指上有两个弯曲…...

数据结构:堆的算法

目录 一堆的向上调整算法二堆的向下调整算法三堆的应用:堆排序四TOPK问题 一堆的向上调整算法 我们在堆中插入一个数据一般实在堆的最后插入然后可以一步一步与上层结点&#xff08;父结点进行比较&#xff09;&#xff0c;继而进行交换&#xff0c;完成二叉树的结构&#xff0…...

python画图|3D直方图基础教程

前述已经完成了直方图和3D图的基本学习&#xff0c;链接如下&#xff1a; 直方图&#xff1a;python画图|水平直方图绘制-CSDN博客 3D图&#xff1a;python画图|水平直方图绘制-CSDN博客 现在我们尝试把二者结合&#xff0c;画3D直方图。 【1】官网教程 首先&#xff0c;依…...

C语言中的函数,实参,形参,递归

1&#xff1a;什么是函数 2&#xff1a;定义带形式参数的函数和带实际参数的函数 3&#xff1a;递归 --------------------------------------------------------------------------------------------------------------------------------- 1&#xff1a;在 C 语言中&…...

ICM20948 DMP代码详解(15)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;14&#xff09; 上一回开始对icm20948_sensor_setup函数中第3段代码即inv_icm20948_initialize函数进行解析。为了便于理解和回顾&#xff0c;再次贴出其源码&#xff0c;在EMD-Core\sources\Invn\Devices\Drivers\IC…...

NC 和为K的连续子数组

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个无序…...

JS设计模式之装饰者模式:优雅的给对象增添“魔法”

引言 在前端开发中&#xff0c;我们经常会遇到需要在不修改已有代码的基础上给对象添加新的行为或功能的情况。而传统的继承方式并不适合这种需求&#xff0c;因为继承会导致类的数量急剧增加&#xff0c;且每一个子类都会固定地实现一种特定的功能扩展。 装饰者模式则提供了…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...