郵件
簡介
laravel 基於流行的 SwiftMailer 類庫構建了一種乾淨簡潔的郵件 API。laravel 提供了驅動以支援 SMTP,Mandrill,SparkPost,Amazon SES,PHP 的 mail 方法和 sendmail 方法,這允許你快速的開始構建通過本地或雲端服務發送郵件的功能。
驅動先決條件
基於 API 的驅動程式如 Mailgun 和 Mandrill 通常要比 SMTP 服務簡單快速。所有的 API 驅動都必須引入 Guzzle HTTP 類庫,你可以通過在 composer.json 檔案中添加下面的內容來進行安裝:
"guzzlehttp/guzzle": "~5.3|~6.0"
Mailgun 驅動
如果使用 Mailgun 驅動,你首先需要安裝 Guzzle,然後設定 config/mail.php 設定檔的 driver 選項為 mailgun。然後,你需要確認你的 config/services.php 設定檔中包含以下選項:
'mailgun' => [ 'domain' => 'your-mailgun-domain', 'secret' => 'your-mailgun-key',],
Mandrill 驅動
如果使用 Mandrill 驅動,你首先需要安裝 Guzzle,然後設定 config/mail.php 設定檔的 driver 選項為 mandrill。接著,你需要確認你的 config/services.php 設定檔中包含以下選項:
'mandrill' => [ 'secret' => 'your-mandrill-key',],
SparkPost 驅動
如果使用 SparkPost 驅動,你首先需要安裝 Guzzle,然後設定你的 config/mail.php 設定檔中的 driver 選項為 sparkpost。接著,你需要確認你的 config/services.php 設定檔中包含以下選項:
'sparkpost' => [ 'secret' => 'your-sparkpost-key',],
SES 驅動
如果使用 Amazon SES 驅動,你需要在 PHP 中引入 Amazon AWS SDK。你可以通過在 composer.json 檔案中進行引入安裝:
"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],
發送郵件
laravel 允許你使用視圖來儲存你的郵件資訊。比如,你可以在 resources/views 目錄下建立一個 emails 目錄來管理你的郵件視圖:
你需要使用 Mail 假面的 send 方法來發送一個郵件。send 方法接收三個參數,第一個參數應該是視圖的名稱。第二個參數應該是傳遞到視圖中的資料所組成的數組。最後,是一個 Closure 回呼函數,這個回呼函數會接收一個 message 執行個體,這允許你自由的配置收件者,主題,和其他方面的郵件資訊:
$user], function ($m) use ($user) { $m->from('hello@app.com', 'Your Application'); $m->to($user->email, $user->name)->subject('Your Reminder!'); }); }}
因為上面的樣本中我們傳遞了 user 鍵到數組中,所以我們可以在我們的郵件視圖中使用使用者的名稱:
name; ?>
注意: 一個 $message 變數會自動的傳遞到郵件視圖,並且允許內聯附件。所以,你應該避免手動的傳遞到視圖 message 變數。
構建一個 Message
就如我們上面談到的,傳遞到 send 方法的第三個參數是一個 Closure,這個閉包允許你設定郵件資訊的各種選項。使用閉包,你可以指定資訊的其它屬性,比如複寫,密抄等:
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 = []);// 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 資訊類的方法。
純文字郵件
預設的,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){ //});
附件
你可以使用傳遞到閉包中的 $message 對象的 attach 方法來在郵件中添加附件。attach 方法接收一個完整的檔案路徑作為第一個參數:
Mail::send('emails.welcome', $data, function ($message) { // $message->attach($pathToFile); });
當你添加一個郵件附件時,你可能也需要指定附件顯示的名稱或者 MIME type。你可以向 attach 方法傳遞一個數組作為第二個參數:
$message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);
attachData 方法可以用來添加一個原始位元組字串作為一個附件。比如,你可能需要使用這個方法來將記憶體中產生的 PDF 直接添加到附件中,而不需要先儲存到磁碟:
$message->attachData($pdf, 'invoice.pdf');$message->attachData($pdf, 'invoice.pdf', ['mime' => $mime]);
內聯附件
在郵件視圖中嵌入一個圖片
在郵件中內聯一個圖片通常是比較笨重的。但是,laravel 提供了一種便捷的方式在你的郵件中附加一個圖片並且取回適當的 CID。你需要在郵件視圖中使用 $message 變數的 embed 方法。你應該記得,Laravel 會自動的建立一個 $message 變數並將其傳遞到你的郵件視圖中:
Here is an image: embed($pathToFile); ?>"
嵌入未經處理資料到視圖
如果你希望嵌入一個未經處理資料到郵件資訊中,你可以使用 $message 變數的 embedData 方法:
Here is an image from raw data: embedData($data, $name); ?>"
郵件隊列
隊列化郵件資訊
由於發送郵件是非常消耗資源的一件事,這樣會影響到應用的回應時間。所以很多開發人員都選擇使用隊列來完成非同步郵件發送。Laravel 使用統一的隊列介面來使這些非常簡單。你需要使用 Mail 假面的 queue 方法來使郵件隊列化:
Mail::queue('emails.welcome', $data, function ($message) { // });
該方法會自動的在隊列添加發送郵件的任務,該任務會在後台自動的執行。當然,你需要先配置好隊列。
延遲訊息佇列
如果你希望順延強制郵件的發送隊列。你需要使用 later 方法。你需要在方法的第一個參數傳送一個你希望順延強制的秒數:
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) { // });
郵件 & 本地開發
當開發一個發送郵件的服務時,你可能並不希望真實的去發送一個郵件。只需要類比測試成功就可以了。laravel 提供了多種方式來禁用真實的郵件發送。
log 驅動
其中一個解決方案就是在本地開發時使用 log 郵件驅動。這個驅動會將所有的郵件資訊寫入到記錄檔中。
通用的郵件
另外一個解決方案就是設定一個通用的郵件來接收所有的應用發出的郵件。這種方式,會使應用產生的所有郵件都發送到這個地址。你可以通過配置 config/mail.php 檔案的 to 選項來進行設定:
'to' => [ 'address' => 'dev@domain.com', 'name' => 'Dev Example'],
mailtrap
最後,你也可以使用一些像 Mailtrap 和 smtp 驅動的服務來發送你的郵件到一個虛擬郵箱,而且你也可以通過真實的郵件用戶端進行查看。這可以使你看到真實的郵件在 Mailtrap 中的顯示效果。
事件
laravel 會在發送郵件之前觸發事件。你應該注意的是,它是在郵件發送之前觸發事件,而不是添加到隊列時。你可以在 EventServiceProvider 中註冊一個事件監聽者:
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ 'Illuminate\Mail\Events\MessageSending' => [ 'App\Listeners\LogSentMessage', ], ];