Skip to content

邮件发送无论是用于用户身份的验证,消息通知的发送,还是在系统运维中系统预警的通知发送都有着非常广泛的使用,掌握邮件发送的重要性自然也不言而喻。本文也将结合当下最火热的 laravel 框架,介绍下其邮件发送的几种具体实现。

邮件发送无论是在日常的开发中用于用户身份的验证,消息通知的发送,还是在系统运维中作为系统功能预警的通知都有着非常广泛的使用,其重要性自然也不言而喻。laravel 作为当今最火的 php 框架之一,本文也将结合 laravel 的邮件发送在自己在工作生活中的实际运用做一些简单的分享。

开发前的准备

工欲善其事必先利其器,再进行实际的编码之前,让我们先来看看还需要准备些什么。

一台用于发送的邮件的代理服务器,这里像 163,qq,新浪,搜狐等各大邮箱服务商均提供了这一功能,本文以 163 的邮箱为例。邮件发送服务需要你开启 POP3/SMTP/IMAP 功能,另外 163 的第三方邮件发送使用的是授权码模式,具体的该怎么设置请自行百度,这里不在赘述。

开启 openssl 扩展,因为某些云服务商屏蔽了不安全的邮件发送端口和非 ssl 协议端口,所以请务必确认你的服务器开启了 openssl 服务,不知道怎么开启的请自行百度开启。

在配置好了上方的功能之后,让我们来对 laravel .env 文件下的邮件配置进行一下调整。

MAIL_DRIVER=smtp //发送邮件所使用的协议
MAIL_HOST=smtp.163.com //邮件服务器地址
MAIL_PORT=994 //邮件发送端口
[email protected] //发送邮件的账户
MAIL_PASSWORD=xxxxxx //发送邮件账户的授权码
MAIL_ENCRYPTION=ssl //邮件的加密方式
[email protected] //邮件的发送者
MAIL_FROM_NAME=夜雪独行 //邮件发送人

laravel 发送邮件的实现

laravel 的邮件发送是基于 swiftmail 扩展封装了自己的邮件扩展类,而且 laravel 为邮件的发送处理方式提供了更为灵活的方式,下面我们将对几种实现做一下简单的介绍。

使用 Mail 的 facade 上的 to 方法实现发送

此中发送方法最为直接也最为方便,易于理解,因为这种方法,需要接受一个 user 集合或者对象,laravel 会自动的寻找对象或者集合上的 email 和 name 属性去设置邮件的的属性和接收人,所以确保对象或者属性上有这些属性。

php

namespace App\Http\Controllers;

use App\User;
use App\Mail\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * 投发送邮件。
     *
     * @param  Request  $request
     * @return Response
     */
    public function ship(Request $request)
    {
       // 发送邮件
        Mail::to($request->user())->send(new Registered($request->user()));
    }
}

使用 Notification 实现

这种处理方的的好处在于没有任何的限制,你只需要在 user 实例上调用 notify 方法即可,laravel 会自动需找 user 上的 email 属性所谓邮件的接受者,接下来 laravel 会使用 Notification 上的 toMail()方法进行邮件的实际发送,在这里你可以调整自己的邮件发送实现。

通知的调用

php
$user->notify(new ResetPassword($token));

通知的实现

php
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;

class ResetPassword extends Notification
{
    use Queueable;

    public $token;

    /**
     * 构造函数,用于一些参数的传入.
     * @param $token
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * 邮件接收者属性
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * 调用方法执行实际的邮件发送工作
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->level('blue')
            ->subject('重置密码')
            ->line('您收到这封邮件是因为我们收到了您的重置密码申请。')
            ->action('重置密码', url(config('app.url').route('password.reset', $this->token, false)))
            ->line('如果这不是您本人的操作,请您忽略这封邮件!');
    }
}

使用队列的方式实现

使用 Notification 实现

Notification 类默认加载了 Queueable,只需要将 Notification 接入 ShouldQueue 实现,laravel 将自动将通知推送到默认队列上去实现,除此之外你还可以使用 chainQueue 属性来定义将推送的队列。

使用 Mail facade 实现

队列的调用

php
Mail::to($request->user())
    ->queue(new SendRegisterEmail($user));

队列任务的实现

php
namespace App\Jobs;

use App\Mail\Registered;
use App\Traits\QueueFailedEmail;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Mail;

class SendRegisterEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, SendsPasswordResetEmails, QueueFailedEmail;

    public $user;

    public $tries = 3;

    /**
     * 参数的传入
     * @param $user
     */
    public function __construct($user)
    {
        $this->user = $user;
    }

    /**
     * 执行队列任务,发送邮件
     *
     * @return void
     */
    public function handle()
    {
        Mail::to($this->user['email'])
            ->send(new Registered($this->user));

    }
}