最近一个项目需要用到SMTP发送邮件,之前的库类不存在了,又不喜欢安装pear或者使用pear的net/smtp类,感觉太复杂了。就直接从discuz中抽取出核心稍微修改了下。 从协议分析网上,查找到SMTP协议的命令和应答,SMTP协议在发送SMTP和接收SMTP之间的会话是靠发送SMTP的SMTP命令和接收SMTP反馈的应答来完成的。常用的命令如下: HELLO<domain><CRLF>识别发送方到接收SMTP的一个HELLO命令 MAILFROM:<reverse-path><CRLF><reverse-path>为发送者地址。此命令告诉接收方一个新邮件发送的开始,并对所有的状态和缓冲区进行初始化。此命令开始一个邮件传输处理,最终完成将邮件数据传送到一个或多个邮箱中。 RCPTTO:<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。 比如: telnetsmtp.263.net25 Trying211.150.96.25... Connectedtosmtp.263.net. Escapecharacteris'^]'. 220WelcometocoremailSystem(WithAnti-Spam)2.1for263(040326) HELOweiqiong@cctk.net 250smtp.263.net mailfrom:weiqiong@cctk.net 250Ok rcptto:g2_t1@263.net 250Ok data 354Enddatawith. haha . 250Ok:queuedasB9E452FF3E quit 221Bye Connectionclosedbyforeignhost. 在此基础上就可以写出一个简单的SMTP类了。 <? classstmp{ private$mailcfg=array(); private$error_msg=''; function__construct($mailcfg){ $this->mailcfg=$mailcfg; } publicfunctionsend($mail){ $mailcfg=$this->mailcfg; if(!$fp=fsockopen($mailcfg['server'],$mailcfg['port'],$errno,$errstr,30)){ return$this->error("($mailcfg[server]:$mailcfg[port])CONNECT-UnabletoconnecttotheSMTPserver,pleasecheckyour"mail_config.php"."); } stream_set_blocking($fp,true); $lastmessage=fgets($fp,512); if(substr($lastmessage,3)!='220'){ return$this->error("$mailcfg[server]:$mailcfg[port]CONNECT-$lastmessage"); } fputs($fp,($mailcfg['auth']?'EHLO':'HELO')."".$mailcfg['auth_username']."rn"); $lastmessage=fgets($fp,3)!=220&&substr($lastmessage,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,"AUTHLOGINrn"); $lastmessage=fgets($fp,3)!=334){ return$this->error("($mailcfg[server]:$mailcfg[port])AUTHLOGIN-$lastmessage"); } fputs($fp,base64_encode($mailcfg['auth_username'])."rn"); $lastmessage=fgets($fp,3)!=334){ return$this->error("($mailcfg[server]:$mailcfg[port])USERNAME-$lastmessage"); } fputs($fp,base64_encode($mailcfg['auth_password'])."rn"); $lastmessage=fgets($fp,3)!=235){ return$this->error("($mailcfg[server]:$mailcfg[port])PASSWORD-$lastmessage"); } $email_from=$mailcfg['from']; } fputs($fp,"MAILFROM:<".preg_replace("/.&;(.+?)>./","1",$email_from).">rn"); $lastmessage=fgets($fp,3)!=250){ fputs($fp,3)!=250){ return$this->error("($mailcfg[server]:$mailcfg[port])MAILFROM-$lastmessage"); } } $email_to=$mail['to']; foreach(explode(',',$email_to)as$touser){ $touser=trim($touser); if($touser){ fputs($fp,"RCPTTO:<$touser>rn"); $lastmessage=fgets($fp,512); return$this->error("($mailcfg[server]:$mailcfg[port])RCPTTO-$lastmessage"); } } } fputs($fp,"DATArn"); $lastmessage=fgets($fp,3)!=354){ return$this->error("($mailcfg[server]:$mailcfg[port])DATA-$lastmessage"); } $str="To:$email_tornFrom:$email_fromrnSubject:".$mail['subject']."rnrn".$mail['content']."rn.rn"; fputs($fp,$str); fputs($fp,"QUITrn"); returntrue; } publicfunctionget_error(){ return$this->error_msg; } privatefunctionerror($msg){ $this->error_msg.=$msg; returnfalse; } } ?> 简单的调用例子: <? $mailcfg['server']='smtp.163.com'; $mailcfg['port']='25'; $mailcfg['auth']=1; $mailcfg['from']='testtest@163.com'; $mailcfg['auth_username']='test'; $mailcfg['auth_password']='password'; $stmp=newstmp($mailcfg); $mail=array('to'=>'test@gmail.com','subject'=>'测试标题','content'=>'邮件内容<ahref="http://www.phpobject.net">PHP面向对象'); if(!$stmp->send($mail)){ echo$stmp->geterror(); }else{ echo'mailsucc!'; } ?> 如果发送成功,你就可以去邮箱查看邮件了。^^ (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|