首页 / 网页编程 / PHP / php下使用SMTP发邮件的代码
最近一个项目需要用到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"]."
"); $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
"); $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"])."
"); $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"])."
"); $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).">
"); $lastmessage = fgets($fp, 512); if(substr($lastmessage, 0, 3) != 250) { fputs($fp, "MAIL FROM: <".preg_replace("/.*<(.+?)>.*/", "\1", $email_from).">
"); $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>
"); $lastmessage = fgets($fp, 512); if(substr($lastmessage, 0, 3) != 250) { fputs($fp, "RCPT TO: <$touser>
"); $lastmessage = fgets($fp, 512); return $this->error("($mailcfg[server]:$mailcfg[port]) RCPT TO - $lastmessage"); } } } fputs($fp, "DATA
"); $lastmessage = fgets($fp, 512); if(substr($lastmessage, 0, 3) != 354) { return $this->error("($mailcfg[server]:$mailcfg[port]) DATA - $lastmessage"); } $str="To: $email_to
From: $email_from
Subject: ".$mail["subject"]."
".$mail["content"]."
.
"; fputs($fp, $str); fputs($fp, "QUIT
"); 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!"; } ?> 如果发送成功,你就可以去邮箱查看邮件了。^_^
收藏该网址