Laravel - 上手實現 - 郵件發送


Laravel 自帶 SwiftMailer 庫,集成了多種郵件API,可以很方便的實現郵件的發送。
我們使用到的是SMTP(Simple Message Transfer Protocol)簡單郵件傳輸協議,通常理解為郵件發送服務器。

1、開啟POP3和SMTP服務

1.1、在這里我們以QQ郵箱為案例

設置 -> 賬戶 -> POP3 -> 開啟

到這一步會提示驗證,按照提示發送短信通過驗證:

短信發送成功,會出現如下提示、也就代表配置成功。你需要記錄密鑰,這個東西會在配置中用:

1.2、在這里我們以 163郵箱為案例

后期有時間在維護。。。。理解理解。。。

2、對 Laravel 框架中郵件發送的配置文件進行修改:

.env 文件:

MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=********@qq.com
MAIL_PASSWORD=qq郵箱此處填寫上圖產生的授權碼
MAIL_FROM_NAME=郵箱的名稱
MAIL_ENCRYPTION=ssl

config/mail.php 文件:

return [
    'driver' => env('MAIL_DRIVER', 'smtp'),
    'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
    'port' => env('MAIL_PORT', 587),
    'from' => [
        'address' => env("MAIL_USERNAME", ""),
        'name' => env("MAIL_FROM_NAME")
    ],
    'encryption' => env('MAIL_ENCRYPTION'),
    'username' => env('MAIL_USERNAME'),
    'password' => env('MAIL_PASSWORD'),
    'sendmail' => '/usr/sbin/sendmail -bs',
    'pretend' => env('MAIL_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發送郵件。
    // 就目前狀況來看,使用smtp是最明智的選擇;
    // mail不安全,sendmail需要安裝配置Sendmail/Postfix,其他要么付費要么不能用。

// host:郵箱所在主機;
    // 使用163郵箱,對應值是smtp.163.com;
    // 使用QQ郵箱,對應值是smtp.qq.com。
    // 使用騰訊企業郵箱,對應值是smtp.exmail.qq.com

// port:用於配置郵箱發送服務端口號,
    // 一般默認值是25,但如果設置SMTP使用SSL加密,該值為465。

// from:配置項包含address和name,
    // address 表示你自己的郵箱
    // name 表示你郵件用戶名(這里郵箱,是用來發郵件的郵箱)。

// encryption:表示加密類型;
    // 可以設置為null表示不使用任何加密,也可以設置為tls或ssl。

// username: 表示郵箱賬號,比如123456789@qq.com
// password 表示上述郵箱登錄對應登錄密碼。
    // 注意QQ郵箱的話應該開啟POP3|SMTP服務時給的授權碼。
// sendmail: 是在設置driver為sendmail時使用,用於指定sendmail命令路徑。
// pretend: 用於配置是否將郵件發送記錄到日志中;
    // 默認為false則發送郵件不記錄日志;
    // 如果為true的話只記錄日志不發送郵件,這一配置在本地開發中調試時很有用

3、生產控制器、配置路由

php artisan make:controller MailController
Route::any('mail/send','MailController@sendMail');

4、編輯控制器、加入以下代碼:

// 記得使用內置的郵件類 use Illuminate\Support\Facades\Mail;
public function sendMail() {
    $name = '這是郵件發送的標題'; 
    // Mail::send()的返回值為空,所以可以其他方法進行判斷 
    // Mail::send();需要傳三個參數;
    // 第一個為引用的模板
    // 第二個為給模板傳遞的變量(郵箱發送的文本內容)
    // 第三個為一個閉包,參數綁定Mail類的一個實例。
    Mail::send('emails.test',['name'=>$name],function($message){ 
        $to = 'itlaowen@qq.com'; 
        $message ->to($to)->subject('郵件測試'); 
    }); 
    // 返回的一個錯誤數組,利用此可以判斷是否發送成功
    dd(Mail::failures());  
} 

5、由於上面👆指定了郵件發送的視圖層、所以去編輯

在resources/emails下創建一個模板文件。

這是測試郵件!!
{{$name}} 

6、測試

訪問:http://localhost/mail/send 如果返回一個空數組則表示郵件發送成功。

7、報錯:stream_socket_client() 、certificate verify failed

具體報錯如下:

stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed

原因:

php openssl 沒有加載 ca 證書 , 去下載個 ca 證書然后添加進去即可

解決:

查看phpinfo()、檢查openssl.cafile的文件是否存在
不存在的話進行如下操作
1、找到自己的 php 的安裝目錄
2、進入目錄:cd php/etc/
3、下載 ca 證書:wget http://curl.haxx.se/ca/cacert.pem
4、查看目錄:pwd
5、編輯 php.ini:vim php.ini
6、修改 openssl.cafile 的路徑 openssl.cafile=/usr/local/php/etc/cacert.pem

7.2 報錯 Expected response code 250 but got code "501"

具體報錯如下:

Expected response code 250 but got code "501", with message "501 Mail from address must be same as authorization user. "

解決:
在.env文件中增加兩行
MAIL_FROM_ADDRESS=你的郵箱
MAIL_FROM_NAME=你的郵箱

MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=你的郵箱
MAIL_FROM_ADDRESS=你的郵箱
MAIL_FROM_NAME=你的郵箱
MAIL_PASSWORD=授權碼
MAIL_ENCRYPTION=ssl

8、擴展:發送純文本郵件

public function sendEmail()
{
    // 純文本信息郵件測試
    Mail::raw('你好,我是PHP程序!', function ($message) {
        $to = 'itlaowen@163.com';
        $message ->to($to)->subject('純文本信息郵件測試');
    });
    if (count(Mail::failures()) < 1) {
        echo '發送郵件成功,請查收!';
    } else {
        echo '發送郵件失敗,請重試!';
    }
}

9、擴展:郵件內容中增加圖片

視圖文件:

{{$name}} 
<br>
hello world。
<br>
<img src="{{ $message->embed($image) }}">

控制器:

public function sendEmail()
{
    // 郵件內部附件
    $name = '郵件內部附件';
    $image = public_path('php/8I0BHkS2QKmxyfQBBfiamBZALR5Ox2zkN62KFFoP.jpeg');
    // $image = 'http://t8.baidu.com/it/u=1484500186,1503043093&fm=79&app=86&f=JPEG?w=1280&h=853';//網上圖片
    Mail::send('Emails.test', ['image' => $image, 'name' => $name], function ($message) {
        $to = 'itlaowen@163.com';
        $message->to($to)->subject('圖片測試');
    });
    if (count(Mail::failures()) < 1) {
        echo '發送郵件成功,請查收!';
    } else {
        echo '發送郵件失敗,請重試!';
    }
}

10、擴展:郵件附件

public function sendEmail()
{
    // 發送附件郵件
    $name = '這是帶附件的郵件';
    $image = 'http://t8.baidu.com/it/u=1484500186,1503043093&fm=79&app=86&f=JPEG?w=1280&h=853'; //網上圖片
    Mail::send('Emails.test', ['image' => $image, 'name' => $name], function ($message) {
        $to = 'itlaowen@163.com';
        $message->to($to)->subject('郵件測試');
        $attachment = public_path('file/1.xlsx');
        // 在郵件中上傳附件 
        $message->attach($attachment, ['as' => '中文文檔.xlsx']);
    });
    if (count(Mail::failures()) < 1) {
        echo '發送郵件成功,請查收!';
    } else {
        echo '發送郵件失敗,請重試!';
    }
}

如果出現亂碼、可以嘗試以下寫法:

$message->attach($attachment,['as'=>"=?UTF-8?B?".base64_encode('中文文檔')."?=.xls"]);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM