Survive in the cracks – use SMTP to send emails in a php virtual host environment with nothing (1)

Surviving in the cracks

Use the php virtual host to send an email to the designated QQ mailbox account, taking 163 mailbox as an example.

Preface: In the harsh environment of Alibaba Cloud virtual host PHP, there are very few PHP function libraries and all kinds of support are not supported. If I want to send an email that is not blocked by the recipient’s mailbox, I suddenly feel that the whole world is dark. But fortunately, after surviving in the cracks and stepping through various pitfalls, there is still a solution in the end.

  • First, you must register a 163 personal email account, configure SMTP and set an authorization password (this part will not be repeated, if you have any questions, please Baidu).
  • A few reminders:
    • The email was sent successfully but no email reminder was received: The sent email may have been placed in the trash, especially if the account is the recipient of QQ mailbox.
    • Don’t have too much content in the email, otherwise it is likely to be treated as spam (I personally tested that if you send the entire html code email, the QQ receiving mailbox will block and reject the mail, while the 163 receiving mailbox will receive the mail normally), especially Note that the account is the recipient of QQ mailbox.
    • The following is to configure smpt with 163 mailbox. The personal test code is available. Configuration of smpt with other mailboxes has not been tried.
    • Custom sender has been solved, it is written in the code.
    • The problem that when the receiving email address is a QQ mailbox, the email will be treated as spam by the QQ mailbox has not been solved.
  • The following is the php code:
test.php
 1 <?php
 2 header("Content-Type: text/html; charset=utf-8");
 3
 4 //Introduce sending mail class
 5 require("smtp.php");
 6 //Use 163 mailbox server
 7 $smtpserver = "smtp.163.com";
 8 //163 Email server port
 9 $smtpserverport = 25;
10 //Your 163 server email account
11 $smtpusermail = "****@163.com";//
12 //Recipient’s email address, ***@163.com/***@qq.com
13 $smtpemailto = "[email protected]";
14 //Sender, you can display the sender at will
15 $sender = "Email sender";
16 //Your email account (remove @163.com)
17 $smtpuser = "****";//Remove the 163.com in your 163 email address
18 //Your email password
19 $smtppass = "*****"; //Your 163 mailbox SMTP authorization code, do not fill in the password! ! !
20
21 //Email subject
22 $mailsubject = "Email Reminder";
23 //Email content
24 $mailbody = "
25 Details:</br>
26 <h1>This is a test email</h1>
27 ";
28 //Email format (HTML/TXT), TXT is text email
29 $mailtype = "HTML";
30 //A true here means that authentication is used, otherwise authentication is not used.
31 $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);
32 //Whether to display the sent debugging information
33 $smtp->debug = TRUE;
34 //Send email
35 $smtp->sendmail($smtpemailto, $smtpusermail, $sender,$mailsubject, $mailbody, $mailtype);
36
37 ?>
smtp.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 /* Contractor */
 21 function smtp($relay_host = "", $smtp_port = 25,$auth = false,$user,$pass)
 twenty two  {
 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, $sender, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "")
 37 {
 38 $mail_from = $this->get_address($this->strip_comment($from));
 39 $body = preg_replace("/(^|(\r\
))(\.)/", "\1.\3", $body);
 40 $header = "MIME-Version:1.0\r\
";
 41 if($mailtype=="HTML")
 42 {
 43 $header .= "Content-Type:text/html\r\
";
 44}
 45 $header .= "To: ".$to."\r\
";
 46 if ($cc != "")
 47 {
 48 $header .= "Cc: ".$cc."\r\
";
 49 }
 50 $header .= "From: ".$sender."<".$from.">\r\
";
 51 $header .= "Subject: ".$subject."\r\
";
 52 $header .= $additional_headers;
 53 $header .= "Date: ".date("r")."\r\
";
 54 $header .= "X-Mailer:By Redhat (PHP/".phpversion().")\r\
";
 55 list($msec, $sec) = explode(" ", microtime());
 56 $header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">\r\
";
 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."\
");
 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.">\
");
 80}
 81 else
 82 {
 83 $this->log_write("Error: Cannot send email to <".$rcpt_to.">\
");
 84 $sent = FALSE;
 85}
 86 fclose($this->sock);
 87 $this->log_write("Disconnected from remote host\
");
 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."\
");
154 $this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out);
155 if (!($this->sock & amp; & amp; $this->smtp_ok()))
156 {
157 $this->log_write("Error: Cannot connect to relay host ".$this->relay_host."\
");
158 $this->log_write("Error: ".$errstr." (".$errno.")\
");
159 return FALSE;
160 }
161 $this->log_write("Connected to relay host ".$this->relay_host."\
");
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.""\
");
171 return FALSE;
172 }
173 foreach ($MXHOSTS as $host)
174 {
175 $this->log_write("Trying to ".$host.":".$this->smtp_port."\
");
176 $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out);
177 if (!($this->sock & amp; & amp; $this->smtp_ok()))
178 {
179 $this->log_write("Warning: Cannot connect to mx host ".$host."\
");
180 $this->log_write("Error: ".$errstr." (".$errno.")\
");
181 continue;
182 }
183 $this->log_write("Connected to mx host ".$host."\
");
184 return TRUE;
185 }
186 $this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")\
");
187 return FALSE;
188 }
189
190 function smtp_message($header, $body)
191 {
192 fputs($this->sock, $header."\r\
".$body);
193 $this->smtp_debug("> ".str_replace("\r\
", "\
"."> ", $header."\
> ".$body."\
> "));
194 return TRUE;
195 }
196
197 function smtp_eom()
198 {
199 fputs($this->sock, "\r\
.\r\
");
200 $this->smtp_debug(". [EOM]\
");
201 return $this->smtp_ok();
202 }
203
204 function smtp_ok()
205 {
206 $response = str_replace("\r\
", "", fgets($this->sock, 512));
207 $this->smtp_debug($response."\
");
208 if (!preg_match("/^[23]/", $response))
209 {
210 fputs($this->sock, "QUIT\r\
");
211 fgets($this->sock, 512);
212 $this->log_write("Error: Remote host returned "".$response.""\
");
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\
");
232 $this->smtp_debug("> ".$cmd."\
");
233 return $this->smtp_ok();
234 }
235
236 function smtp_error($string)
237 {
238 $this->log_write("Error: Error occurred while ".$string.".\
");
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.""\
");
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\
]) + /", "", $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 ?>