本篇文章是介绍关于使用Socket发送邮件,现在分享给大家,有兴趣的朋友可以看一下
之前写过一篇《使用php发送邮件》,方法是利用nette/mail组件发送邮件。
以下内容整理自《PHP核心技术与最佳实践》。
PHP有一个自带的mail()函数,但是要想使用SMTP协议发送邮件,需要安装SMTP服务器。如果不想安装,可以使用Socket发送邮件。SMTP协议建立在TCP协议之上,所以原则上按照SMTP协议的规范,使用Socket跟SMTP服务器进行交互。
SMTP连接与发送过程如下:
1)建立TCP连接。
2)客户端发送HELO命令以标识发件人自己的身份,客户端发送MAIL命令。服务器以OK作为响应,表明准备接收。
3)使用AUTH命令登陆SMTP服务器,输入用户名和密码(注意,用户名和密码都需要base64加密)。
4)客户端发送RCPT命令,标识该电子邮件的计划接收人,可以有多个RCPT行。服务器以OK作为响应,表示愿意为收件人发送邮件。
5)协商结束后,使用DATA命令发送。
6)以”.”号表示结束,输入内容一起发送出去,结束此次发送,用QUIT命令退出。
例如,使用Telnet创建一个SMTP会话,其中S代表服务器,C代表客户端,代码如下:
C: open smtp.qq.com 25S: 220 esmtp4.qq.com Esmtp QQ Mail ServerC: HELO smtp qq.comS: 250 esmtp4.qq.comC: AUTH loginS: 334 VXNlcm5hbWU6C: 这里输入使用base64加密过的用户名S: 334 UGFzc3dvcmQ6C: 这里输入使用base64加密过的密码 S:235 Authentication successfulC: MAIL FROM:S: 250 sender OKC: RCPT TO: S: 250 recipient OKC: DATAS: 354 Enter mail,end with "." on a line by itselfC: This is example from smtp protocolC:.S: 250 message sentC: QUITS: 221 goodbye
本来想用qq邮箱发邮件,但是qq邮箱开启SMTP后页面老是出错,使用163邮箱可以正常发送邮件,邮箱需开启POP3/SMTP服务。
代码:
smtp_mail.php
host=$host; $this->port=$port; $this->user=$user; $this->pwd=$pwd; $this->mail_format=$mail_format; $this->debug=$debug; //连接SMTP服务器
/**
* fsockopen() 初始化一个套接字连接到指定主
* 最后一个参数为timeout,连接时限
*/
$this->sock=fsockopen($this->host,$this->port,$errno,$errstr,10); if (!$this->sock){//连接失败
exit("Error number: $errno, Error message: $errstr\n");
} //取得服务器信息
$response=fgets($this->sock); //若包含220,表示已经成功连接到服务器
if (strstr($response,"220")===false){//首次出现地址|false
exit("Server error: $response\n");
}
} //将命令发送到服务器,然后取得服务器反馈信息,判断命令是否执行成功
private function do_command($cmd,$return_code){
fwrite($this->sock,$cmd); $response=fgets($this->sock); if (strstr($response,"$return_code")===false){ $this->show_debug($response); return false;
} return true;
} //发送邮件
public function send_mail($from,$to,$subject,$content){ //判断收发件邮箱地址是否合法
if (!$this->is_email($from) or !$this->is_email($to)){ $this->show_debug('Please enter valid from/to email.'); return false;
} //判断主题内容是否为空
if (empty($subject) or empty($content)){ $this->show_debug('Please enter subject/content.'); return false;
} //整合邮件信息,发送邮件主体时要以\r\n.\r\n作为结尾
$detail="From:".$from."\r\n"; $detail.="To:".$to."\r\n"; $detail.="Subject:".$subject."\r\n"; if ($this->mail_format==1){ $detail.="Content-Type: text/html;\r\n";
}else{ $detail.="Content-Type: text/plain;\r\n";
} $detail.="charset=utf-8\r\n\r\n"; $detail.=$content; //此处应该有判断命令是否执行成功
$this->do_command("HELO smtp.qq.com\r\n",250); $this->do_command("AUTH LOGIN\r\n",334); $this->do_command("$this->user\r\n",334); $this->do_command("$this->pwd\r\n",235); $this->do_command("MAIL FROM:<".$from.">\r\n",250); $this->do_command("RCPT TO:<".$to.">\r\n",250); $this->do_command("DATA\r\n",354); $this->do_command($detail."\r\n.\r\n",250); $this->do_command("QUIT\r\n",221); return true;
} //判断是否为合法邮箱
private function is_email($emial){ if(filter_var($emial,FILTER_VALIDATE_EMAIL)){ return true;
}else{ return false;
}
} //显示调试信息
private function show_debug($message){ if ($this->debug){
echo "Debug: $message
";
}
}
}index.php
send_mail($from,$to,$subject,$content);
相关推荐:










