laravel 队列之队列消息与发送邮件

前期准备:

  1. 开发环境:homestead(Ubuntu 18.04 LTS+php 7.2.30+mysql 5.7.22)
    确保安装了redis扩展,如无安装,请执行:
    composer require predis/predis
  2. 配置信息
    config/queue.phpconnections中配置:
    'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, 'block_for' => null, ],
    在.env文件中配置发送邮件的邮箱:
    MAIL_MAILER=smtp #邮箱服务器地址 MAIL_HOST=smtp.163.com MAIL_PORT=25 #邮箱账号 MAIL_USERNAME=XXX@163.com #POP3/SMTP服务密码 MAIL_PASSWORD=XXXX MAIL_ENCRYPTION=null #可以随便填写字符串,但是一定不能为空 MAIL_FROM_ADDRESS=null MAIL_FROM_NAME="${APP_NAME}"
    在此有个需要注意的地方,MAIL_PASSWORD不是邮箱的登录密码,而是POP3/SMTP服务密码(设置方法)。
    注意:本例子中使用的是网易邮箱和SMTP,不同驱动下的服务器地址、端口号均不同:
  • 服务器地址:
    POP3服务器: pop.163.com
    SMTP服务器: smtp.163.com
    IMAP服务器: imap.163.com
    安全支持:
    POP3/SMTP/IMAP服务全部支持SSL连接
  • 端口:
    网易邮箱端口

    开发阶段:

  • 生成任务类

执行命令:

php artisan make:job SendEmail

运行成功在app/Jobs目录下生成SendEmail类。修改类的内容后如下:

namespace App\Jobs; use App\Models\UserInfo; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Mail\Mailer; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class SendEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $user; /** * Create a new job instance. * * @return void */ public function __construct(UserInfo $user) { // $this->user = $user; } /** * Execute the job. * * @return void */ public function handle(Mailer $mailer) { // $user = $this->user; $mailer->send('emails.reminder',['user'=>$user],function($message) use ($user){ $message->to($user->email)->subject('新功能发布'); }); } }

参考资料:Laravel 队列系列 —— 基于 Redis 实现任务队列的基本配置和使用

  • 编写调用函数:
    <?php namespace App\Admin\Controllers; use App\Http\Controllers\Controller; use App\Jobs\SendEmail; use App\Models\UserInfo; use Illuminate\Http\Request; use Illuminate\Support\Facades\Redis; class ApiController extends Controller { private $redis; public function __construct(){ $this->redis = Redis::connection('default'); } public function test(Request $request){ //方便测试,写死 $user = UserInfo::find(1); $this->dispatch(new SendEmail($user)); } }
    加上测试路由:
    Route::group([ 'prefix' => 'admin', 'middleware' => ['web'], ], function (Router $router) { $router->any('api/{action}', function ($action) { $ctrl = \App::make("\\App\\Admin\\Controllers\\ApiController"); return \App::call([$ctrl, $action]); }); });

    测试阶段:

    调用xxx.test/api/test
    得出结果:
    QQ邮箱收到邮件提醒
    进入查看邮件:
    收到邮件

至此,邮件发送成功完成!

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

生成后job下的类名叫SendEmail,下面实例化怎么是SendReminderEmail?是写错了,他俩是一个?

5年前 评论
她来听我的演唱会 (楼主) 5年前

我是新手。我理一下。如有不对还望指出 我从后面开始,先写一个路由,可以访问到test这个动作。然后这个动作执行了发送邮件的方法。然后邮件执行的方法,只是往redis队列塞了一封邮件。最后通过消耗队列来发送邮件。是这样的流程吗?

2年前 评论
她来听我的演唱会 (楼主) 2年前
xiaofeishu (作者) 2年前