郵件
簡介
laravel 基于流行的 SwiftMailer 類庫構(gòu)建了一種干凈簡潔的郵件 API吠昭。laravel 提供了驅(qū)動以支持 SMTP喊括,Mandrill,SparkPost矢棚,Amazon SES郑什,PHP 的 mail
方法和 sendmail
方法,這允許你快速的開始構(gòu)建通過本地或云服務(wù)發(fā)送郵件的功能蒲肋。
驅(qū)動先決條件
基于 API 的驅(qū)動程序如 Mailgun 和 Mandrill 通常要比 SMTP 服務(wù)簡單快速蘑拯。所有的 API 驅(qū)動都必須引入 Guzzle HTTP 類庫,你可以通過在 composer.json
文件中添加下面的內(nèi)容來進(jìn)行安裝:
"guzzlehttp/guzzle": "~5.3|~6.0"
Mailgun 驅(qū)動
如果使用 Mailgun 驅(qū)動兜粘,你首先需要安裝 Guzzle申窘,然后設(shè)置 config/mail.php
配置文件的 driver
選項為 mailgun
。然后孔轴,你需要確認(rèn)你的 config/services.php
配置文件中包含以下選項:
'mailgun' => [
'domain' => 'your-mailgun-domain',
'secret' => 'your-mailgun-key',
],
Mandrill 驅(qū)動
如果使用 Mandrill 驅(qū)動剃法,你首先需要安裝 Guzzle,然后設(shè)置 config/mail.php
配置文件的 driver
選項為 mandrill
路鹰。接著贷洲,你需要確認(rèn)你的 config/services.php
配置文件中包含以下選項:
'mandrill' => [
'secret' => 'your-mandrill-key',
],
SparkPost 驅(qū)動
如果使用 SparkPost 驅(qū)動收厨,你首先需要安裝 Guzzle,然后設(shè)置你的 config/mail.php
配置文件中的 driver
選項為 sparkpost
优构。接著诵叁,你需要確認(rèn)你的 config/services.php
配置文件中包含以下選項:
'sparkpost' => [
'secret' => 'your-sparkpost-key',
],
SES 驅(qū)動
如果使用 Amazon SES 驅(qū)動,你需要在 PHP 中引入 Amazon AWS SDK俩块。你可以通過在 composer.json
文件中進(jìn)行引入安裝:
"aws/aws-sdk-php": "~3.0"
然后設(shè)置你的 config/mail.php
配置文件的 driver
選項為 ses
黎休。接著,你需要確認(rèn)你的 config/services.php
配置文件中包含以下選項:
'ses' => [
'key' => 'your-ses-key',
'secret' => 'your-ses-secret',
'region' => 'ses-region', //e.g. us-east-1
],
發(fā)送郵件
laravel 允許你使用視圖來存儲你的郵件信息玉凯。比如势腮,你可以在 resources/views
目錄下創(chuàng)建一個 emails
目錄來管理你的郵件視圖:
你需要使用 Mail
假面的 send
方法來發(fā)送一個郵件。send
方法接收三個參數(shù)漫仆,第一個參數(shù)應(yīng)該是視圖的名稱捎拯。第二個參數(shù)應(yīng)該是傳遞到視圖中的數(shù)據(jù)所組成的數(shù)組。最后盲厌,是一個 Closure
回調(diào)函數(shù)署照,這個回調(diào)函數(shù)會接收一個 message 實例,這允許你自由的配置收件人吗浩,主題建芙,和其他方面的郵件信息:
<?php
namespace App\Http\Controller;
use Mail;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Send an e-mail reminder to the user.
*
* @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->from('hello@app.com', 'Your Application');
$m->to($user->email, $user->name)->subject('Your Reminder!');
});
}
}
因為上面的示例中我們傳遞了 user
鍵到數(shù)組中,所以我們可以在我們的郵件視圖中使用用戶的名稱:
<?php echo $user->name; ?>
注意: 一個
$message
變量會自動的傳遞到郵件視圖懂扼,并且允許內(nèi)聯(lián)附件禁荸。所以,你應(yīng)該避免手動的傳遞到視圖message
變量阀湿。
構(gòu)建一個 Message
就如我們上面談到的赶熟,傳遞到 send
方法的第三個參數(shù)是一個 Closure
,這個閉包允許你設(shè)置郵件信息的各種選項陷嘴。使用閉包映砖,你可以指定信息的其它屬性,比如復(fù)寫灾挨,密抄等:
Mail::send('emails.welcome', $data, function ($message) {
$message->from('us@example.com', 'Laravel');
$message->to('foo@example.com')->cc('bar@example.com');
});
這里列出了 $message
構(gòu)建實例所有可用的方法:
$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 = []);
// Attach a file from a raw $data string...
$message->attachData($data, $name, array $options = []);
// Get the underlying SwiftMailer message instance...
$message->getSwiftMessage();
注意:message 實例繼承自 SwiftMailer 信息類并會被傳遞到
Mail::send
閉包中邑退。這允許你在訪問所有 SwiftMailer 信息類的方法。
純文本郵件
默認(rèn)的涨醋,send
方法會假設(shè)傳遞到其中的視圖包含了 HTML瓜饥。但是,你可以傳遞一個數(shù)組到 send
方法的第一個參數(shù)浴骂,你指定一個純文本視圖來合并 HTML 視圖:
Mail::send(['html.view', 'text.view'], $data, $callback);
或者你可以只傳遞一個純文本的郵件,你需要指定數(shù)組的鍵為 text
:
Mail::send(['text' => 'view'], $data, $callback);
原始字符串郵件
你可以使用 raw
方法來直接發(fā)送原始字符串郵件:
Mail::raw('Text to e-mail', function ($message){
//
});
附件
你可以使用傳遞到閉包中的 $message
對象的 attach
方法來在郵件中添加附件宪潮。attach
方法接收一個完整的文件路徑作為第一個參數(shù):
Mail::send('emails.welcome', $data, function ($message) {
//
$message->attach($pathToFile);
});
當(dāng)你添加一個郵件附件時溯警,你可能也需要指定附件顯示的名稱或者 MIME type趣苏。你可以向 attach
方法傳遞一個數(shù)組作為第二個參數(shù):
$message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);
attachData
方法可以用來添加一個原始字節(jié)字符串作為一個附件。比如梯轻,你可能需要使用這個方法來將內(nèi)存中生成的 PDF 直接添加到附件中食磕,而不需要先存儲到磁盤:
$message->attachData($pdf, 'invoice.pdf');
$message->attachData($pdf, 'invoice.pdf', ['mime' => $mime]);
內(nèi)聯(lián)附件
在郵件視圖中嵌入一個圖片
在郵件中內(nèi)聯(lián)一個圖片通常是比較笨重的。但是喳挑,laravel 提供了一種便捷的方式在你的郵件中附加一個圖片并且取回適當(dāng)?shù)?CID彬伦。你需要在郵件視圖中使用 $message
變量的 embed
方法。你應(yīng)該記得伊诵,Laravel 會自動的創(chuàng)建一個 $message
變量并將其傳遞到你的郵件視圖中:
<body>
Here is an image:
<img src="<?php echo $message->embed($pathToFile); ?>"
</body>
嵌入原始數(shù)據(jù)到視圖
如果你希望嵌入一個原始數(shù)據(jù)到郵件信息中单绑,你可以使用 $message
變量的 embedData
方法:
<body>
Here is an image from raw data:
<img src="<?php echo $message->embedData($data, $name); ?>"
</body>
郵件隊列
隊列化郵件信息
由于發(fā)送郵件是非常消耗資源的一件事,這樣會影響到應(yīng)用的響應(yīng)時間曹宴。所以很多開發(fā)者都選擇使用隊列來完成異步的郵件發(fā)送搂橙。Laravel 使用統(tǒng)一的隊列接口來使這些非常簡單。你需要使用 Mail
假面的 queue
方法來使郵件隊列化:
Mail::queue('emails.welcome', $data, function ($message) {
//
});
該方法會自動的在隊列添加發(fā)送郵件的任務(wù)笛坦,該任務(wù)會在后臺自動的執(zhí)行区转。當(dāng)然,你需要先配置好隊列版扩。
延遲消息隊列
如果你希望延遲執(zhí)行郵件的發(fā)送隊列废离。你需要使用 later
方法。你需要在方法的第一個參數(shù)傳送一個你希望延遲執(zhí)行的秒數(shù):
Mail::later(5, 'emails.welcome', $data, function ($message) {
//
});
添加到指定的隊列
如果你希望添加郵件任務(wù)到指定的隊列礁芦,你需要使用 queueOn
和 laterOn
方法:
Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) {
//
});
Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) {
//
});
郵件 & 本地開發(fā)
當(dāng)開發(fā)一個發(fā)送郵件的服務(wù)時蜻韭,你可能并不希望真實的去發(fā)送一個郵件。只需要模擬測試成功就可以了宴偿。laravel 提供了多種方式來禁用真實的郵件發(fā)送湘捎。
log 驅(qū)動
其中一個解決方案就是在本地開發(fā)時使用 log
郵件驅(qū)動。這個驅(qū)動會將所有的郵件信息寫入到日志文件中窄刘。
通用的郵件
另外一個解決方案就是設(shè)置一個通用的郵件來接收所有的應(yīng)用發(fā)出的郵件窥妇。這種方式,會使應(yīng)用生成的所有郵件都發(fā)送到這個地址娩践。你可以通過配置 config/mail.php
文件的 to
選項來進(jìn)行設(shè)置:
'to' => [
'address' => 'dev@domain.com',
'name' => 'Dev Example'
],
mailtrap
最后活翩,你也可以使用一些像 Mailtrap 和 smtp
驅(qū)動的服務(wù)來發(fā)送你的郵件到一個虛擬郵箱,而且你也可以通過真實的郵件客戶端進(jìn)行查看翻伺。這可以使你看到真實的郵件在 Mailtrap 中的顯示效果材泄。
事件
laravel 會在發(fā)送郵件之前觸發(fā)事件。你應(yīng)該注意的是吨岭,它是在郵件發(fā)送之前觸發(fā)事件拉宗,而不是添加到隊列時。你可以在 EventServiceProvider
中注冊一個事件監(jiān)聽者:
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\LogSentMessage',
],
];