首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

ThinkPHP 5/6 整合 PHPMailer 發送郵件:從零到生產級的完整教程

     編輯:PHP 綜合知識

環境準備

  • ThinkPHP 5.1+ / 6.0+
  • PHP 7.2+
  • Composer 管理依賴(推薦)

步驟 1:安裝 PHPMailer

# 專案根目錄執行
composer require phpmailer/phpmailer

或手動下載放入 extend/PHPMailer(不推薦,難維護)。

步驟 2:配置郵件參數

<!-- config/mail.php -->
<?php
return [
    'host'       => 'smtp.qq.com',      // SMTP 服務器
    'port'       => 465,                // SSL 端口 465 / TLS 端口 587
    'username'   => 'your@qq.com',      // 郵箱賬號
    'password'   => 'auth_code',        // 授權碼(非登錄密碼)
    'from_email' => 'your@qq.com',      // 發件人郵箱
    'from_name'  => '我的應用',          // 發件人顯示名
    'charset'    => 'UTF-8',
    'timeout'    => 30,
];

步驟 3:封裝 Service 類(推薦單例模式)

<?php
// app/service/MailService.php
namespace app\service;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use think\facade\Config;

class MailService {
    protected static ?self $instance = null;
    protected PHPMailer $mailer;

    private function __construct() {
        $this->mailer = new PHPMailer(true);
        $this->configure();
    }

    public static function instance(): self {
        return self::$instance ??= new self();
    }

    protected function configure(): void {
        $cfg = Config::get('mail');
        $m = $this->mailer;
        $m->isSMTP();
        $m->Host       = $cfg['host'];
        $m->Port       = $cfg['port'];
        $m->SMTPAuth   = true;
        $m->Username   = $cfg['username'];
        $m->Password   = $cfg['password'];
        $m->SMTPSecure = $cfg['port'] === 465 ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
        $m->CharSet    = $cfg['charset'];
        $m->Timeout    = $cfg['timeout'];
        $m->setFrom($cfg['from_email'], $cfg['from_name']);
        // 開發環境可關閉驗證
        if (app()->isDebug()) {
            $m->SMTPOptions = [
                'ssl' => ['verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true]
            ];
        }
    }

    /**
     * 發送郵件
     * @param string|array $to 收件人郵箱或 [email => name]
     * @param string $subject 主題
     * @param string $htmlBody HTML 正文
     * @param string|null $altBody 純文本備用正文
     * @param array $attachments 附件 [['path'=>..., 'name'=>...], ...]
     * @return bool
     */
    public function send($to, string $subject, string $htmlBody, ?string $altBody = null, array $attachments = []): bool {
        try {
            $m = $this->mailer;
            $m->clearAddresses();
            $m->clearAttachments();
            
            foreach ((array)$to as $email => $name) {
                is_int($email) ? $m->addAddress($name) : $m->addAddress($email, $name);
            }
            $m->Subject = $subject;
            $m->msgHTML($htmlBody);
            $m->AltBody = $altBody ?? strip_tags($htmlBody);
            
            foreach ($attachments as $att) {
                $m->addAttachment($att['path'], $att['name'] ?? basename($att['path']));
            }
            return $m->send();
        } catch (Exception $e) {
            think\facade\Log::error('Mail send failed: ' . $e->getMessage());
            return false;
        }
    }
}

步驟 4:控制器/業務層調用

<?php
// app/controller/UserController.php
namespace app\controller;

use app\service\MailService;
use think\facade\View;

class UserController {
    public function register() {
        // ... 驗證、入庫 ...
        $userEmail = 'newuser@example.com';
        $html = View::fetch('mail/welcome', ['username' => '張三']);
        
        $ok = MailService::instance()->send(
            $userEmail,
            '歡迎註冊!',
            $html
        );
        return json(['code' => $ok ? 0 : 1, 'msg' => $ok ? '郵件發送成功' : '郵件發送失敗']);
    }
}

郵件模板範例

<!-- view/mail/welcome.html -->
<div style="font-family:Microsoft YaHei,sans-serif;line-height:1.6;color:#333">
  <h2>歡迎加入,{$username}!</h2>
  <p>您的賬號已成功註冊,現在可以開始使用我們的服務。</p>
  <p><a href="{:url('index/index')}" style="color:#007bff">立即體驗</a></p>
  <hr>
  <small>此郵件由系統自動發送,請勿直接回覆。</small>
</div>

常見問題排查表

現象可能原因解決方案
連接超時端口錯誤/防火牆/雲服務商封禁 25/465/587用 465 (SSL) 或 587 (TLS);檢查安全組;改用 API 發信
認證失敗用了登錄密碼而非授權碼郵箱設置中生成 SMTP 授權碼
進垃圾箱缺 SPF/DKIM/DMARC、內容觸發規則配置域名解析記錄;優化內容;使用企業郵箱/發信服務商
中文亂碼CharSet 未設為 UTF-8$mail->CharSet = 'UTF-8';

生產級建議

  • 異步發送:將發信任務推入隊列(Redis/RabbitMQ),控制器秒級響應
  • 重試機制:失敗自動重試 3 次,指數退避
  • 發信服務商:大量業務郵件建議接入 SendCloud、Mailgun、阿里雲邮件推送等,提升到達率
  • 日誌審計:記錄發信請求、結果、錯誤碼,便於排查
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved