thinkphp6 消息队列(queue)使用方法 (发送邮件示例)
1、首先,你需要在你的框架中下载queue这个扩展
composer require topthink/think-queue
2.公共配置,配置文件位于:config/queue.php
return [ 'default' => 'redis', 'connections' => [ 'sync' => [ 'type' => 'sync', ], 'database' => [ 'type' => 'database', 'queue' => 'default', 'table' => 'jobs', 'connection' => null, ], 'redis' => [ 'type' => 'redis', 'queue' => 'default', 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'select' => 0, 'timeout' => 0, 'persistent' => false, ], ], 'failed' => [ 'type' => 'none', 'table' => 'failed_jobs', ], ];
你可以在配置文件中选择你需要使用数据库的类型,根据自己的需求使用,这里我选择的是redis
'default'=>'sync' //驱动类型,可选择 sync(默认):同步执行,database:数据库驱动,redis:Redis驱动//或其他自定义的完整的类名
3.创建任务类
单模块项目推荐使用 app\job
作为任务类的命名空间
多模块项目可用使用 app\module\job
作为任务类的命名空间 也可以放在任意可以自动加载到的地方
我这里是在 app\admin\job 创建了这个任务类
里面执行了我发送邮件的任务,这里的例子可以实现延迟发送邮件的任务
示例代码如下
<?php namespace app\admin\job; use think\facade\Log; use think\queue\Job; use tool\SendMail; class Test { public function fire(Job $job, $data){ if ($job->attempts()>3){ //执行失败写入错误日志 Log::error('fire执行失败'); //删除这个任务 $job->delete(); }else{ $toemail="407489255@qq.com"; //定义收件人的邮箱 $username="407486225@qq.com"; //发送方的邮箱地址 $password="qmxrvjgohiucbbgj"; //发送方邮箱的密码 $setFrom="1223524552@qq.com"; //设置发件人信息 $addReplyTo="1003729782@qq.com"; //设置收件人信息 $contrnt="邮件内容是 <b>您的验证码是:123456</b>,哈哈哈!111122"; //设置邮件内容 SendMail::sendMail($toemail,$username,$password,$setFrom,$addReplyTo,$contrnt); //执行成功删除这个任务 $job->delete(); } } }
这个是发送邮件的封住类 配合上面的使用
<?php namespace tool; use PHPMailer\PHPMailer\PHPMailer; class SendMail { public static function sendMail($toemail,$username,$password,$setFrom,$addReplyTo,$contrnt) { $toemail ="$toemail";//定义收件人的邮箱 $mail = new PHPMailer(); $mail->isSMTP();// 使用SMTP服务 $mail->CharSet = "utf8";// 编码格式为utf8,不设置编码的话,中文会出现乱码 $mail->Host = "smtp.qq.com";// 发送方的SMTP服务器地址 $mail->SMTPAuth = true;// 是否使用身份验证 $mail->Username = "$username";// 发送方的163邮箱用户名,就是你申请163的SMTP服务使用的163邮箱</span><span style="color:#333333;"> $mail->Password = "$password";// 发送方的邮箱密码,注意用163邮箱这里填写的是“客户端授权密码”而不是邮箱的登录密码!</span><span style="color:#333333;"> $mail->SMTPSecure = "ssl";// 使用ssl协议方式</span><span style="color:#333333;"> $mail->Port = 465;// 163邮箱的ssl协议方式端口号是465/994 $mail->setFrom("$setFrom", "Mailer");// 设置发件人信息,如邮件格式说明中的发件人,这里会显示为Mailer(xxxx@163.com),Mailer是当做名字显示 $mail->addAddress($toemail, 'Wang');// 设置收件人信息,如邮件格式说明中的收件人,这里会显示为Liang(yyyy@163.com) $mail->addReplyTo("$addReplyTo", "Reply");// 设置回复人信息,指的是收件人收到邮件后,如果要回复,回复邮件将发送到的邮箱地址 //$mail->addCC("xxx@163.com");// 设置邮件抄送人,可以只写地址,上述的设置也可以只写地址(这个人也能收到邮件) //$mail->addBCC("xxx@163.com");// 设置秘密抄送人(这个人也能收到邮件) //$mail->addAttachment("bug0.jpg");// 添加附件 $mail->Subject = "这是一个测试邮件";// 邮件标题 $mail->Body = "$contrnt";// 邮件正文 //$mail->AltBody = "This is the plain text纯文本";// 这个是设置纯文本方式显示的正文内容,如果不支持Html方式,就会用到这个,基本无用 if (!$mail->send()) {// 发送邮件 echo "Message could not be sent."; echo "Mailer Error: " . $mail->ErrorInfo;// 输出错误信息 } else { echo '发送成功'; } } }
4.发布任务 控制器调用这个 进入发布任务
<?php declare (strict_types = 1); namespace app\admin\controller; use think\facade\Queue; use think\Request; class index { /** * 显示资源列表 * * @return \think\Response */ public function index() { //设置执行这个任务 Queue::later('20','app\admin\job\Test@fire',['name'=>'Test'],'fire'); }
注:一写参数的解释与使用方法
think\facade\Queue::push($job, $data = '', $queue = null)
和think\facade\Queue::later($delay, $job, $data = '', $queue = null)
两个方法,前者是立即执行,后者是在$delay
秒后执行
$job
是任务名
单模块的,且命名空间是app\job
的,比如上面的例子一,写Job1
类名即可
多模块的,且命名空间是app\module\job
的,写model/Job1
即可
其他的需要些完整的类名,比如上面的例子二,需要写完整的类名app\lib\job\Job2
如果一个任务类里有多个小任务的话,如上面的例子二,需要用@+方法名app\lib\job\Job2@task1
、app\lib\job\Job2@task2
$data
是你要传到任务里的参数
$queue
队列名,指定这个任务是在哪个队列上执行,同下面监控队列的时候指定的队列名,可不填
5.监听任务并执行
这是我的执行的方法
php think queue:listen --queue fire
参数解释
php think queue:listen
php think queue:work
两种,具体的可选参数可以输入命令加 --help 查看
可配合supervisor使用,保证进程常驻