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

PHPMailer SMTP 發送失敗「Could not connect to SMTP host」三大根因與修復方案

     編輯:PHP 相關知識

錯誤現場

SMTP Error: Could not connect to SMTP host. send fail

根因一:大小寫導致誤進 MailSend 分支(歷史版本 Bug)

現象:IsSMTP() 內部設置 $this->Mailer = 'smtp' (小寫),但 switch($this->Mailer) 中 case 'smtp': 區分大小寫,導致落入 default: 分支,改用 MailSend() (本地 mail() 函數) 而非真正 SMTP。

修復

// class.phpmailer.php
function IsSMTP() {
    $this->Mailer = 'SMTP'; // 改為大寫
}

此問題存在於舊版 PHPMailer (5.x 早期),新版 (6.x+) 已修復。若仍用舊版建議升級。

根因二:服務器禁用 fsockopen()(虛擬主機常見)

原因:安全策略禁用 fsockopen,導致 SMTP 連接建立失敗。

修復方案(按優先級)

  1. 改用 pfsockopen (持久連接):
    // class.smtp.php
    $this->smtp_conn = @pfsockopen($host, $port, $errno, $errstr, $tval);
    
  2. 改用 stream_socket_client() (PHP 5.1+ 內置,繞過禁用):
    $this->smtp_conn = @stream_socket_client(
        "tcp://{$host}:{$port}",
        $errno, $errstr, $tval,
        STREAM_CLIENT_CONNECT
    );
    
  3. 聯系主機商解禁 或遷移至支持的主機。

根因三:防火牆/安全組阻擋出站 SMTP 端口(25/465/587)

排查步驟

  1. 服務器內執行 telnet smtp.exmail.qq.com 465 或 openssl s_client -connect smtp.gmail.com:465。
  2. 若不通,檢查:
    • 本機 iptables -L -n / Windows 防火牆出站規則。
    • 雲廠商安全組:出站規則放行 TCP 25/465/587。
    • 數據中心/ISP 封鎖 25 端口(極常見)→ 強制用 465 (SSL) 或 587 (STARTTLS)。
  3. 臨時關閉防火牆驗證(systemctl stop firewalld),確認為防火牆問題後再精準放行。

綜合排查清單

步驟命令/操作預期結果
1. PHPMailer 版本composer show phpmailer/phpmailer≥ 6.5.0 (含大小寫修復)
2. 函數可用性php -r "var_dump(function_exists('fsockopen'));"bool(true)
3. 端口連通性telnet smtp.host 465Connected / 顯示 220 banner
4. SSL/TLS 驗證openssl s_client -connect smtp.host:465Certificate chain 正常
5. PHPMailer 參數Host/Port/SMTPSecure/Username/Password與郵件服務商文檔一致

延伸閱讀

  • Fatal error: Call to undefined function date_default_timezone_set()
  • Fatal error: Class 'SoapClient' not found
  • Fatal error: Class 'ZipArchive' not found
  • PHP date() 時區警告解決
  • PHP Maximum execution time of 30 seconds exceeded
  • 網頁緩存控制 Cache-Control 詳解
  • PHP 運行出現 Call to undefined function curl_init 排查
  • PHP ob_flush vs flush 區別深度理解
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved