【資料來源:http://www.fwolf.com/blog/post/155 】
【轉載原文如下】
授權方式:署名,非商業用途,保持一致,轉載時請務必以超鏈接(http://www.fwolf.com/blog/post/155)的形式標明文章原始出處和作者信息及本聲明。

phpmailer(現在的版本是1.73)是一個很好用的工具,可以很方便的使用php語言發送郵件,支持smtp及驗證,我們一直都用它。

但是,由於gmail的smtp採用了ssl連接:

Outgoing Mail (SMTP) Server - requires TLS: smtp.gmail.com (use authentication)
Use Authentication: Yes
Use STARTTLS: Yes (some clients call this SSL)
Port: 465 or 587

使用phpmailer就無法正常連接gmail的發信服務器了,並且這個問題一直沒有得到phpmailer的官方解決,不過在sf.net上面的討論裡倒是找到了一點資料,採用下面這種方法就可以連接gmail了。

修改class.smtp.php,第101行,把

$this->smtp_conn = fsockopen($host, # the host of the server

改成

$this->smtp_conn = fsockopen(』ssl://』 . $host, # the host of the server

這樣就可以了,就是指定使用ssl協議連接主機,當然php的openssl模塊必須打開:

extension=php_openssl.dll

但是這樣就不能使用非ssl的主機了,我也不像在include目錄下面放兩份phpmailer,於是,又琢磨出了一種更好的方式:

打開class.phpmailer.php,在大概543行附近,函數SmtpConnect()中,找到:

$this->smtp->do_debug = $this->SMTPDebug;
$hosts = explode(」;」, $this->Host);
$index = 0;
$connection = ($this->smtp->Connected());

// Retry while there is no connection
while($index < count($hosts) && $connection == false)
{
if(strstr($hosts[$index], ":"))
list($host, $port) = explode(":", $hosts[$index]);
else
{
$host = $hosts[$index];
$port = $this->Port;
}

這一段的部分功能就是,如果你輸入的主機名中帶有端口號,自動的識別出來,設想雖好,但就是這部分讓我們無法直接在調用的時候使用ssl格式的主機名,因為「ssl://xxx」的形式會被誤認為是主機:端口號的形式,另外端口號一般都比較固定,我們手工設置好了,也不必一定要和主機一起賦值,所以在上面的代碼後面添加:

//Modify by Fwolf @ 2006-4-14, to enable ssl mail connection
$host = $this->Host;
$port = $this->Port;

就可以了,使用正常smtp主機的時候,用法不變,使用gmail的時候,使用ssl://smtp.gmail.com作為主機名就可以了,唯一稍微麻煩一些的就是端口需要手工指定——其實也不麻煩。

按照上面的配置更改後,使用gmail賬號發送郵件時還會有一條警告信息:

Warning: fgets(): SSL: fatal protocol error in H:\php_includes\phpmailer_ssl\cla
ss.smtp.php on line 1024

這各警告信息在php的幫助裡面有,好像是在使用ssl連接的時候,讀文件讀到文件尾的時候出現的問題,需要手工屏蔽,或者人為控制讀的長度,我們用最簡單的方式禁止警告信息顯示就可以了,找到class.smtp.php的1024行,在fgets($this->smtp_conn,515)函數前面加上個@就可以了。

下面是一個完整的使用phpmailer發送郵件的函數:

function send_mail($to_address, $to_name ,$subject, $body, $attach = 」)
{
//使用phpmailer發送郵件
require_once(」phpmailer/class.phpmailer.php」);
$mail = new PHPMailer();
$mail->IsSMTP(); // set mailer to use SMTP
$mail->CharSet = 『utf-8′;
$mail->Encoding = 『base64′;
$mail->From = 『fwolf.mailagent@gmail.com』;
$mail->FromName = 『Fwolf』;
//$mail->Sender = 『fwolf.mailagent@gmail.com』;
//$mail->ConfirmReadingTo = 『fwolf.mailagent@gmail.com』; //回執?

$mail->Host = 』ssl://smtp.gmail.com』;
$mail->Port = 465; //default is 25, gmail is 465 or 587
$mail->SMTPAuth = true;
$mail->Username = 「fwolf.mailagent@gmail.com」;
$mail->Password = 「xxx」;

$mail->>ddAddress($to_address, $to_name);
//$mail->AddReplyTo(』fwolf.mailagent@gmail.com』, 「Fwolf」); //針對gmail無用,gmail是In-Reply-To:,phpmailer默認生成的是Reply-to:
$mail->WordWrap = 50;
if (!empty($attach))
$mail->AddAttachment($attach);
$mail->IsHTML(false);
$mail->Subject = $subject;
$mail->Body = $body;
//$mail->AltBody = 「This is the body in plain text for non-HTML mail clients」;

if(!$mail->Send())
{
echo 「Mail send failed.\r\n」;
echo 「Error message: 」 . $mail->ErrorInfo . 「\r\n」;
return false;
}
else
{
echo(」Send $attach to $to_name <$to_address> successed.\r\n」);
return true;
}
//echo 「Message has been sent」;
//
}

update @ 2006-11-3
感謝RainChen提供的fgets出錯提示的更好解決辦法(位置大概在class.smtp.php的1024行):
將:

fgets($this->smtp_conn,515)

改為:

!feof($this->smtp_conn) && $str = fgets($this->smtp_conn,515)

這樣的代碼就規範多了,極力不提倡使用@來屏蔽錯誤信息。
(未測試, 但有網友反映這種改法是不行的

arrow
arrow
    全站熱搜

    yoonow 發表在 痞客邦 留言(0) 人氣()