1、简介
Laravel基于目前流行的SwiftMailer库提供了一套干净清爽的邮件API。Laravel为SMTP、Mailgun、Mandrill、Amazon SES、PHP的mail
函数,以及sendmail
提供了驱动,从而允许你快速通过本地或云服务发送邮件。
1.1 邮件驱动预备知识
基于驱动的API如Mailgun和Mandrill通常比SMTP服务器更简单、更快。所有的API驱动要求应用已经安装Guzzle HTTP库。你可以通过添加如下行到composer.json
文件来安装Guzzle到项目:
"guzzlehttp/guzzle": "~5.3|~6.0"
1.1.1 Mailgun驱动
要使用Mailgun驱动(Mailgun前10000封邮件免费,后续收费),首先安装Guzzle,然后在配置文件config/mail.php
中设置driver
选项为mailgun
。接下来,验证配置文件config/services.php
包含如下选项:
'mailgun' => [
'domain' => 'your-mailgun-domain',
'secret' => 'your-mailgun-key',],
1.1.2 Mandrill驱动
要使用Mandrill驱动(Mandrill不支持中国区用户注册,汗!),首先安装Guzzle,然后在配置文件config/mail.php
中设置driver
选项值为mandrill
。接下来,验证配置文件config/services.php
包含如下选项:
'mandrill' => [
'secret' => 'your-mandrill-key',],
1.1.3 SES驱动
要使用Amazon SES驱动(收费),安装Amazon AWS的PHP SDK,你可以通过添加如下行到composer.json
文件的require
部分来安装该库:
"aws/aws-sdk-php": "~3.0"
接下来,设置配置文件config/mail.php
中的driver
选项为ses
。然后,验证配置文件config/services.php
包含如下选项:
'ses' => [
'key' => 'your-ses-key',
'secret' => 'your-ses-secret',
'region' => 'ses-region', // e.g. us-east-1
],
2、发送邮件
Laravel允许你在视图中存储邮件信息,例如,要组织你的电子邮件,可以在resources/views
目录下创建emails
目录。
要发送一条信息,使用Mail
门面上的send
方法。send
方法接收三个参数。第一个参数是包含邮件信息的视图名称;第二个参数是你想要传递到该视图的数组数据;第三个参数是接收消息实例的闭包回调——允许你自定义收件人、主题以及邮件其他方面的信息:
<?php
namespace App\Http\Controllers;
use Mail;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller{
/**
* 发送邮件给用户
*
* @param Request $request
* @param int $id
* @return Response
*/
public function sendEmailReminder(Request $request, $id)
{
$user = User::findOrFail($id);
Mail::send('emails.reminder', ['user' => $user], function ($m) use ($user) {
$m->to($user->email, $user->name)->subject('Your Reminder!');
});
}
}
由于我们在上例中传递一个包含user
键的数组,我们可以在邮件中使用如下方式显示用户名:
<?php echo $user->name; ?>
注意:
$message
变量总是被传递到邮件视图,并允许嵌入附件,因此,你应该在视图负载中避免传入消息变量。
构造消息
正如前面所讨论的,传递给send
方法的第三个参数是一个允许你指定邮件消息本身多个选项的闭包。使用这个闭包可以指定消息的其他属性,例如抄送、群发,等等:
Mail::send('emails.welcome', $data, function ($message) {
$message->from('us@example.com', 'Laravel');
$message->to('foo@example.com')->cc('bar@example.com');
});
下面试$message
消息构建器实例上的可用方法:
$message->from($address, $name = null);
$message->sender($address, $name = null);
$message->to($address, $name = null);
$message->cc($address, $name = null);
$message->bcc($address, $name = null);
$message->replyTo($address, $name = null);
$message->subject($subject);
$message->priority($level);
$message->attach($pathToFile, array $options = []);
// 从$data字符串追加文件...
$message->attachData($data, $name, array $options = []);
// 获取底层SwiftMailer消息实例...
$message->getSwiftMessage();
注意:传递给
Mail::send
闭包的消息实例继承自SwiftMailer
消息类,该实例允许你调用该类上的任何方法来构建自己的电子邮件消息。
纯文本邮件
默认情况下,传递给send
方法的视图假定包含HTML,然而,通过传递数组作为第一个参数到send
方法,你可以指定发送除HTML视图之外的纯文本视图:
Mail::send(['html.view', 'text.view'], $data, $callback);
或者,如果你只需要发送纯文本邮件,可以指定在数组中使用text键:
Mail::send(['text' => 'view'], $data, $callback);
原生字符串邮件
如果你想要直接发送原生字符串邮件你可以使用raw
方法:
Mail::raw('Text to e-mail', function ($message) {
//
});
2.1 附件
要添加附件到邮件,使用传递给闭包的$message
对象上的attach
方法。该方法接收文件的绝对路径作为第一个参数:
Mail::send('emails.welcome', $data, function ($message) {
//
$message->attach($pathToFile);
});
当添加文件到消息时,你还可以通过传递数组作为第二个参数到attach
方法来指定文件显示名和MIME类型:
$message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);
2.2 内联附件
2.2.1 在邮件视图中嵌入一张图片
嵌套内联图片到邮件中通常是很笨重的,然而,Laravel提供了一个便捷的方式附加图片到邮件并获取相应的CID,要嵌入内联图片,在邮件视图中使用$message
变量上的embed
方法。记住,Laravel自动在所有邮件视图中传入$message
变量使其有效:
<body>
Here is an image:
<img src="<?php echo $message->embed($pathToFile); ?>">
</body>
2.2.2 在邮件视图中嵌入原生数据
如果你想要在邮件消息中嵌入原生数据字符串,可以使用$message
变量上的embedData
方法:
<body>
Here is an image from raw data:
<img src="<?php echo $message->embedData($data, $name); ?>">
</body>
2.3 邮件队列
2.3.1 邮件消息队列
发送邮件消息可能会大幅度延长应用的响应时间,许多开发者选择将邮件发送放到队列中再后台执行,Laravel中可以使用内置的统一队列API来实现。要将邮件消息放到队列中,使用Mail
门面上的queue
方法:
Mail::queue('emails.welcome', $data, function ($message) {
//
});
该方法自动将邮件任务推送到队列中以便在后台发送。当然,你需要在使用该特性前配置队列。
2.3.2 延迟消息队列
如果你想要延迟已经放到队列中邮件的发送,可以使用later
方法。只需要传递你想要延迟发送的秒数作为第一个参数到该方法即可:
Mail::later(5, 'emails.welcome', $data, function ($message) {
//
});
2.3.3 推入指定队列
如果你想要将邮件消息推送到指定队列,可以使用queueOn
和laterOn
方法:
Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) {
//
});
Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) {
//
});
3、邮件&本地开发
开发发送邮件的应用时,你可能不想要真的发送邮件到有效的电子邮件地址,而只是想要做下测试。Laravel提供了几种方式“禁止”邮件的实际发送。
3.1 日志驱动
一种解决方案是在本地开发时使用log
邮件驱动。该驱动将所有邮件信息写到日志文件中以备查看,想要了解更多关于每个环境的应用配置信息,查看配置文档。
3.2 通用配置
Laravel提供的另一种解决方案是为框架发送的所有邮件设置通用收件人,这样的话,所有应用生成的邮件将会被发送到指定地址,而不是实际发送邮件指定的地址。这可以通过在配置文件config/mail.php
中设置to
选项来实现:
'to' => [
'address' => 'dev@domain.com',
'name' => 'Dev Example'
],
3.3 Mailtrap
最后,你可以使用Mailtrap服务和smtp
驱动发送邮件信息到“虚拟”邮箱,这种方法允许你在Mailtrap的消息查看器中查看最终的邮件。
$flag = Mail::send(‘user.email’,[‘name’=>’测试’],function($message){
$message->to(‘861877723@qq.com’);
$message->subject(‘测试内容’);
});
dd($flag);
求问,,为什么邮件发送成功失败把回的$flag都是空
lumen中应该怎么配置mailgun呢?
如何使用多个邮箱发送啊,例如找回密码是一个邮箱,注册激活又是一个邮箱,这样的怎么处理?求指点
要使用Mailgun驱动(Mailgun前10000封邮件免费,后续收费),我只想使用免费的图文+文档的方式,能不能不是用这个驱动
使用SMTP得了
好的。知道了[挤眼]
我在用163 邮箱来测试发电子邮件功能为什么不行呢?有这样的提示是说明什么问题了呢?错在哪?
stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
我遇到困难了,发电子邮件不成功,可以解答一下吗?
这两天重感冒 文章都无暇更新 等康复了再来看吧
你使用TLS验证了?
TLS 是不是在.env 文件中 MAIL_ENCRYPTION=tls 这样设置呢?这个我设了。 在config/mail.php 这个文件中 ‘encryption’ => env(‘MAIL_ENCRYPTION’, ‘tls’),
参考:http://stackoverflow.com/questions/26896265/php-swiftmailer-using-starttls-and-self-signed-certificates
怎么哪都有你叨叨叨
你是谁啊,我在学习,不明当然提问,难道不懂装懂,装B。
有些问题 你可以加群到群里去讨论 我不一定能及时看到 学院重构后会推出一个问答模块 以便更好地帮助大家解决问题
我在测试发邮件功能时报错是哪里错了呢?我用的是smtp 服务
Failed to authenticate on SMTP server with username “1176964075@qq.com” using 3 possible authenticators
如何判断邮件是否发送成功?
请参考邮件实例教程:http://laravelacademy.org/post/1986.html
这一句话是什么意思:你可以通过添加如下行到composer.json文件来安装Guzzle到项目: 是不是只要在composer.json文件修改添加 “guzzlehttp/guzzle”: “~5.3|~6.0″就行了呢?,不用下载什么文件吗?
添加后需要运行composer update
我在 控制台上输入 composer require “guzzlehttp/guzzle”: “~5.3|~6.0” 为什么无法下载 Guzzle ,这个是不是要下载到本地的呢?