Use Socket to send an email (php)

Source: Internet
Author: User
TABLEcellSpacing4cellPadding5width530border0 used a Socket to send an email by limodou. in the PHP homepage space applied by the author, limodou does not provide the mail function much and always calls mail () after the function, there will be no more details. However, emails play an increasingly important role in online life. Think about it. The Net worm does not receive mail TABLE cellSpacing = 4 cellPadding = 5 width = 530 border = 0>
Use Socket to send emails

Author: limodou

In the several PHP homepage spaces applied by the author, there are not many projects that can provide the mail function. after The mail () function is called
No more. 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? Email
But what if the home page does not support mail () sending? I also thought about using socket to implement mail.
But I am not familiar with socket programming with php. In addition, the SMTP protocol is used to send emails, and I have to read a lot of English.
I have never studied it. One day I finally found an article about sending emails through socket programming. I copied it as soon as I got it.
And transformed it into a php available class for everyone to use. The original article is just a simple example, and there is also
Some errors. after many experiments and transformations, I finally changed it to a class that directly uses socket to send emails to the specified mailbox, such
By combining with the previous article on sending MIME, you can send emails on websites that do not support the mail () function. Because sending
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 problem of sending
The Mail sending function is pressing, and you can also learn to use php for socket programming. The following describes the implementation principles of this class,
At the same time, I will explain some basic SMTP knowledge to you.

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 all implemented through the request/response method, and all use text information.
It is easier to process. SMTP is short for the simple mail transmission protocol. it can send mail to the server by the client. So
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
. 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. Different servers
The response code returned by the server complies with the protocol, but the response body does not have. Each command and response end with a carriage return.
You can use fputs () and fgets () to process commands and responses. SMTP commands and response information are single rows. The information body is an email.
The final end line should be a separate "." as the end line.

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 information returned by the server is in the following format: 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 stmp.263.net:

HELO limodou
250 smtp.263.net
Mail from: chatme@263.net
250 OK
Rcpt to: chatme@263.net
250 OK
DATA
354 End data.
To: chatme@263.net
From: chatme@263.net
Subject: test
From: chatme@263.net
Test
.
QUIT
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

$ Lastmessage and $ lastact are used to record the last response information and the command to be executed. When an error occurs, you can use it.
. 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
Any output. $ 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 ");
}
Else
$ 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 = '<';
8}
9 else
10 $ m = '> ';
11 if (! Ereg ("\ n $", $ message ))
12 $ message. ="
";
13 $ message = nl2br ($ message );
14 echo "$ {m }$ {message }";
15}
16}
--------------------------------------------------------------------------------
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 the response is returned, 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 the following information to row 3:
">" To differentiate Upload commands.
Line 11-12: Determine whether the information string is a line break. if not, add the HTML line break mark. Line breaks of Line 2 will be converted to 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;
11}
12 else
13 return true;
14}
--------------------------------------------------------------------------------
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, and the response code returned should be processed if it is expected,
If it is not expected, the exit 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 {
3
4 // connect to the server
5 $ this-> lastact = "connect ";
6
7 $ this-> show_debug ("Connect to SMTP server:". $ this-> smtp, "out ");
8 $ this-> fp = fsockopen ($ this-> smtp, $ this-> port );
9 if ($ this-> fp)
10 {
11
12 set_socket_blocking ($ this-> fp, true );
13 $ this-> lastmessage = fgets ($ this-> fp, 512 );
14 $ this-> show_debug ($ this-> lastmessage, "in ");
15
16 if (! Ereg ("^ 220", $ this-> lastmessage ))
17 {
18 return false;
19}
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;
27}
28
29 $ this-> lastact = "mail from: $ from". "\ n ";
30 if (! $ This-> do_command ($ this-> lastact, "250 "))
31 {
32 fclose ($ this-> fp );
33 return false;
34}
35
36 $ this-> lastact = "rcpt to: $ to". "\ n ";
37 if (! $ This-> do_command ($ this-> lastact, "250 "))
38 {
39 fclose ($ this-> fp );
40 return false;
41}
42
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;
49}
50
51 // process the Subject header
52 $ head = "Subject: $ subject \ n ";
53 if (! Empty ($ subject )&&! Ereg ($ head, $ message ))
54 {
55 $ message = $ head. $ message;
56}
57
58 // process the From header
59 $ head = "From: $ from \ n ";
60 if (! Empty ($ from )&&! Ereg ($ head, $ message ))
61 {
62 $ message = $ head. $ message;
63}
64
65 // process the To header
66 $ head = "To: $ to \ n ";
67 if (! Empty ($ )&&! Ereg ($ head, $ message ))
68 {
69 $ message = $ head. $ message;
70}
71
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 );
77
78 $ this-> lastact = "QUIT \ n ";
79 if (! $ This-> do_command ($ this-> lastact, "250 "))
80 {
81 fclose ($ this-> fp );
82 return false;
83}
84}
85 return true;
86}
87 else
88 {
89 $ this-> show_debug ("Connect failed! "," In ");
90 return false;
91}
92}
--------------------------------------------------------------------------------
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 ("smtp.263.net", "limodou", true); // Display The Call Information
4 if ($ sendmail-> send ("chatme@263.net", "chatme@263.net", "test", $ email ))
5 {
6 echo "sent successfully!
";
7}
8 else
9 {
10 echo "failed to send!
";
11}
?>
--------------------------------------------------------------------------------
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 ("smtp.263.net ");.
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 @ 263.net'; // change the email address to the recipient's email address.
$ Str = "Newsletter for". date ('m Y', time ());

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

Hello! This is a test!

';

// Generate a MIME-type instance
$ MIME_mail ("chatme@263.net", $ 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 ("smtp.263.net", "limodou", true );

// Send an email
$ Sendmail-> send ("chatme@263.net", "chatme@263.net", $ str, $ mime-> email );

?>

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: info-contact@alibabacloud.com 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.