今天 user 來電,跟我說我的程式沒有正常送出月報。執行後我如果嘗試印出 PHPmailer 的 errorInfo,會出現以下錯誤訊息:

SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting

只說 SMTP 連不上,超簡約的錯誤訊息。請 IT 幫忙查 mail server,看到以下訊息:

connect_from=[xxx.xxx.xxx.xxx],state=550 X.7 Couldn't start TLS!
Receiving HELO command
EHLO xxx.xxx.xxx.xxx
HELO command end
Couldn't start TLS: SSL connect accept failed because of handshake problems error: 14094416: SSL routines: SSL_READ_BYTES: sslv3 alert certificate unknown
Receving QUIT command
QUIT command end

看到有正常執行完畢,只是 sslv3 alert certificate unknown,真是一段好聚好散的 LOG。

其實同時 PHP log 也會針對這段 handshake 失敗有個訊息:

[14-May-2021 05:44:32 UTC] PHP Warning:  stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages:
error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
in D:\Projects\PHPMailer\class.smtp.php 

後來發現是 Mail server 沒有裝憑證,上網查了一下,參考《PHP 使用 PHPMailer 遇到 SSL operation failed 的解法》,PHPMailer 預設會開啟 TLS,所以把它關掉就可以了:

  $mail->SMTPAutoTLS = false;

假設我的程式是這樣:

<?php
// 此為舊版的引用方法,依照 "Fatal error: Class 'PHPMailer' not found",在 2018 年後發布的 PHPMailer 新版,需要逐層載入
//  $mail = new PHPMailer();
  $mail = new PHPMailer\PHPMailer\PHPMailer();
  $mail->IsSMTP();
  $mail->CharSet = "UTF-8";
  $mail->Encoding = "base64";
  $mail->Host = "smtp.test.com.tw";
  $mail->From = "fanny@test.org.tw";
  $mail->FromName = "Fanny";
  $mail->Subject = "Hello World!";
  $mail->SMTPDebug = 1;
  // 1 = errors and messages
  // 2 = messages only
  $mail->SMTPAutoTLS = false;  // 關掉 TLS

  $body = "<p>Hello World!</p>";
  $mail->MsgHTML($body);
  $mail->AddAddress("fanny@test.org.tw","Test receiver");
  if($mail->Send()){
    $success = true;
  }else{
    $success = false;
    print_r($mail);
    writeLog("Error:".$mail->ErrorInfo);
  }
?>  

或是請 SMTP server 裝上正確憑證,也可以正常運作。

 

arrow
arrow
    文章標籤
    phpmailer smtp
    全站熱搜
    創作者介紹
    創作者 小攻城師 的頭像
    小攻城師

    小攻城師的戰場筆記

    小攻城師 發表在 痞客邦 留言(0) 人氣()