首頁  >  文章  >  後端開發  >  Linux伺服器下PHPMailer發送郵件失敗的問題解決的技巧

Linux伺服器下PHPMailer發送郵件失敗的問題解決的技巧

黄舟
黄舟原創
2017-03-06 09:19:012051瀏覽

這篇文章主要給大家介紹了關於如何解決Linux伺服器下PHPMailer發送郵件失敗的問題,文中透過範例程式碼介紹的很詳細,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。

需求

更換伺服器之後,我發現我的發送郵件功能失效了!原來的伺服器是可以的,一定是哪裡出問題了,決定來排查一下。我是用的PHPMailer,SMTP方式寄郵件的。

檢查流程

這個方式先PHP要開啟sockets拓展,查了一下phpinfo頁面,是開啟的:

看了一下openssl也是開啟(因為拿了qq信箱來測),所以沒問題:

那就再看一下allow_url_fopen,開啟的,沒問題:

是不是停用了函數?沒有停用,沒問題:


那配置上就沒有問題了,我就想,是不是連接埠被佔用了?

運行一下:netstat -tnlp

第一條就是這玩意:

25埠被佔用,被一個叫master的玩意佔了,好傢伙,看看是什麼東西,運行ps -f -p 1818看一下結果,1818為當前這個程序的進程號PID,可以看到是:

是postfix這個東西在運行,可能搭建環境的時候不小心給裝了。

postfix是什麼?

postfix是一款運作在Linux環境下免費的郵件伺服器,或稱為MTA(Mail Transfer Agent),其它類似的有Sendmail、Qmail、exim及Zmailer 等。所以Postfix就是一個搭郵件伺服器的。那這玩意肯定是衝突了,我們要透過25埠請求外部的郵件伺服器,而本地用25埠運行了一個郵件伺服器,這個是不行的估計.

嘗試解決問題

我們試試看用我們這個郵件伺服器去寄郵件,而不是用外部伺服器(例如之前用阿里雲企業郵),放了一小段測試程式碼到PHPMailer目錄同級下:

<?php header("content-type:text/html;charset=utf-8"); require &#39;PHPMailer/class.phpmailer.php&#39;; try { $mail = new PHPMailer(true); $mail->IsSMTP();
 $mail->CharSet=&#39;UTF-8&#39;;
 $mail->SMTPAuth = true;
 $mail->Port = 25;
 $mail->Host = &#39;127.0.0.1&#39;;//邮箱smtp地址
 $mail->Username = &#39;gzp@gzpblog.com&#39;;//你的邮箱账号
 $mail->Password = &#39;扒拉扒拉。。。&#39;;//你的邮箱密码
 $mail->From = &#39;gzp@gzpblog.com&#39;;//你的邮箱账号
 $mail->FromName = &#39;锅子&#39;;
 $to = "扒拉扒拉@qq.com";
 $mail->AddAddress($to);
 $mail->Subject = "test";
 $mail->Body = &#39;hello!&#39;;
 $mail->WordWrap = 80;
 $mail->IsHTML(true);
 $mail->Send();
 echo "success!";
 } catch (phpmailerException $e) {
 echo "邮件发送失败:".$e->errorMessage(); 
}

透過25埠的本機伺服器發送郵件,運行這個頁面,發現不行,報錯不能夠驗證,說明這其中還有一些設定要弄,暫時行不通,不往下深究本機伺服器發送了,我們試試看換回:

$mail->Host = ‘smtp.mxhichina.com&#39;; //阿里云的邮箱smtp地址

試試看,還是不行:

沒辦法連接到SMTP。那我們把25埠的postfix伺服器殺掉, 執行kill 1818(目前postfix的PID),再執行一次,還是同樣錯誤,無法連線上。這就奇了怪了,25埠沒有程式運作了,還不行。

可能的原因

查到有可能是因為ipv6的原因,phpMailer在進行smtp伺服器DNS解析時,得到了IP v6位址,然後與IP v6解析到的位址進行連接,導致連接失敗。

我試試看:

ip -6 addr show

#沒東西,那又不是這個問題。

那是什麼原因呢?

解決問題

既然25端口不可用,於是我想,是否可以嘗試一下其它端口,用465端口試試。

465埠(SMTPS):465埠是為SMTPS(SMTP-over-SSL)協定服務開放的,這是SMTP協定基於SSL安全協定之上的變種協議,它繼承了SSL安全協定的非對稱加密的高度安全可靠性,可防止郵件外洩。 SMTPS和SMTP協定一樣,也是用來發送郵件的,只是更安全些,防止郵件被駭客截取洩露,還可實現郵件發送者抗抵賴功能。防止發送者發送之後刪除已發送郵件,拒絕承認發送過這樣一份郵件。

465埠似乎看起來還更好,直接就開始嘗試了,進行以下嘗試,以下為指令:

sbin/iptables -I OUTPUT -p tcp –dport 465 -j ACCEPT  打通465端口

/etc/rc.d/init.d/iptables save 保存

service iptables restart 重启

/etc/init.d/iptables status 查看需要打开的端口是否生效?

似乎可行,现在尝试一下,用SMTP的465SSL连接方式来发送邮件,稍微改了一下测试代码:

<?php header("content-type:text/html;charset=utf-8"); require &#39;PHPMailer/class.phpmailer.php&#39;; try { $mail = new PHPMailer(true); $mail->IsSMTP();
$mail->CharSet=&#39;UTF-8&#39;;
$mail->SMTPAuth = true;
$mail->SMTPSecure = &#39;ssl&#39;;
$mail->Port = 465;
$mail->Host = &#39;smtp.mxhichina.com&#39;;//邮箱smtp地址
$mail->Username = &#39;gzp@gzpblog.com&#39;;//你的邮箱账号
$mail->Password = &#39;扒拉扒拉。。。&#39;;//你的邮箱密码
$mail->From = &#39;gzp@gzpblog.com&#39;;//你的邮箱账号
$mail->FromName = &#39;锅子&#39;;
$to = "扒拉扒拉@qq.com";
$mail->AddAddress($to);
$mail->Subject = "test";
$mail->Body = &#39;hello!&#39;;
$mail->WordWrap = 80;
//$mail->AddAttachment("f:/test.png"); //可以添加附件
$mail->IsHTML(true);
$mail->Send();
echo "success!";
} catch (phpmailerException $e) {
echo "邮件发送失败:".$e->errorMessage(); //测试的时候可以去掉此行的注释
}

执行,成功!右下角弹出了QQ邮件的提醒。

总结

PHPMailer通过465端口进行更安全的SMTPS协议发送邮件

可以修改:

$mail->Port = 465;

为:

$mail->SMTPSecure = 'ssl';
$mail->Port = 465;

即可。

 以上就是Linux服务器下PHPMailer发送邮件失败的问题解决的技巧的内容,更多相关内容请关注PHP中文网(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn