在 Laravel 5.1 中使用SMTP驅動實現郵件發送(含附件和圖片)詳細教學

2020-08-14 21:08:15

原文地址
1、組態檔
Laravel整合了SwiftMailer庫進行郵件發送,郵件組態檔位於config/mail.php:


return [

    'driver' => env('MAIL_DRIVER', 'smtp'),

    'host' => env('MAIL_HOST', 'smtp.mailgun.org'),

    'port' => env('MAIL_PORT', 587),

    'from' => ['address' => null, 'name' => null],

    'encryption' => env('MAIL_ENCRYPTION', 'tls'),

    'username' => env('MAIL_USERNAME'),

    'password' => env('MAIL_PASSWORD'),

    'sendmail' => '/usr/sbin/sendmail -bs',

    'pretend' => false,

]

driver用於設定預設的郵件發送驅動,Laravel支援多種郵件驅動方式,包括smtp、Mailgun、Maildrill、Amazon SES、mail和sendmail,Mailgun和Amazon SES都是收費的,Maildrill目前不支援中國區使用者,這三個都是第三方郵件服務。mail驅動使用PHP提供的mail函數發送,sendmail驅動通過Sendmail/Postfix(Linux)提供的命令發送郵件,smtp驅動通過支援ESMTP的SMTP發送郵件。

注:ESMTP即Extended SMTP, 是對標準 SMTP 協定進行的擴充套件,它與 SMTP 服務的區別僅僅是,使用 SMTP 發信不需要驗證使用者帳戶,而用 ESMTP 發信時,伺服器會要求使用者提供使用者名稱和密碼以便驗證身份。
就目前狀況來看,使用smtp是最明智的選擇,mail不安全,sendmail需要安裝設定Sendmail/Postfix,其他要麼付費要麼不能用(汗!)。下面 下麪其它設定的說明都基於driver是smtp。
接下來其他的設定都好理解,host是郵箱所在主機,比如我們使用163郵箱,對應值是smtp.163.com,使用QQ郵箱的話,對應值是smtp.qq.com。

port用於設定郵箱發送伺服器端口號,比如一般預設值是25,但如果設定SMTP使用SSL加密,該值爲465。

from設定項包含address和name,前者表示發送郵箱,後者表示發送郵件使用的使用者名稱。

encryption表示加密型別,可以設定爲null表示不使用任何加密,也可以設定爲tls/ssl。

username表示郵箱賬號,比如[email protected]

password表示上述郵箱登錄對應登錄密碼。

sendmail是在設定driver爲sendmail時使用,用於指定sendmail命令路徑。

pretend用於設定是否將郵件發送記錄到日誌中,預設爲false則發送郵件不記錄日誌,如果爲true的話只記錄日誌不發送郵件,這一設定在本地開發中偵錯時很有用。

根據你的郵箱服務及郵箱賬號填寫該組態檔,當然很多設定值需要在.env中設定。

2、定義路由
爲我們的測試在routes.php定義路由規則:

1

Route::get('mail/send','MailController@send');

3、郵件發送邏輯實現
建立控制器
接下來建立匹配路由的控制器,使用如下命令建立一個乾淨的MailController:

php artisan make:controller MailController --plain
在app/Http/Controllers目錄下生成一個新的控制器MailController:


<?php

namespace App\Http\Controllers;use Illuminate\Http\Request;


use App\Http\Requests;

use App\Http\Controllers\Controller;class MailController extends Controller

{


}

簡單郵件發送實現
在該控制器中新增郵件發送動作send(),我們使用Mail門面的send方法發送郵件,我們先發送一個最簡單的郵件:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Mail;
c


lass MailController extends Controller

{

    public function send()

    {

        $name = '學院君';

        $flag = Mail::send('emails.test',['name'=>$name],function($message){

            $to = '[email protected]';

            $message ->to($to)->subject('測試郵件');

        });

        if($flag){

            echo '發送郵件成功,請查收!';

        }else{
      		echo '發送郵件失敗,請重試!';
        }
    }
}

Mail::send需要傳遞三個參數,第一個是郵件檢視,第二個是傳入檢視的數據,第三個是一個閉包,該閉包中定義了收件人、抄送人(如果有的話)、郵件主題、附件等資訊。郵件的主體內容位於區域性檢視中,下面 下麪我們就來定義這個區域性檢視,在resources/views/emails目錄下新建test.blade.php,編輯其內容如下:

1
{{$name}},這是一封測試郵件
然後我們就可以在瀏覽器中存取http://laravel.app:8000/mail/send發送郵件,如果頁面顯示郵件發送成功,那麼到收件人郵箱就能收到郵件了:

Laravel簡單郵件發送
更簡單的純文字郵件發送
上面的範例僅僅是發送一個字串,對於純文字字串郵件發送,還有更簡單的方法:

Mail::raw('這是一封測試郵件', function ($message) {

    $to = '[email protected]';

    $message ->to($to)->subject('測試郵件');

});

這樣的話無需建立檢視即可完成郵件發送。

發送帶附件的郵件(中文亂碼解決)
當然,郵件內容往往不僅僅是純文字這麼簡單,有時候我們會在郵件中加上附件,那麼這該如何實現呢?

先上程式碼:

$flag = Mail::send('emails.test',['name'=>$name],function($message){

    $to = '[email protected]';

    $message->to($to)->subject('測試郵件');$attachment = storage_path('app/files/test.doc');

    //在郵件中上傳附件

    $message->attach($attachment,['as'=>'測試文件.doc']);

});

從程式碼可知我們使用閉包中$message範例上的attach方法上傳附件,該方法第一個參數是附件地址,第二個參數是一些額外參數,這裏我們通過as指定附件在郵件中的顯示名稱。

注:需要注意的是KaTeX parse error: Undefined control sequence: \Mail at position 22: …e實際上是Illuminate\̲M̲a̲i̲l̲\Message的範例,我們可…message上呼叫Message類的所有方法。
再次存取http://laravel.app:8000/mail/send發送郵件,這樣在收件箱中可以看到附件,但附件名稱出現中文亂碼,解決辦法如下:

$message->attach($attachment,['as'=>"=?UTF-8?B?".base64_encode('測試文件')."?=.doc"]);

通過這樣處理後,就不會有中文亂碼出現了: