iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 15
1
Modern Web

寫給朋友的 PHP 從 0 到 100 實戰教程系列 第 15

Day 15. PHP教學: 用 phpmailer + gmail smtp 實作寄信功能

Why
為什麼要學這個呢?
因為很多時候我們需要發電子郵件給用戶,可能是註冊確認信、
或是密碼重置信或訂單確認信。

為什麼要用 Gmail smtp 呢?
因為如果單純使用 php 內建的 mail() function
所以非常高的可能性會直接被當成垃圾信,甚至直接擋掉
這是因為曾經有人用這個方式狂送垃圾信,導致被各大廠封殺。
為了讓我們的信正常的送達目標信箱,
所以我們使用被信任的 Gmail 的 SMTP 服務

How
首先用省麻煩大師 composer 來安裝 phpmailer 最新套件,
開啟終端機,切到專案目錄後,輸入下方指令

composer require phpmailer/phpmailer

為什麼我會知道這個?在 google 輸入 『php mail github』
用這幾個關鍵字來搜尋很容易就找到它了

切到 libraries 目錄 新增一個檔案 Mail.php
目的是要透過這個 class 來使用我們裝好的套件 PHPMailer

<?php
use PHPMailer\PHPMailer;

class Mail extends PHPMailer\PHPMailer {
    public $Host     = 'smtp.gmail.com';
    public $Mailer   = 'smtp';
    public $SMTPAuth = true;
    public $Username = '';
    public $Password = '';
    public $SMTPSecure = 'tls';
    public $WordWrap = 75;

    public function __construct($Username, $Password){
        $this->Username = $Username;
        $this->Password = $Password;
    }

    public function subject($subject) {
        $this->Subject = $subject;
    }

    public function body($body) {
        $this->Body = $body;
    }

    public function send() {
        $this->AltBody = strip_tags(stripslashes($this->Body))."\n\n";
        $this->AltBody = str_replace(" ", "\n\n", $this->AltBody);
        return parent::send();
    }
}

到 config 目錄中,也新增一個 config.php

<?php
class Config {
    const BASE_URL = "http://127.0.0.1/game/";
    const MAIL_FROM = "no_reply@mail.com";
    const MAIL_FROM_NAME = "your name";  
    const MAIL_USER_NAME = "example@gmail.com"; // 用來寄信的 GMAIL 帳號
    const MAIL_USER_PASSWROD = "password";      // 用來寄信的 GMAIL 密碼
}

用來寄信的 gmail 需要調降安全性,才能給我們的伺服器來連線使用

https://myaccount.google.com/lesssecureapps?pli=1

https://ithelp.ithome.com.tw/upload/images/20180101/20107394eoMKDZPhPk.png

記得新增後要下達 composer 更新指令

composer dump

於是在 route.php 中就可以加上這段,直接開始使用囉

switch($route->getParameter(1)){
    case "do_mail"; // 網址就會是 http://127.0.0.1/game/do_mail
      try { 
        $to = "enter_your_mail_addres@gmail.com";
        $subject = "sample subject";
        $body = "sample content";
        $mail = new Mail(Config::MAIL_USER_NAME, Config::MAIL_USER_PASSWROD);
        $mail->setFrom(Config::MAIL_FROM, Config::MAIL_FROM_NAME);
        $mail->addAddress($to);
        $mail->subject($subject);
        $mail->body($body);
        if($mail->send()){
            echo "success";
        }else{
            echo "fail";
        }
      } catch(Exception $e) {
        echo 'Caught exception: ',  $e->getMessage();
        $error[] = $e->getMessage();
      }
    break;
}

最後打上網址來測試執行

http://127.0.0.1/game/do_mail

What
我們使用了一個新東西

try ... catch ...

這是用來處理異常狀態的內建方法
如果 try { ...有錯誤... }
就會執行 catch(Exception $e) { ...這段... }
讓我們更容易 debug
也可以由我們自己寫判斷邏輯是否有誤
直接在 try { ...裡面... } 直接加上 throw
例如:

<?php
try {
    $error = 'something error';
    throw new Exception($error);

    // 上面 throw 後,下面這行不會被執行
    echo 'execute?';

} catch (Exception $e) {
    echo 'exception: '. $e->getMessage();
}

上一篇
Day 14. PHP教學: 學習日期與時間控制
下一篇
Day 16. PHP教程: 將 MySQLi 升級為 PDO (PHP Data Object)
系列文
寫給朋友的 PHP 從 0 到 100 實戰教程30

尚未有邦友留言

立即登入留言