Use Socket to send emails in PHP

Source: Internet
Author: User
Tags ereg
In the several PHP homepage spaces applied by the author, there are not many mail functions available. after The mail () function is called, there will be no more details. However, emails play an increasingly important role in online life. Do you think that online worms do not receive emails and can be called real worms? I don't want to talk about the role of mail, but what if the home page does not support mail () sending? in the PHP home pages applied by the author, there are not many projects that provide mail functions, after calling the mail () function, there will be no more details. However, emails play an increasingly important role in online life. Do you think that online worms do not receive emails and can be called real worms? I don't want to talk about the role of the email, but what if the home page does not support mail () sending? I also thought about sending emails through socket, but I am not familiar with socket programming using php. In addition, sending emails requires SMTP protocol and reading a lot of English, so I have never studied it. One day I finally found an article about sending emails through socket programming. I copied it as a treasure and transformed it into a usable php class for your use. The original article is just a simple example, and there are still some errors. after many experiments and transformations, I finally changed it to a direct socket, class for sending emails to a specified mailbox. if you combine the class with the previous article about sending MIME, you can send emails on websites that do not support the mail () function. Because the mail sending process takes time, it may not be the same as the mail () processing mechanism, so the speed is slower, but it can solve the urgent need for the mail sending function, you can also use php for socket programming. The following describes the implementation principles of this class, and explains some basic SMTP knowledge.

Socket programming

I declare to everyone that I am not a TCP/IP programming expert, so here I just give my understanding and experience.

Use the fsockopen function to open an Internet connection. function syntax format:

Int fsockopen (string hostname, int port, int [errno], string [errstr], int [timeout]);

I don't want to talk about the parameter. the port number is 25 because the SMTP protocol is used. After the connection is successfully opened,
Socket handle, which can be the same as the file handle. Available operations include fputs (), fgets (), feof (), and fclose ()

This is a simple introduction.

SMTP basics

The common command formats of TCP/IP-based Internet protocols are implemented through the request/response method and all adopt text information, so it is easier to process them. SMTP is short for the simple mail transmission protocol. it can send mail to the server by the client. Therefore, the following commands refer to the request commands sent by the client to the server, and the response refers to the information that the server returns to the client.

SMTP is divided into the command header and information body. The command header is used to connect the client to the server and verify the connection. The entire process consists of multiple commands. After each command is sent to the server, the server gives the response information, which is generally a three-digit response code and response text. The response codes returned by different servers follow the protocol, but the response body does not have. Each command and response end with a carriage return. using fputs () and fgets (), you can process commands and responses. SMTP commands and response information are single rows. The message body is the body of the email. the ending line should be a separate.

Some common SMTP commands on the client are:

HELO hostname: Greet the server and inform the client of the name of the machine used.
Mail from: sender_id: indicates the address of the sender on the server.
Rcpt to: receiver_id: tell the recipient's address on the server
DATA: Transfer the Mail content below, and end with a special line containing only.
RESET: cancel the command.
VERIFY userid: Check whether the account exists (this command is optional and may not be supported by the server)
QUIT: disconnect and end
The response message returned by the server is in the format of: response code space explanation ):

220 service ready (this message is returned when the socket connection is successful)
221 processing in progress
250 The request email is correct and completed (HELO, mail from, rcpt to, QUIT command execution will return this message)
354 start sending DATA and end with. (This message will be returned if the DATA command is executed successfully. the client should send the message)
500 syntax error. the command cannot be identified
550 the command cannot be executed, and the email address is invalid
552 interrupt handling: The user exceeds the file space
Below is a simple command header (this is done after opening the socket), which is the test result of sending an email to

HELO limodou
Mail from:
250 OK
Rcpt to:
250 OK
354 End data.
Subject: test
250 OK: queued as C46411C5097E0

This is some simple SMTP knowledge. For more information, see RFC.

RFC 821 defines instructions for receiving/sending emails.
RFC 822 defines the email content format.
RFC 2045-2048 defines the multimedia mail content format,
RFC 1113,142-discusses how to enhance the confidentiality of emails.

Send_mail class implementation
Now we will introduce the mail class I have compiled. With the above preparation knowledge, the following is the implementation.

Class member variables

Var $ lastmessage; // record the last response
Var $ lastact; // The final action, in the string format
Var $ welcome; // used after HELO. welcome
Var $ debug; // whether to display debugging information
Var $ smtp; // smtp server
Var $ port; // smtp port number
Var $ fp; // socket handle

