最近一个项目需要用到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
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: .*/", "\\1", $email_from).">\r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 250) {
fputs($fp, "MAIL FROM: .*/", "\\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: \r\n");
$lastmessage = fgets($fp, 512);
if(substr($lastmessage, 0, 3) != 250) {
fputs($fp, "RCPT TO: \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
$mailcfg['auth_username'] = 'test';
$mailcfg['auth_password'] = 'password';
$stmp=new stmp($mailcfg);
$mail=array('to'=>'test@gmail.com','subject'=>'测试标题','content'=>'邮件内容PHP面向对象');
if(!$stmp->send($mail)){
echo $stmp->get_error();
}else{
echo 'mail succ!';
}
?>
如果发送成功,你就可以去邮箱查看邮件了。^_^

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.