Laravel基于目前流行的SwiftMailer庫提供了一套干凈清爽的郵件、PHP的mail
函數(shù),以及sendmail
提供了驅(qū)動,從而允許你快速通過本地或云服務(wù)發(fā)送郵件。
基于驅(qū)動的API如Mail?HTTP庫。你可以通過添加如下行到composer.json
文件來安裝Guzzle到項目:
"guzzlehttp/guzzle": "~5.3|~6.0"
要使用Mailgun驅(qū)動,首先安裝Guzzle,然后在配置文件config/mail.php
中設(shè)置driver
選項為mailgun
。接下來,驗證配置文件config/services.php
包含如下選項:
'mailgun' => [
'domain' => 'your-mailgun-domain',
'secret' => 'your-mailgun-key',],
要使用Mandrill驅(qū)動,首先安裝Guzzle,然后在配置文件config/mail.php
中設(shè)置driver
選項值為mandrill
。接下來,驗證配置文件config/services.php
包含如下選項:
'mandrill' => [
'secret' => 'your-mandrill-key',],
要使用Amazon SES驅(qū)動,安裝Amazon AWS的PHP SDK,你可以通過添加如下行到composer.json
文件的require
部分來安裝該庫:
"aws/aws-sdk-php": "~3.0"
接下來,設(shè)置配置文件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
],
Laravel允許你在視圖中存儲郵件信息,例如,要組織你的電子郵件,可以在resources/views
目錄下創(chuàng)建emails
目錄。
要發(fā)送一條信息,使用Mail
門面上的send
方法。send
方法接收三個參數(shù)。第一個參數(shù)是包含郵件信息的視圖名稱;第二個參數(shù)是你想要傳遞到該視圖的數(shù)組數(shù)據(jù);第三個參數(shù)是接收消息實例的閉包回調(diào)——允許你自定義收件人、主題以及郵件其他方面的信息:
<?php
namespace App\Http\Controllers;
use Mail;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller{
/**
* 發(fā)送郵件給用戶
*
* @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
鍵的數(shù)組,我們可以在郵件中使用如下方式顯示用戶名:
<?php echo $user->name; ?>
注意:
$message
變量總是被傳遞到郵件視圖,并允許嵌入附件,因此,你應(yīng)該在視圖負載中避免傳入消息變量。
構(gòu)造消息
正如前面所討論的,傳遞給send
方法的第三個參數(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 = []);
// 從$data字符串追加文件...
$message->attachData($data, $name, array $options = []);
// 獲取底層SwiftMailer消息實例...
$message->getSwiftMessage();
注意:傳遞給
Mail::send
閉包的消息實例繼承自SwiftMailer
消息類,該實例允許你調(diào)用該類上的任何方法來構(gòu)建自己的電子郵件消息。
純文本郵件
默認情況下,傳遞給send
方法的視圖假定包含HTML,然而,通過傳遞數(shù)組作為第一個參數(shù)到send
方法,你可以指定發(fā)送除HTML視圖之外的純文本視圖:
Mail::send(['html.view', 'text.view'], $data, $callback);
或者,如果你只需要發(fā)送純文本郵件,可以指定在數(shù)組中使用text鍵:
Mail::send(['text' => 'view'], $data, $callback);
原生字符串郵件
如果你想要直接發(fā)送原生字符串郵件你可以使用raw
方法:
Mail::raw('Text to e-mail', function ($message) {
//
});
要添加附件到郵件,使用傳遞給閉包的$message
對象上的attach
方法。該方法接收文件的絕對路徑作為第一個參數(shù):
Mail::send('emails.welcome', $data, function ($message) {
//
$message->attach($pathToFile);
});
當添加文件到消息時,你還可以通過傳遞數(shù)組作為第二個參數(shù)到attach
方法來指定文件顯示名和MIME類型:
$message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);
嵌套內(nèi)聯(lián)圖片到郵件中通常是很笨重的,然而,Laravel提供了一個便捷的方式附加圖片到郵件并獲取相應(yīng)的CID,要嵌入內(nèi)聯(lián)圖片,在郵件視圖中使用$message
變量上的embed
方法。記住,Laravel自動在所有郵件視圖中傳入$message
變量使其有效:
<body>
Here is an image:
<img src="<?php echo $message->embed($pathToFile); ?>">
</body>
如果你想要在郵件消息中嵌入原生數(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ā)送放到隊列中再后臺執(zhí)行,Laravel中可以使用內(nèi)置的統(tǒng)一隊列API來實現(xiàn)。要將郵件消息放到隊列中,使用Mail
門面上的queue
方法:
Mail::queue('emails.welcome', $data, function ($message) {
//
});
該方法自動將郵件任務(wù)推送到隊列中以便在后臺發(fā)送。當然,你需要在使用該特性前配置隊列。
如果你想要延遲已經(jīng)放到隊列中郵件的發(fā)送,可以使用later
方法。只需要傳遞你想要延遲發(fā)送的秒數(shù)作為第一個參數(shù)到該方法即可:
Mail::later(5, 'emails.welcome', $data, function ($message) {
//
});
如果你想要將郵件消息推送到指定隊列,可以使用queueOn
和laterOn
方法:
Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) {
//
});
Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) {
//
});
開發(fā)發(fā)送郵件的應(yīng)用時,你可能不想要真的發(fā)送郵件到有效的電子郵件地址,而只是想要做下測試。Laravel提供了幾種方式“禁止”郵件的實際發(fā)送。
一種解決方案是在本地開發(fā)時使用log
郵件驅(qū)動。該驅(qū)動將所有郵件信息寫到日志文件中以備查看,想要了解更多關(guān)于每個環(huán)境的應(yīng)用配置信息,查看配置文檔。
Laravel提供的另一種解決方案是為框架發(fā)送的所有郵件設(shè)置通用收件人,這樣的話,所有應(yīng)用生成的郵件將會被發(fā)送到指定地址,而不是實際發(fā)送郵件指定的地址。這可以通過在配置文件config/mail.php
中設(shè)置to
選項來實現(xiàn):
'to' => [
'address' => 'dev@domain.com',
'name' => 'Dev Example'
],
最后,你可以使用Mailtrap服務(wù)和smtp
驅(qū)動發(fā)送郵件信息到“虛擬”郵箱,這種方法允許你在Mailtrap的消息查看器中查看最終的郵件。
更多建議: