php 发邮件 (socket smtp)

php smtp socket 发邮件

用socket发邮件,socket发送邮件是指上就是通过客户端向邮件服务器发送以上的命令,从而实现SMTP协议来达到发送邮件的目的,但是于邮件服务器交互的时候,不是一下子就结束了,是一条指令,一条指令的发,返回的结果如果是正常 比如 220,250,334,才能继续向下

看这个东西都是网上看的别人的资料,收集了一些觉得别人说的不错的,另外还有一个RFC文档,将smtp,和扩展的MIME头,将的是非常的详细了.(虽然很多我都看不懂)
stmp协议介绍 算找到的资料中最详细的了
别人的blog
别人的blog
别人的blog(这位兄弟些了好多blog来介绍的)

一些状态码(不是 http 状态码)

  • 500 格式错误,命令不可识别(此错误也包括命令行过长)
  • 501 参数格式错误
  • 502 命令不可实现
  • 503 错误的命令序列
  • 504 命令参数不可实现
  • 211 系统状态或系统帮助响应
  • 214 帮助信息
  • 220 服务就绪
  • 221 服务关闭传输信道
  • 421 服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应)
  • 250 要求的邮件操作完成
  • 251 用户非本地,将转发向
  • 450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)
  • 550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)
  • 451 放弃要求的操作;处理过程中出错
  • 551 用户非本地,请尝试
  • 452 系统存储不足,要求的操作未执行
  • 552 过量的存储分配,要求的操作未执行
  • 553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误)
  • 354 开始邮件输入,以.结束
  • 554 操作失败
  • 535 用户验证失败
  • 235 用户验证成功
  • 334 等待用户输入验证信息

每次客户端想服务器发一个指令过服务器便会返回相应的相应信息,信息格式为(响应码+空格+解释)
一些常见的相应码为:

简单的过程
  1. 建立TCP 连接。
  2. 客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令;服务器端正希望以OK作为响应,表明准备接收。
  3. 客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行;服务器端则表示是否愿意为收件人接收邮件。
  4. 协商结束,发送邮件,用命令DATA发送。
  5. 以“.”号表示结束输入内容一起发送出去,结束此次发送,用QUIT命令退出。

客户端向邮件服务器发送的 常用指令
HELO hostname 与服务器打招呼并且告知服务器客户端使用的机器名,这里可以随便填写;
AUTH LOGIN:user,pass 邮箱帐号,密码
MAIL FROM:sender 告诉邮件服务器发信人的地址;
RCPT TO:receiver 告诉邮件服务器收信人的地址;
DATA 开始发送邮件内容,并且最后只能含有"."为结尾字符的行结束。
QUIT 传输结束,退出连接;


一个简单的例子 

<?php
	class aMail{
		public static $smtp_prot = 25;
		public static $debug = true;
		public static $crlf  = "\r\n";
		var $smtp_host;
		var $login_name;
		var $password;
		var $form;
		var $to;
		var $err;
		var $message;
		var $socket;
		function __construct($options=""){
			if($options == "" || !is_array($options)){
				return false;
			}
			foreach($options as $key=>$val){
				$this->$key = $val;
			}
		}

		function sendMail(){						 
			$this->socket = fsockopen($this->smtp_host,self::$smtp_prot);
			$socket = $this->socket;
			$crlf   = self::$crlf;
			stream_set_blocking($socket,true);
			$this->message = fgets($socket,512);	
			echo $this->message;
			if(!$this->print_messsage("/^220/","connect fail")){
				return false;
			}

			fputs($socket,"EHLO 127.0.0.1 ".$crlf);
			$this->message = fgets($socket, 512);				
			if(!$this->print_messsage("/^2/","EHLO fail")){
				return false;
			}
			
			fputs($socket,"AUTH LOGIN".$crlf);
			$this->message = fgets($socket, 512);				
			$this->print_messsage("/^2/","AUTH LOGIN fail");
			
			fputs($socket,base64_encode($this->login_name).$crlf);
			$this->message = fgets($socket, 512);				
			$this->print_messsage("/^2/","login_name fail");
			
			fputs($socket,base64_encode($this->password).$crlf);
			$this->message = fgets($socket, 512);				
			$this->print_messsage("/^2/","password fail");			

			fputs($socket,"MAIL FROM: <".$this->from.">".$crlf);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^2/","from fail");

			fputs($socket,"RCPT TO: <".$this->to.">".$crlf);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^334|^2/","to fail");
			
			fputs($socket,"DATA".$crlf);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^334|^2/","DATA fail");			

			$html = implode("",array(
						"To: ".$this->to.$crlf,
						"From: ".$this->from.$crlf,
						"Subject: ".$this->subject.$crlf.$crlf,
						$this->content.$crlf.".".$crlf,
					));

			fputs($socket,$html);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^2/","html fail");
			
			fputs($socket, "QUIT".$crlf);
			$this->message=fgets($socket,512);
			$this->print_messsage("/^2/","QUIT fail");
		}
		function print_messsage($reg="",$err=""){
			$message = $this->message;
			if(preg_match($reg,$message)<=0){
				$this->err = $err."___".$message."--------------";
				echo $err."___".$message."--------------<br>";
				return false;
			}
			if(self::$debug){
				echo $this->message."<br>";
			}
			return true;
		}
	}
	$mail_options = array(
					"smtp_host"=>"smtp.sina.com.cn",
					"login_name"=>"ycwtt0527",
					"password"=>"XXXXX",//填写真实的密码的密码
					"from"=>"ycwtt0527@sina.com",
					"to"=>"ycwtt0527@sina.com",
					"subject"=>"hengheng",
					"content"=>"<div style='color:#f00'>asfsadfasdf</div><span>haha</span>",

				);
	
	$x = new aMail($mail_options);
	$x->sendMail();
?>

运行上面  在页面上会打印

220 irja2-171.sinamail.sina.com.cn ESMTP 220 irja2-171.sinamail.sina.com.cn ESMTP
250-irja2-171.sinamail.sina.com.cn
250-8BITMIME
250-SIZE 73400320
250-AUTH PLAIN LOGIN
250 AUTH=PLAIN LOGIN
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 #2.0.0 OK Authenticated
250 sender ok


看到sender ok  算是发送成功了, 但是对方是否能收的到就不一定了........


发送的内容是<div style='color:#f00'>asfsadfasdf</div><span>haha</span>

发现在收邮件的时候这个标签被转义了,(如果发的是图片,我试了几次都收不到)

这是就要靠MIME扩展来解决这个问题了


大概看了2天相关的内容,结果完全晕了....

MIME的扩展 真心看不大懂   然后看了下phpmailer  就更晕了  光 content-type就有8bit ,7bit ,text/plain,iso-8859-1,base64

然后发邮件又有个中参数  附件 图片 多媒体   等等  n多分枝(因为要根据设置了不同的参数来设置MIME头,在phpmailer里面有create_header,create_body 2个方法,对这边有比较多的判断,我是没兴趣看了)

想看  MIME部分 还是 去看 RFC文档  配合 phpmailer一起看可能效果好点

算了  放弃了     用phpmailer 发了封简单的邮件

看  怎么拼简单的html邮件

如下

To: ycwtt0527@sina.com
From: <ycwtt0527@sina.com>
Subject: hengheng<br>
Return-Path: ycwtt0527@sina.com
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/html; charset = "iso-8859-1"

<div>asdasdasdasdasdasd</div>


