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 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 5

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

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

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

7个月前 评论
她来听我的演唱会 (楼主) 7个月前
xiaofeishu (作者) 7个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!