<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fwolf's Blog &#187; smtp - Fwolf's Blog</title>
	<atom:link href="http://www.fwolf.com/blog/post/tag/smtp/feed" rel="self" type="application/rss+xml" />
	<link>http://www.fwolf.com/blog</link>
	<description>随心·随意·随缘·努力～</description>
	<lastBuildDate>Wed, 07 Jul 2010 07:07:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>终于能够通过phpmailer使用gmail账号发送邮件了</title>
		<link>http://www.fwolf.com/blog/post/155</link>
		<comments>http://www.fwolf.com/blog/post/155#comments</comments>
		<pubDate>Fri, 14 Apr 2006 08:25:16 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[phpmailer]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/post/155</guid>
		<description><![CDATA[phpmailer（现在的版本是1.73）是一个很好用的工具，可以很方便的使用php语言发送邮件，支持smtp及验证，我们一直都用它。 但是，由于gmail的smtp采用了ssl连接： Outgoing Mail (SMTP) Server &#8211; 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(&#8216;ssl://&#8217; . $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 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://sourceforge.net/projects/phpmailer">phpmailer</a>（现在的版本是1.73）是一个很好用的工具，可以很方便的使用php语言发送邮件，支持smtp及验证，我们一直都用它。</p>

<p>但是，由于gmail的smtp采用了ssl连接：</p>

<div class="code">
Outgoing Mail (SMTP) Server &#8211; requires TLS: smtp.gmail.com (use authentication)
Use Authentication: Yes
Use STARTTLS: Yes (some clients call this SSL)
Port: 465 or 587  
</div>

<p>使用phpmailer就无法正常连接gmail的发信服务器了，并且这个问题一直没有得到phpmailer的官方解决，不过在<a href="http://sourceforge.net/forum/forum.php?thread_id=1222165&#038;forum_id=81620">sf.net上面的讨论</a>里倒是找到了一点资料，采用下面这种方法就可以连接gmail了。</p>

<p>修改class.smtp.php，第101行，把</p>

<div class="code">
        $this->smtp_conn = fsockopen($host,    # the host of the server
</div>

<p>改成</p>

<div class="code">
        $this->smtp_conn = fsockopen(&#8216;ssl://&#8217; . $host,    # the host of the server
</div>

<p>这样就可以了，就是指定使用ssl协议连接主机，当然php的openssl模块必须打开：</p>

<div class="code">
extension=php_openssl.dll
</div>

<p>但是这样就不能使用非ssl的主机了，我也不像在include目录下面放两份phpmailer，于是，又琢磨出了一种更好的方式：</p>

<p>打开class.phpmailer.php，在大概543行附近，函数SmtpConnect()中，找到：</p>

<div class="code">
        $this->smtp->do_debug = $this->SMTPDebug;
        $hosts = explode(&#8220;;&#8221;, $this->Host);
        $index = 0;
        $connection = ($this->smtp->Connected()); 

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

<p>这一段的部分功能就是，如果你输入的主机名中带有端口号，自动的识别出来，设想虽好，但就是这部分让我们无法直接在调用的时候使用ssl格式的主机名，因为“ssl://xxx”的形式会被误认为是主机：端口号的形式，另外端口号一般都比较固定，我们手工设置好了，也不必一定要和主机一起赋值，所以在上面的代码后面添加：</p>

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

<p>就可以了，使用正常smtp主机的时候，用法不变，使用gmail的时候，使用ssl://smtp.gmail.com作为主机名就可以了，唯一稍微麻烦一些的就是端口需要手工指定——其实也不麻烦。</p>

<p>按照上面的配置更改后，使用gmail账号发送邮件时还会有一条警告信息：</p>

<div class="code">
Warning: fgets(): SSL: fatal protocol error in H:\php_includes\phpmailer_ssl\cla
ss.smtp.php on line 1024
</div>

<p>这各警告信息在<a href="http://www.php.net/manual/en/function.fopen.php">php的帮助</a>里面有，好像是在使用ssl连接的时候，读文件读到文件尾的时候出现的问题，需要手工屏蔽，或者人为控制读的长度，我们用最简单的方式禁止警告信息显示就可以了，找到class.smtp.php的1024行，在fgets($this->smtp_conn,515)函数前面加上个@就可以了。</p>

<p>下面是一个完整的使用phpmailer发送邮件的函数：</p>

<div class="code">
function send_mail($to_address, $to_name ,$subject, $body, $attach = &#8221;)
{
    //使用phpmailer发送邮件
    require_once(&#8220;phpmailer/class.phpmailer.php&#8221;);
    $mail = new PHPMailer();
    $mail-&gt;IsSMTP();                                      // set mailer to use SMTP
    $mail-&gt;CharSet = &#8216;utf-8&#8242;;
    $mail-&gt;Encoding = &#8216;base64&#8242;;
    $mail-&gt;From = &#8216;fwolf.mailagent@gmail.com&#8217;;
    $mail-&gt;FromName = &#8216;Fwolf&#8217;;
    //$mail-&gt;Sender = &#8216;fwolf.mailagent@gmail.com&#8217;;
    //$mail-&gt;ConfirmReadingTo = &#8216;fwolf.mailagent@gmail.com&#8217;;     //回执？
    
    $mail-&gt;Host = &#8216;ssl://smtp.gmail.com&#8217;;
    $mail-&gt;Port = 465;       //default is 25, gmail is 465 or 587
    $mail-&gt;SMTPAuth = true;
    $mail-&gt;Username = &#8220;fwolf.mailagent@gmail.com&#8221;;
    $mail-&gt;Password = &#8220;xxx&#8221;;
    
    $mail->&gt;ddAddress($to_address, $to_name);
    //$mail-&gt;AddReplyTo(&#8216;fwolf.mailagent@gmail.com&#8217;, &#8220;Fwolf&#8221;);   //针对gmail无用，gmail是In-Reply-To:，phpmailer默认生成的是Reply-to:
    $mail-&gt;WordWrap = 50;
    if (!empty($attach))
        $mail-&gt;AddAttachment($attach);
    $mail-&gt;IsHTML(false);
    $mail-&gt;Subject = $subject;
    $mail-&gt;Body    = $body;
    //$mail-&gt;AltBody = &#8220;This is the body in plain text for non-HTML mail clients&#8221;;

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

<h4>update @ 2006-11-3</h4>

<p>感谢RainChen提供的fgets出错提示的更好解决办法（位置大概在class.smtp.php的1024行）：
将：</p>

<div class="code">fgets($this-&gt;smtp_conn,515)</div>

<p>改为：</p>

<div class="code">!feof($this-&gt;smtp_conn) &#038;&#038; $str = fgets($this-&gt;smtp_conn,515)</div>

<p>这样的代码就规范多了，极力不提倡使用@来屏蔽错误信息。
（未测试， 但有网友反映这种改法是不行的）</p>

<h4>Update @ 2008-04-14</h4>

<p>试了最新的phpMailer 2.1.0 Beta 2，不用作任何修改，就可以用gmail账号发送邮件了，<a href="http://phpmailer.codeworxtech.com/changelog.html">官方文档</a>中还给出了例子，和我用的方法不太一样。</p>

<p>不过<a href="176">中文附件的问题</a>依然没有解决，需要自己hack。</p>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/gmail" title="gmail" rel="tag">gmail</a>, <a href="http://www.fwolf.com/blog/post/tag/mail" title="mail" rel="tag">mail</a>, <a href="http://www.fwolf.com/blog/post/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.fwolf.com/blog/post/tag/phpmailer" title="phpmailer" rel="tag">phpmailer</a>, <a href="http://www.fwolf.com/blog/post/tag/smtp" title="smtp" rel="tag">smtp</a>, <a href="http://www.fwolf.com/blog/post/tag/ssl" title="ssl" rel="tag">ssl</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/176" title="让phpmailer支持中文名称的附件 (2006-05-23)">让phpmailer支持中文名称的附件</a> (5)</li>
	<li><a href="http://www.fwolf.com/blog/post/379" title="[Mutt]用msmtp替代esmtp作发信代理 (2008-01-12)">[Mutt]用msmtp替代esmtp作发信代理</a> (2)</li>
	<li><a href="http://www.fwolf.com/blog/post/451" title="Apple Mail 邮件太多不下载问题的解决 (2010-06-29)">Apple Mail 邮件太多不下载问题的解决</a> (0)</li>
	<li><a href="http://www.fwolf.com/blog/post/300" title="针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS） (2007-03-18)">针对$_SERVER['PHP_SELF']的跨站脚本攻击（XSS）</a> (3)</li>
	<li><a href="http://www.fwolf.com/blog/post/443" title="配置安全的共享web服务器（抛砖引玉） (2009-06-09)">配置安全的共享web服务器（抛砖引玉）</a> (4)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/155/feed</wfw:commentRss>
		<slash:comments>50</slash:comments>
		</item>
	</channel>
</rss>
