使用 PHPMailer 透過 Gmail SMTP 發送大量郵件時,常遭遇認證失敗、SSL/TLS 設定錯誤、連線中斷等問題。本文彙整實戰中最高頻的坑點,提供完整的環境配置、程式碼修正與最佳實踐指南。
| 錯誤現象 | 根本原因 | 解決方案 |
|---|---|---|
Could not authenticate | 帳密錯誤、未開啟「低安全性應用程式存取權」、雙因子驗證衝突 | 確認帳密、開啟應用程式密碼、檢查 Gmail 安全性設定 |
| 迴圈發送第 2 封失敗 | SMTP 連線未正確關閉,導致連線殘留 | 每次 send() 後必須呼叫 SmtpClose() |
SSL context creation failed | PHP 未啟用 OpenSSL 擴充套件 | 安裝並啟用 php_openssl |
| 連線逾時/無回應 | Port/加密協議不匹配 | Gmail: SSL+465 或 TLS+587,二選一 |
php.ini 取消註解:extension=openssllibeay32.dll、ssleay32.dll 至 C:\Windows\System32\(PHP 7+ 通常內建)# 以 PHP 5.2.14 為例 cd /usr/src/php-5.2.14/ext/openssl /usr/local/php/bin/phpize mv config0.m4 config.m4 ./configure --with-openssl --with-php-config=/usr/local/php/bin/php-config make && make install # 複製產生的 openssl.so 至 extension_dir echo "extension=openssl.so" >> /usr/local/php/lib/php.ini service httpd restart
舊版 PHPMailer 需手動修改原始碼支援 Is_SSL 屬性。現代版本(≥ 5.2)已內建 SMTPSecure 選項,**無需修改核心檔案**即可正常運作。
isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Username = 'your@gmail.com';
$mail->Password = 'your_app_password'; // 應用程式密碼,非登入密碼
$mail->SMTPSecure = 'tls'; // 'ssl' 或 'tls'
$mail->Port = 587; // tls=587, ssl=465
// 信件內容
$mail->setFrom('your@gmail.com', '寄件者名稱');
$mail->addAddress('recipient@example.com', '收件者');
$mail->isHTML(true);
$mail->Subject = '測試主旨';
$mail->Body = 'HTML 內容
支援中文
';
$mail->AltBody = '純文字備用內容';
$mail->CharSet = 'UTF-8';
$mail->send();
echo '發送成功';
} catch (Exception $e) {
echo "發送失敗: {$mail->ErrorInfo}";
}
$mail->Password// 1. 單一 SMTP 連線複用發送多封(大幅降低連線開銷)
$mail->SMTPKeepAlive = true;
foreach ($recipients as $to) {
$mail->clearAddresses();
$mail->addAddress($to['email'], $to['name']);
$mail->Subject = "個人化主旨 {$to['name']}";
$mail->Body = "個人化內容...";
if (!$mail->send()) {
error_log("發送給 {$to['email']} 失敗: {$mail->ErrorInfo}");
continue; // 單封失敗不中斷整批
}
}
// 2. 批次間適度休眠,避免觸發 Gmail 速率限制
if ($i % 50 === 0) sleep(2);
// 3. 發送完畢正確關閉
$mail->smtpClose();
SMTPDebug = 2; // 除錯輸出
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->Username = 'test@gmail.com';
$mail->Password = 'app_password_here';
$mail->setFrom('test@gmail.com', 'Tester');
$mail->addAddress('target@example.com');
$mail->Subject = 'PHPMailer Gmail Test';
$mail->Body = '測試內容 ' . date('Y-m-d H:i:s');
if ($mail->send()) echo "OK\n"; else echo "FAIL: {$mail->ErrorInfo}\n";
telnet smtp.gmail.com 587:測試網路連通性openssl s_client -connect smtp.gmail.com:465 -crlf:測試 SSL 握手/var/log/maillog 或 PHP 錯誤日誌遵循「應用程式密碼 + TLS 587 + SMTPKeepAlive + 正確錯誤處理」四大原則,PHPMailer 群發 Gmail 即可穩定、高效運行。