<?php
//RFC文档
	class aMail{
		public static $smtp_prot = 25;
		public static $debug = true;
		public static $crlf  = "\r\n";
		var $smtp_host;
		var $login_name;
		var $password;
		var $form;
		var $to;
		var $err;
		var $message;
		var $socket;
		public function __construct($options=""){
			if($options == "" || !is_array($options)){
				return false;
			}
			foreach($options as $key=>$val){
				$this->$key = $val;
			}
		}

		public function sendMail(){						 
			$this->socket = fsockopen($this->smtp_host,self::$smtp_prot);
			$socket = $this->socket;
			$crlf   = self::$crlf;
			stream_set_blocking($socket,true);
			$this->message = fgets($socket,512);	
			echo $this->message;
			if(!$this->print_messsage("/^220/","connect fail")){
				return false;
			}

			fputs($socket,"EHLO 127.0.0.1 ".$crlf);
			$this->message = fgets($socket, 512);				
			if(!$this->print_messsage("/^2/","EHLO fail")){
				return false;
			}
			
			fputs($socket,"AUTH LOGIN".$crlf);
			$this->message = fgets($socket, 512);				
			$this->print_messsage("/^2/","AUTH LOGIN fail");
			
			fputs($socket,base64_encode($this->login_name).$crlf);
			$this->message = fgets($socket, 512);				
			$this->print_messsage("/^2/","login_name fail");
			
			fputs($socket,base64_encode($this->password).$crlf);
			$this->message = fgets($socket, 512);				
			$this->print_messsage("/^2/","password fail");			

			fputs($socket,"MAIL FROM: <".$this->from.">".$crlf);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^2/","from fail");

			fputs($socket,"RCPT TO: <".$this->to.">".$crlf);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^334|^2/","to fail");
			
			fputs($socket,"DATA".$crlf);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^334|^2/","DATA fail");			
	
			$content = $this->setHtmlBody();		
			
			fputs($socket,$content);
			$this->message = fgets($socket, 512);
			$this->print_messsage("/^2/","html fail");
			
			fputs($socket, "QUIT".$crlf);
			$this->message=fgets($socket,512);
			$this->print_messsage("/^2/","QUIT fail");
		}
		public function print_messsage($reg="",$err=""){
			$message = $this->message;
			if(preg_match($reg,$message)<=0){
				$this->err = $err."___".$message."--------------";
				echo $err."___".$message."--------------<br>";
				return false;
			}
			if(self::$debug){
				echo $this->message."<br>";
			}
			return true;
		}
		public function setHtmlBody(){
			$content = $this->content;
			$crlf = self::$crlf;			
			$header = array();

			$uniq_id = md5(uniqid(time()));
        	$boundary1 = "b1_" . $uniq_id;
        	$boundary2 = "b2_" . $uniq_id;			
			
			$header[] = "To: ".$this->to.$crlf;
			$header[] = "From: <".$this->from.">".$crlf;
			$header[] = "Subject: ".$this->subject.$crlf;
			$header[] = "Return-Path: ".$this->from.$crlf;
			$header[] = "MIME-Version: 1.0".$crlf;
			$header[] = "Content-Transfer-Encoding: 8bit".$crlf;
			$header[] = "Content-Type: text/html; charset = \"iso-8859-1\"".$crlf.$crlf;
			$content = str_replace("\r\n", "\n", $content);
			$content = str_replace("\r", "\n", $content);
			$content = str_replace("\n", $crlf, $content);
			$header[] = $content.$crlf.$crlf;
			$str  = join("", $header);
			$str.= $crlf.".".$crlf;
			return $str;
		}
	}
	$mail_options = array(
					"smtp_host"=>"smtp.sina.com.cn",
					"login_name"=>"ycwtt0527",
					"password"=>"xxxxx",//填写密码的
					"from"=>"ycwtt0527@sina.com",
					"to"=>"ycwtt0527@sina.com",
					"subject"=>"hengheng",
					"content"=>'<font size="7"><b>hello,world</b></font><br><font size="2">sdfsadasdf</font><br>',
				);
	
	$x = new aMail($mail_options);
	$x->sendMail();
	
?>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值