|
从协议分析网上,查找到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!';
}
?>
如果发送成功,你就可以去邮箱查看邮件了。^_^
php技术:php下使用SMTP发邮件的代码,转载需保留来源!
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。