[TOC]
### **1、簡介**
[Laravel](http://laravelacademy.org/tags/laravel "View all posts in Laravel")?基于?[SwiftMailer](http://swiftmailer.org/)?庫提供了一套干凈清爽的[郵件](http://laravelacademy.org/tags/%e9%82%ae%e4%bb%b6 "View all posts in 郵件")API。Laravel為[SMTP](http://laravelacademy.org/tags/smtp "View all posts in SMTP")、[Mailgun](http://laravelacademy.org/tags/mailgun "View all posts in Mailgun")、Mandrill、Amazon SES、PHP 的`mail`函數,以及`sendmail`提供了驅動,從而允許你快速通過本地或云服務發送郵件。
#### **郵件驅動預備知識**
基于驅動的 API 如?[Mail](http://laravelacademy.org/tags/mail "View all posts in Mail")gun 和 Mandrill 通常比 SMTP 服務器更簡單、更快。所有的 API 驅動要求應用已經安裝 Guzzle?HTTP 庫。你可以通過添加如下行到`composer.json`文件來安裝 Guzzle 到項目:
~~~
"guzzlehttp/guzzle": "~5.3|~6.0"
~~~
##### **Mailgun驅動**
要使用 Mailgun 驅動(Mailgun 前10000封郵件免費,后續收費),首先安裝 Guzzle,然后在配置文件`config/mail.php`中設置`driver`選項為`mailgun`。接下來,驗證配置文件`config/services.php`包含如下選項:
~~~
'mailgun' => [
'domain' => 'your-mailgun-domain',
'secret' => 'your-mailgun-key',],
~~~
##### **Mandrill驅動**
要使用 Mandrill 驅動(Mandrill不支持中國區用戶注冊,汗!),首先安裝 Guzzle,然后在配置文件`config/mail.php`中設置`driver`選項值為`mandrill`。接下來,驗證配置文件`config/services.php`包含如下選項:
~~~
'mandrill' => [
'secret' => 'your-mandrill-key',],
~~~
##### **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 允許你在[視圖](http://laravelacademy.org/post/2855.html)中存儲郵件信息,例如,要組織你的電子郵件,可以在`resources/views`目錄下創建`emails`目錄。
要發送一條信息,使用`Mail`[門面](http://laravelacademy.org/post/2920.html)上的`send`方法。`send`方法接收三個參數。第一個參數是包含郵件信息的[視圖](http://laravelacademy.org/tags/%e8%a7%86%e5%9b%be "View all posts in 視圖")名稱;第二個參數是你想要傳遞到該視圖的數組數據;第三個參數是接收消息實例的閉包回調——允許你自定義收件人、主題以及郵件其他方面的信息:
~~~
<?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->from('hello@app.com', 'Your Application');$m->to($user->email, $user->name)->subject('Your Reminder!');
});
}
}
~~~
由于我們在上例中傳遞一個包含`user`鍵的數組,我們可以在郵件中使用如下方式顯示用戶名:
~~~
<?php echo $user->name; ?>
~~~
> 注意:`$message`變量總是被傳遞到郵件視圖,并允許嵌入[附件](http://laravelacademy.org/tags/%e9%99%84%e4%bb%b6 "View all posts in 附件"),因此,你應該在視圖負載中避免傳入消息變量。
##### **構造消息**
正如前面所討論的,傳遞給`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 內聯附件**
##### **在郵件視圖中嵌入一張圖片**
嵌套內聯圖片到郵件中通常是很笨重的,然而,Laravel提供了一個便捷的方式附加圖片到郵件并獲取相應的CID,要嵌入內聯圖片,在郵件視圖中使用`$message`變量上的`embed`方法。記住,Laravel自動在所有郵件視圖中傳入`$message`變量使其有效:
~~~
<body>
Here is an image:
<img src="<?php echo $message->embed($pathToFile); ?>">
</body>
~~~
##### **在郵件視圖中嵌入原生數據**
如果你想要在郵件消息中嵌入原生數據字符串,可以使用`$message`變量上的`embedData`方法:
~~~
<body>
Here is an image from raw data:
<img src="<?php echo $message->embedData($data, $name); ?>">
</body>
~~~
#### **2.3 郵件[隊列](http://laravelacademy.org/tags/%e9%98%9f%e5%88%97 "View all posts in 隊列")**
##### **郵件消息隊列**
發送郵件消息可能會大幅度延長應用的響應時間,許多開發者選擇將[郵件發送](http://laravelacademy.org/tags/%e9%82%ae%e4%bb%b6%e5%8f%91%e9%80%81 "View all posts in 郵件發送")放到隊列中再后臺執行,Laravel中可以使用內置的統一隊列API來實現。要將郵件消息放到隊列中,使用`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) {
//
});
~~~
### **3、郵件&本地開發**
開發發送郵件的應用時,你可能不想要真的發送郵件到有效的電子郵件地址,而只是想要做下測試。Laravel提供了幾種方式“禁止”郵件的實際發送。
##### **日志驅動**
一種解決方案是在本地開發時使用`log`郵件驅動。該驅動將所有郵件信息寫到日志文件中以備查看,想要了解更多關于每個環境的應用配置信息,查看[配置文檔](http://laravelacademy.org/post/2726.html#environment-configuration)。
##### **通用配置**
Laravel提供的另一種解決方案是為框架發送的所有郵件設置通用收件人,這樣的話,所有應用生成的郵件將會被發送到指定地址,而不是實際發送郵件指定的地址。這可以通過在配置文件`config/mail.php`中設置`to`選項來實現:
~~~
'to' => [
'address' => 'dev@domain.com',
'name' => 'Dev Example'
],
~~~
##### **[Mailtrap](http://laravelacademy.org/tags/mailtrap "View all posts in Mailtrap")**
最后,你可以使用[Mailtrap](https://mailtrap.io/)服務和`smtp`驅動發送郵件信息到“虛擬”郵箱,這種方法允許你在Mailtrap的消息查看器中查看最終的郵件。
### **4、[事件](http://laravelacademy.org/tags/%e4%ba%8b%e4%bb%b6 "View all posts in 事件")**
Laravel 會發送郵件前觸發一個事件,記住,這個事件是在郵件被發送時觸發,而不是推送到隊列時,你可以在`EventServiceProvider`?中注冊事件監聽器:
~~~
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\LogSentMessage',
],
];
~~~
- 序言
- 發行版本說明
- 升級指南
- 貢獻代碼
- 開始
- 安裝
- 配置
- Laravel Homestead
- 基礎
- HTTP 路由
- HTTP 中間件
- HTTP 控制器
- HTTP 請求
- HTTP 響應
- 視圖
- Blade 模板引擎
- 架構
- 一次請求的生命周期
- 應用目錄結構
- 服務提供者
- 服務容器
- 門面(Facades)
- 數據庫
- 起步
- 查詢構建器
- 遷移
- 填充數據
- Eloquent ORM
- 起步
- 關聯關系
- 集合
- 訪問器&修改器
- 序列化
- 服務
- 用戶認證
- 用戶授權
- Artisan Console
- 訂閱支付實現:Laravel Cashier
- 緩存
- 集合
- 集成前端資源:Laravel Elixir
- 加密
- 錯誤&日志
- 事件
- 文件系統/云存儲
- 哈希
- 輔助函數
- 本地化
- 郵件
- 包開發
- 分頁
- Redis
- 隊列
- Session
- Envoy Task Runner
- 任務調度
- 測試
- 驗證
- 新手入門指南
- 簡單任務管理系統
- 帶用戶功能的任務管理系統