Among them, $ lastmessage and $ lastact are used to record the last response information and executed commands. When an error occurs, you can use them. For testing purposes, I also defined the $ debug variable. when its value is true, some execution information is displayed during the running process; otherwise, no output is provided. $ Fp is used to save the opened socket handle.

Class Construction

Function send_mail ($ smtp, $ welcome = "", $ debug = false)
If (empty ($ smtp) die ("SMTP cannt be NULL! ");
$ This-> smtp = $ smtp;
If (empty ($ welcome ))
$ This-> welcome = gethostbyaddr ("localhost ");
$ This-> welcome = $ welcome;
$ This-> debug = $ debug;
$ This-> lastmessage = "";
$ This-> lastact = "";
$ This-> port = "25 ";
This constructor mainly determines and sets some initial values. $ Welcome is used in the HELO command to tell the server user's name. The HELO command must be a machine name. If $ welcome is not provided, the local machine name is automatically searched.

Display debugging information

1 function show_debug ($ message, $ inout)
2 {
3 if ($ this-> debug)
4 {
5 if ($ inout = "in") // response information
6 {
7 $ m = '<';
9 else
10 $ m = '> ';
11 if (! Ereg ("\ n $", $ message ))
12 $ message. ="
13 $ message = nl2br ($ message );
14 echo "$ {m }$ {message }";
This function is used to display debugging information. You can specify whether to upload the command or return the response in $ inout. if it is an upload command, use "out"; if it is a returned response, use "in ".

Line 3: determine whether to output debugging information.
Row 3 determines whether the response information is returned. If yes, add "<" before the information of row 3 to differentiate the information; otherwise, add ">" to the second line to differentiate the upload command.
Line 11-12: Determine whether the information string is a line break. if not, add the HTML line break mark. Line breaks of lines 13th are converted into line breaks of HTML.
Line 3 outputs the entire information, and sets the color of the information to gray to show the difference. Execute a command

1 function do_command ($ command, $ code)
2 {
3 $ this-> lastact = $ command;
4 $ this-> show_debug ($ this-> lastact, "out ");
5 fputs ($ this-> fp, $ this-> lastact );
6 $ this-> lastmessage = fgets ($ this-> fp, 512 );
7 $ this-> show_debug ($ this-> lastmessage, "in ");
8 if (! Ereg ("^ $ code", $ this-> lastmessage ))
9 {
10 return false;
12 else
13 return true;
In the socket processing section, we found that some commands are very similar, such as HELO, mail from, rcpt to, QUIT, and DATA commands, all requests are required to display the relevant content based on whether the debugging information is displayed. if the returned response code is expected, the response should be processed. if not, the response should be interrupted. Therefore, for sake of clarity and simplicity, a general processing function is specially designed for the processing of these commands. In the function parameter, $ code is the expected response code. if the response code is the same, the processing is successful. Otherwise, an error occurs.

Line 3: record the last command to be executed.
Line 3 shows the upload command.
Line 3: Use fputs to transfer commands to the server.
Line 3: The server receives the response information in the final response message variable.
Line 3 shows the response information.
Row 3 determines whether the response is expected. If yes, row 3 returns true; otherwise, row 3 returns false ).

In this way, this function completes the sending and display of commands and information, and judges whether the returned response is successful.

Mail handling

The following are the real secrets. you should check them carefully. :)

1 function send ($ to, $ from, $ subject, $ message)
2 {
4 // connect to the server
5 $ this-> lastact = "connect ";
7 $ this-> show_debug ("Connect to SMTP server:". $ this-> smtp, "out ");
8 $ this-> fp = fsockopen ($ this-> smtp, $ this-> port );
9 if ($ this-> fp)
10 {
12 set_socket_blocking ($ this-> fp, true );
13 $ this-> lastmessage = fgets ($ this-> fp, 512 );
14 $ this-> show_debug ($ this-> lastmessage, "in ");
16 if (! Ereg ("^ 220", $ this-> lastmessage ))
17 {
18 return false;
20 else
21 {
22 $ this-> lastact = "HELO". $ this-> welcome. "\ n ";
23 if (! $ This-> do_command ($ this-> lastact, "250 "))
24 {
25 fclose ($ this-> fp );
26 return false;
29 $ this-> lastact = "mail from: $ from". "\ n ";
30 if (! $ This-> do_command ($ this-> lastact, "250 "))
31 {
32 fclose ($ this-> fp );
33 return false;
36 $ this-> lastact = "rcpt to: $ to". "\ n ";
37 if (! $ This-> do_command ($ this-> lastact, "250 "))
38 {
39 fclose ($ this-> fp );
40 return false;
43 // send the body
44 $ this-> lastact = "DATA \ n ";
45 if (! $ This-> do_command ($ this-> lastact, "354 "))
46 {
47 fclose ($ this-> fp );
48 return false;
51 // process the Subject header
52 $ head = "Subject: $ subject \ n ";
53 if (! Empty ($ subject )&&! Ereg ($ head, $ message ))
54 {
55 $ message = $ head. $ message;
58 // process the From header
59 $ head = "From: $ from \ n ";
60 if (! Empty ($ from )&&! Ereg ($ head, $ message ))
61 {
62 $ message = $ head. $ message;
65 // process the To header
66 $ head = "To: $ to \ n ";
67 if (! Empty ($ )&&! Ereg ($ head, $ message ))
68 {
69 $ message = $ head. $ message;
72 // add the end string
73 if (! Ereg ("\ n \. \ n", $ message ))
74 $ message. = "\ n. \ n ";
75 $ this-> show_debug ($ message, "out ");
76 fputs ($ this-> fp, $ message );
78 $ this-> lastact = "QUIT \ n ";
79 if (! $ This-> do_command ($ this-> lastact, "250 "))
80 {
81 fclose ($ this-> fp );
82 return false;
85 return true;
87 else
88 {
89 $ this-> show_debug ("Connect failed! "," In ");
90 return false;
I won't say anything clearly.

This function has four parameters: $ to indicates the recipient, $ from indicates the sender, and $ subject indicates the subject of the email and $ message indicates the body of the email. If the processing is successful, true is returned. if the processing fails, false is returned.

Line 2: connect to the email server. if the response code is successful, it must be 8th.
Row 3 sets the blocking mode, indicating that the information must be returned to continue. For more information, see the manual.
In row 3, check whether the response code is 16th. If yes, continue to process the code; otherwise, an error is returned.
Line 22-27 processes the HELO command and the expected response code is 250.
Line 29-34 processes the mail from instruction and the expected response code is 250.
Line 36-41 processes the rcpt to command and the expected response code is 250.
Line 44-49 processes DATA commands and the expected response code is 354.
Line 51-76 generates and sends the email body.
Line 52-56. if $ subject is not empty, check whether the subject is included in the email body. if not, add the subject.
Line 59-63. if $ from is not blank, check whether the Mail body contains the sender part. if not, add the sender part.
Line 66-70. if $ to is not empty, check whether the email body contains the recipient. if not, add the recipient.
Row 73-74: Check whether the Mail body has an ending line. if not, add the ending line of the mail body (use "." as a special line for a separate line ).
Row 3: send the email body.
Line 8-83: execute QUIT to check whether the connection is established with the server. the expected response code is 250.
Row 3: returns the success mark (true ).
Line 81-91: Handling of connection failures with the server.
The above is the implementation of the entire send_mail class, which should not be very difficult.

An instance is provided below.

Email sending instance
First, we will provide a simple example:
1 include "sendmail. class. php3 ";
2 $ email = "Hello, this is a test letter! ";
3 $ sendmail = new send_mail ("", "limodou", true); // Display The Call Information
4 if ($ sendmail-> send ("", "", "test", $ email ))
5 {
6 echo "sent successfully!
8 else
9 {
10 echo "failed to send!
Line 3: load the send_mail class.
Line 3: Create an instance of the class and set to display the call information. if you do not want to display the information, you can
$ Sendmail = new send_mail (" ");.
Line 3: send an email.

It's easy, isn't it? The following is an example of sending an HTML attachment to a MIME mail.


Include "MIME. class. php3 ";
// Note: in the text of the MIME Mail, the class file name is MIME. class. here I change it to this

$ To = 'chatme @'; // change the email address to the recipient's email address.
$ Str = "Newsletter for". date ('m Y', time ());

// I have reduced the information.
$ Html_data ='

Hello! This is a test!


// Generate a MIME-type instance
$ MIME_mail ("", $ to, $ str );

// Add HTML attachments
$ Mime-> attach ($ html_data, "", HTML, BASE64 );

// Comment out and use my Sent Mail for processing
// $ Mime-> send_mail ();

// Generate an email
$ Mime-> gen_email ();

// Display mail information
// Echo $ mime-> email ."

// Contains the sendmail file
Include "sendmail. class. php3 ";

// Create an instance
$ Sendmail = new send_mail ("", "limodou", true );

// Send an email
$ Sendmail-> send ("", "", $ str, $ mime-> email );



The annotations are clearly written, so more explanations will not be made. In actual application, set debug in the send_mail constructor to false or not to write.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.