欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

php下使用SMTP发邮件的代码

程序员文章站 2022-05-25 23:13:52
最近一个项目需要用到smtp发送邮件,之前的库类不存在了,又不喜欢安装pear或者使用pear的net/smtp类,感觉太复杂了。就直接从discuz中抽取出核心稍微修改了...
最近一个项目需要用到smtp发送邮件,之前的库类不存在了,又不喜欢安装pear或者使用pear的net/smtp类,感觉太复杂了。就直接从discuz中抽取出核心稍微修改了下。
   从协议分析网上,查找到smtp协议的命令和应答,smtp协议在发送smtp和接收smtp之间的会话是靠发送smtp的smtp命令和接收smtp反馈的应答来完成的。常用的命令如下:
   hello<domain><crlf>识别发送方到接收smtp的一个hello命令
   mail from:<reverse-path><crlf><reverse-path>为发送者地址。此命令告诉接收方一个新邮件发送的开始,并对所有的状态和缓冲区进行初始化。此命令开始一个邮件传输处理,最终完成将邮件数据传送到一个或多个邮箱中。
   rcpt to:<forward-path><crlf><forward-path>标识各个邮件接收者的地址  
   data<crlf>
       接收smtp将把其后的行为看作邮件数据去处理,以<crlf>.<crlf>标识数据的结尾。
   rest<crlf>退出/复位当前的邮件传输
   noop<crlf>要求接收smtp仅做ok应答。(用于测试)
   quit<crlf>要求接收smtp返回一个ok应答并关闭传输。
   vrfy<string><crlf>验证指定的邮箱是否存在,由于安全因素,服务器多禁止此命令。
   expn<string><crlf>验证给定的邮箱列表是否存在,扩充邮箱列表,也常禁止使用。
   help<crlf>查询服务器支持什么命令

   注:<crlf>为回车、换行,ascii码分别为13、10(十进制)。

   另外,可以在command下,使用telnet来进行简单的手工使用smtp。
  比如:


telnet smtp.263.net 25 
trying 211.150.96.25... 
connected to smtp.263.net. 
escape character is '^]'. 
220 welcome to coremail system(with anti-spam) 2.1 for 263(040326) 
helo weiqiong@cctk.net 
250 smtp.263.net 
mail from:weiqiong@cctk.net 
250 ok 
rcpt to:g2_t1@263.net 
250 ok 
data 
354 end data with <cr><lf>.<cr><lf> 
haha 

250 ok: queued as b9e452ff3e 
quit 
221 bye 
connection closed by foreign host. 



   在此基础上就可以写出一个简单的smtp类了。

<? 
class stmp{ 

    private $mailcfg=array(); 
    private $error_msg=''; 

    function __construct($mailcfg){ 

        $this->mailcfg=$mailcfg; 

    } 

    public function send($mail){ 
        $mailcfg=$this->mailcfg; 
        if(!$fp = fsockopen($mailcfg['server'], $mailcfg['port'], $errno, $errstr, 30)) { 
            return $this->error("($mailcfg[server]:$mailcfg[port]) connect - unable to connect to the smtp server, please check your \"mail_config.php\"."); 
        } 
         stream_set_blocking($fp, true); 
         $lastmessage = fgets($fp, 512); 
        if(substr($lastmessage, 0, 3) != '220') { 
            return $this->error("$mailcfg[server]:$mailcfg[port] connect - $lastmessage"); 
        } 
        fputs($fp, ($mailcfg['auth'] ? 'ehlo' : 'helo')." ".$mailcfg['auth_username']."\r\n"); 
        $lastmessage = fgets($fp, 512); 
        if(substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250) { 
            return $this->error("($mailcfg[server]:$mailcfg[port]) helo/ehlo - $lastmessage"); 
        } 
        while(1) { 
            if(substr($lastmessage, 3, 1) != '-' || empty($lastmessage)) { 
                 break; 
             } 
             $lastmessage = fgets($fp, 512); 
        } 
        if($mailcfg['auth']) { 
            fputs($fp, "auth login\r\n"); 
            $lastmessage = fgets($fp, 512); 
            if(substr($lastmessage, 0, 3) != 334) { 
                return $this->error("($mailcfg[server]:$mailcfg[port]) auth login - $lastmessage"); 
            } 
            fputs($fp, base64_encode($mailcfg['auth_username'])."\r\n"); 
            $lastmessage = fgets($fp, 512); 
            if(substr($lastmessage, 0, 3) != 334) { 
                return $this->error("($mailcfg[server]:$mailcfg[port]) username - $lastmessage"); 
            } 

            fputs($fp, base64_encode($mailcfg['auth_password'])."\r\n"); 
            $lastmessage = fgets($fp, 512); 
            if(substr($lastmessage, 0, 3) != 235) { 
                return $this->error("($mailcfg[server]:$mailcfg[port]) password - $lastmessage"); 
            } 

            $email_from = $mailcfg['from']; 
        } 
        fputs($fp, "mail from: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n"); 
        $lastmessage = fgets($fp, 512); 
        if(substr($lastmessage, 0, 3) != 250) { 
            fputs($fp, "mail from: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n"); 
            $lastmessage = fgets($fp, 512); 
            if(substr($lastmessage, 0, 3) != 250) { 
                return $this->error("($mailcfg[server]:$mailcfg[port]) mail from - $lastmessage"); 
            } 
        } 

        $email_to=$mail['to']; 
        foreach(explode(',', $email_to) as $touser) { 
            $touser = trim($touser); 
            if($touser) { 
                fputs($fp, "rcpt to: <$touser>\r\n"); 
                $lastmessage = fgets($fp, 512); 
                if(substr($lastmessage, 0, 3) != 250) { 
                    fputs($fp, "rcpt to: <$touser>\r\n"); 
                    $lastmessage = fgets($fp, 512); 
                    return $this->error("($mailcfg[server]:$mailcfg[port]) rcpt to - $lastmessage"); 
                } 
            } 
        } 
        fputs($fp, "data\r\n"); 
        $lastmessage = fgets($fp, 512); 
        if(substr($lastmessage, 0, 3) != 354) { 
            return $this->error("($mailcfg[server]:$mailcfg[port]) data - $lastmessage"); 
        } 
        $str="to: $email_to\r\nfrom: $email_from\r\nsubject: ".$mail['subject']."\r\n\r\n".$mail['content']."\r\n.\r\n"; 
        fputs($fp, $str); 
        fputs($fp, "quit\r\n"); 
        return true; 
    } 

    public function get_error(){ 
        return $this->error_msg; 
    } 

    private function error($msg){ 
        $this->error_msg.=$msg; 
        return false; 
    } 


?> 

    简单的调用例子:

<? 
$mailcfg['server'] = 'smtp.163.com'; 

        $mailcfg['port'] = '25'; 

        $mailcfg['auth'] = 1; 
        $mailcfg['from'] = 'test <test@163.com>'; 

        $mailcfg['auth_username'] = 'test'; 

        $mailcfg['auth_password'] = 'password';     
        $stmp=new stmp($mailcfg); 
        $mail=array('to'=>'test@gmail.com','subject'=>'测试标题','content'=>'邮件内容<a href="http://www.phpobject.net">php面向对象</a>'); 
        if(!$stmp->send($mail)){ 
            echo $stmp->get_error(); 
        }else{ 
            echo 'mail succ!'; 
        } 
?> 

  如果发送成功,你就可以去邮箱查看邮件了。^_^