php 发邮件的2种方式(使用stmp类、使用socket协议)
方式1:使用stmp类发送邮件
代码:
stmp.php
- 1 <?php
- 2 header("Content-Type: text/html; charset=utf-8");
- 3
- 4 class smtp
- 5 {
- 6 /* Public Variables */
- 7 var $smtp_port;
- 8 var $time_out;
- 9 var $host_name;
- 10 var $log_file;
- 11 var $relay_host;
- 12 var $debug;
- 13 var $auth;
- 14 var $user;
- 15 var $pass;
- 16
- 17 /* Private Variables */
- 18 var $sock;
- 19
- 20 /* Constractor */
- 21 function smtp($relay_host = "", $smtp_port = 25,$auth = false,$user,$pass)
- 22 {
- 23 $this->debug = FALSE;
- 24 $this->smtp_port = $smtp_port;
- 25 $this->relay_host = $relay_host;
- 26 $this->time_out = 30; //is used in fsockopen()
- 27 $this->auth = $auth;//auth
- 28 $this->user = $user;
- 29 $this->pass = $pass;
- 30 $this->host_name = "localhost"; //is used in HELO command
- 31 $this->log_file = "";
- 32 $this->sock = FALSE;
- 33 }
- 34
- 35 /* Main Function */
- 36 function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "")
- 37 {
- 38 $mail_from = $this->get_address($this->strip_comment($from));
- 39 $body = preg_replace("/(^|(\r\n))(\.)/", "\1.\3", $body);
- 40 $header = "MIME-Version:1.0\r\n";
- 41 if($mailtype=="HTML")
- 42 {
- 43 $header .= "Content-Type:text/html\r\n";
- 44 }
- 45 $header .= "To: ".$to."\r\n";
- 46 if ($cc != "")
- 47 {
- 48 $header .= "Cc: ".$cc."\r\n";
- 49 }
- 50 $header .= "From: $from<".$from.">\r\n";
- 51 $header .= "Subject: ".$subject."\r\n";
- 52 $header .= $additional_headers;
- 53 $header .= "Date: ".date("r")."\r\n";
- 54 $header .= "X-Mailer:By Redhat (PHP/".phpversion().")\r\n";
- 55 list($msec, $sec) = explode(" ", microtime());
- 56 $header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">\r\n";
- 57 $TO = explode(",", $this->strip_comment($to));
- 58
- 59 if ($cc != "")
- 60 {
- 61 $TO = array_merge($TO, explode(",", $this->strip_comment($cc)));
- 62 }
- 63 if ($bcc != "")
- 64 {
- 65 $TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));
- 66 }
- 67 $sent = TRUE;
- 68 foreach ($TO as $rcpt_to)
- 69 {
- 70 $rcpt_to = $this->get_address($rcpt_to);
- 71 if (!$this->smtp_sockopen($rcpt_to))
- 72 {
- 73 $this->log_write("Error: Cannot send email to ".$rcpt_to."\n");
- 74 $sent = FALSE;
- 75 continue;
- 76 }
- 77 if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body))
- 78 {
- 79 $this->log_write("E-mail has been sent to <".$rcpt_to.">\n");
- 80 }
- 81 else
- 82 {
- 83 $this->log_write("Error: Cannot send email to <".$rcpt_to.">\n");
- 84 $sent = FALSE;
- 85 }
- 86 fclose($this->sock);
- 87 $this->log_write("Disconnected from remote host\n");
- 88 }
- 89 return $sent;
- 90 }
- 91
- 92 /* Private Functions */
- 93 function smtp_send($helo, $from, $to, $header, $body = "")
- 94 {
- 95 if (!$this->smtp_putcmd("HELO", $helo))
- 96 {
- 97 return $this->smtp_error("sending HELO command");
- 98 }
- 99
- 100 #auth
- 101 if($this->auth)
- 102 {
- 103 if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user)))
- 104 {
- 105 return $this->smtp_error("sending HELO command");
- 106 }
- 107 if (!$this->smtp_putcmd("", base64_encode($this->pass)))
- 108 {
- 109 return $this->smtp_error("sending HELO command");
- 110 }
- 111 }
- 112 if (!$this->smtp_putcmd("MAIL", "FROM:<".$from.">"))
- 113 {
- 114 return $this->smtp_error("sending MAIL FROM command");
- 115 }
- 116 if (!$this->smtp_putcmd("RCPT", "TO:<".$to.">"))
- 117 {
- 118 return $this->smtp_error("sending RCPT TO command");
- 119 }
- 120 if (!$this->smtp_putcmd("DATA"))
- 121 {
- 122 return $this->smtp_error("sending DATA command");
- 123 }
- 124 if (!$this->smtp_message($header, $body))
- 125 {
- 126 return $this->smtp_error("sending message");
- 127 }
- 128 if (!$this->smtp_eom())
- 129 {
- 130 return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]");
- 131 }
- 132 if (!$this->smtp_putcmd("QUIT"))
- 133 {
- 134 return $this->smtp_error("sending QUIT command");
- 135 }
- 136 return TRUE;
- 137 }
- 138
- 139 function smtp_sockopen($address)
- 140 {
- 141 if ($this->relay_host == "")
- 142 {
- 143 return $this->smtp_sockopen_mx($address);
- 144 }
- 145 else
- 146 {
- 147 return $this->smtp_sockopen_relay();
- 148 }
- 149 }
- 150
- 151 function smtp_sockopen_relay()
- 152 {
- 153 $this->log_write("Trying to ".$this->relay_host.":".$this->smtp_port."\n");
- 154 $this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out);
- 155 if (!($this->sock && $this->smtp_ok()))
- 156 {
- 157 $this->log_write("Error: Cannot connenct to relay host ".$this->relay_host."\n");
- 158 $this->log_write("Error: ".$errstr." (".$errno.")\n");
- 159 return FALSE;
- 160 }
- 161 $this->log_write("Connected to relay host ".$this->relay_host."\n");
- 162 return TRUE;;
- 163 }
- 164
- 165 function smtp_sockopen_mx($address)
- 166 {
- 167 $domain = preg_replace("^.+@([^@]+)$", "\1", $address);
- 168 if (!@getmxrr($domain, $MXHOSTS))
- 169 {
- 170 $this->log_write("Error: Cannot resolve MX \"".$domain."\"\n");
- 171 return FALSE;
- 172 }
- 173 foreach ($MXHOSTS as $host)
- 174 {
- 175 $this->log_write("Trying to ".$host.":".$this->smtp_port."\n");
- 176 $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out);
- 177 if (!($this->sock && $this->smtp_ok()))
- 178 {
- 179 $this->log_write("Warning: Cannot connect to mx host ".$host."\n");
- 180 $this->log_write("Error: ".$errstr." (".$errno.")\n");
- 181 continue;
- 182 }
- 183 $this->log_write("Connected to mx host ".$host."\n");
- 184 return TRUE;
- 185 }
- 186 $this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")\n");
- 187 return FALSE;
- 188 }
- 189
- 190 function smtp_message($header, $body)
- 191 {
- 192 fputs($this->sock, $header."\r\n".$body);
- 193 $this->smtp_debug("> ".str_replace("\r\n", "\n"."> ", $header."\n> ".$body."\n> "));
- 194 return TRUE;
- 195 }
- 196
- 197 function smtp_eom()
- 198 {
- 199 fputs($this->sock, "\r\n.\r\n");
- 200 $this->smtp_debug(". [EOM]\n");
- 201 return $this->smtp_ok();
- 202 }
- 203
- 204 function smtp_ok()
- 205 {
- 206 $response = str_replace("\r\n", "", fgets($this->sock, 512));
- 207 $this->smtp_debug($response."\n");
- 208 if (!preg_match("/^[23]/", $response))
- 209 {
- 210 fputs($this->sock, "QUIT\r\n");
- 211 fgets($this->sock, 512);
- 212 $this->log_write("Error: Remote host returned \"".$response."\"\n");
- 213 return FALSE;
- 214 }
- 215 return TRUE;
- 216 }
- 217
- 218 function smtp_putcmd($cmd, $arg = "")
- 219 {
- 220 if ($arg != "")
- 221 {
- 222 if($cmd=="")
- 223 {
- 224 $cmd = $arg;
- 225 }
- 226 else
- 227 {
- 228 $cmd = $cmd." ".$arg;
- 229 }
- 230 }
- 231 fputs($this->sock, $cmd."\r\n");
- 232 $this->smtp_debug("> ".$cmd."\n");
- 233 return $this->smtp_ok();
- 234 }
- 235
- 236 function smtp_error($string)
- 237 {
- 238 $this->log_write("Error: Error occurred while ".$string.".\n");
- 239 return FALSE;
- 240 }
- 241
- 242 function log_write($message)
- 243 {
- 244 $this->smtp_debug($message);
- 245 if ($this->log_file == "")
- 246 {
- 247 return TRUE;
- 248 }
- 249 $message = date("M d H:i:s ").get_current_user()."[".getmypid()."]: ".$message;
- 250 if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a")))
- 251 {
- 252 $this->smtp_debug("Warning: Cannot open log file \"".$this->log_file."\"\n");
- 253 return FALSE;;
- 254 }
- 255 flock($fp, LOCK_EX);
- 256 fputs($fp, $message);
- 257 fclose($fp);
- 258 return TRUE;
- 259 }
- 260
- 261 function strip_comment($address)
- 262 {
- 263 $comment = "/\([^()]*\)/";
- 264 while (preg_match($comment, $address))
- 265 {
- 266 $address = preg_replace($comment, "", $address);
- 267 }
- 268 return $address;
- 269 }
- 270
- 271 function get_address($address)
- 272 {
- 273 $address = preg_replace("/([ \t\r\n])+/", "", $address);
- 274 $address = preg_replace("/^.*<(.+)>.*$/", "\1", $address);
- 275 return $address;
- 276 }
- 277
- 278 function smtp_debug($message)
- 279 {
- 280 if ($this->debug)
- 281 {
- 282 echo $message;
- 283 }
- 284 }
- 285
- 286 }
- 287 ?>
View Code
sendCodeTest.php
- 1 <?php
- 2 header("Content-Type: text/html; charset=utf-8");
- 3
- 4 //引入发送邮件类
- 5 require("smtp.php");
- 6 //使用163邮箱服务器
- 7 $smtpserver = "smtp.163.com";
- 8 //163邮箱服务器端口
- 9 $smtpserverport = 25;
- 10 //你的163服务器邮箱账号
- 11 $smtpusermail = "18503001535@163.com";
- 12 //收件人邮箱
- 13 $smtpemailto = "244491216@qq.com";
- 14
- 15 //你的邮箱账号(去掉@163.com)
- 16 $smtpuser = "18503001535";//你的163邮箱去掉后面的163.com
- 17 //你的邮箱密码
- 18 $smtppass = "baomihua1234"; //你的163邮箱SMTP的授权码,千万不要填密码!!!
- 19
- 20 //邮件主题
- 21 $mailsubject = "测试邮件发送";
- 22 //邮件内容
- 23 $mailbody = "PHP+MySQL";
- 24 //邮件格式(HTML/TXT),TXT为文本邮件
- 25 $mailtype = "TXT";
- 26 //这里面的一个true是表示使用身份验证,否则不使用身份验证.
- 27 $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);
- 28 //是否显示发送的调试信息
- 29 $smtp->debug = TRUE;
- 30 //发送邮件
- 31 $smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $mailbody, $mailtype);
- 32
- 33 ?>
View Code
注意:
- 该代码得设置邮箱得授权码,163邮箱设置得地方:设置-客户端授权密码-重新授权码
- 使用这个发邮件,邮件可能会进入垃圾箱或者被拦截
方式2:使用socket协议发送邮件
sendMail.php
- <?php
- header("Content-Type:text/html;charset=utf8");
- $content = <<<\'html\'
- <table style="width:100%;height:100%;">
- <tr><td style="text-align: center;">
- <div style="display: inline-block; padding:30px; color:red; ">
- <img src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"/>
- <h1>helloworld,这是一封测试邮件</h1>
- <a style="text-decoration: none; color: #ffffff" href="http://serverjs.cn" target="_blank">
- <div style="font-family:\'微软雅黑\';font-size: 18px; text-decoration: none; white-space: nowrap; color: #ffffff; padding-bottom: 10px; text-align: center; padding-top: 10px; padding-left: 25px; margin: 0px; padding-right: 25px; background-color: #cc0001; border-radius: 3px">马上激活 </div>
- </a>
- </div>
- </td></tr>
- </table>
- html;
- // $to = "15679700245@163.com";
- $to = "18503001535@163.com";
- echo sendMail("这是发件人", "admin@serverjs.cn", $to, "这是邮件标题", $content, true, "utf8");
- function sendMail($senderName, $sender, $to, $subject, $content, $isHtml = false, $encode = "utf-8")
- {
- date_default_timezone_set(\'Asia/Shanghai\');
- $toHostname = substr($to, strrpos($to, \'@\') + 1);
- if (dns_get_mx($toHostname, $mxhosts, $weight)) {
- // $best = array_search(min($weight), $weight);
- // $mxBestHost = $mxhosts[$best];
- $socket = $res = $errno = $errstr = null;
- foreach ($mxhosts as $v) {
- $socket = @fsockopen($v, 25, $errno, $errstr, 10);
- if ($socket) {
- $res = fgets($socket);
- if ($res != 220) {
- fclose($socket);
- return $res;
- }
- break;
- }
- }
- if (! $socket) {
- return "$errstr ($errno)";
- }
- $senderHost = substr($sender, strrpos($sender, \'@\') + 1);
- fwrite($socket, "HELO $senderHost\r\n");
- fflush($socket);
- $res = fgets($socket);
- if ($res != 250) {
- fclose($socket);
- return $res;
- }
- fwrite($socket, "MAIL FROM: <$sender>\r\n");
- fflush($socket);
- $res = fgets($socket);
- if ($res != 250) {
- fclose($socket);
- return $res;
- }
- fwrite($socket, "RCPT TO: <$to>\r\n");
- fflush($socket);
- $res = fgets($socket);
- if ($res != 250) {
- fclose($socket);
- return $res;
- }
- fwrite($socket, "DATA\r\n");
- fflush($socket);
- $res = fgets($socket);
- if ($res != 354) {
- fclose($socket);
- return $res;
- }
- fwrite($socket, "From: =?$encode?B?" . base64_encode($senderName) . "?= <$sender>\r\n");
- fwrite($socket, "To: $to\r\n");
- fwrite($socket, "Subject: =?$encode?B?" . base64_encode($subject) . "?=\r\n");
- fwrite($socket, "Date: " . date(DATE_RFC822) . "\r\n");
- fwrite($socket, "MIME-Version: 1.0\r\n");
- if ($isHtml) {
- fwrite($socket, "Content-Type: text/html; charset=\"$encode\"\r\n");
- } else {
- fwrite($socket, "Content-Type: text/plain; charset=\"$encode\"\r\n");
- }
- fwrite($socket, "Content-Transfer-Encoding: base64\r\n");
- fwrite($socket, "X-Priority: 3\r\n");
- fwrite($socket, "X-Mailer: PHP Server\r\n");
- fwrite($socket, "\r\n");
- fwrite($socket, base64_encode($content));
- fwrite($socket, "\r\n.\r\n");
- fflush($socket);
- $res = fgets($socket);
- if ($res == 550) {
- fclose($socket);
- return "邮件被拦截: $res";
- } elseif ($res != 250) {
- fclose($socket);
- return $res;
- }
- fwrite($socket, "QUIT\r\n");
- fflush($socket);
- $res = fgets($socket);
- if ($res != 221) {
- fclose($socket);
- return $res;
- }
- fclose($socket);
- return "发送成功";
- } else {
- return "找不到主机";
- }
- }