Send email with Socket
Author: limodou in several PHP home page space of the application, to provide mail functionality is very small, always call the complete mail () function will later cents below the no. But the role of email in online life is getting bigger. I want to think about the Networm online without collecting the email. Can you call the real nematoth? The role of the mail I don't want to say anything, but if the home page does not support mail () send so? I also thought about implementing email through Socket, but helpless for Socket programming is unfamiliar with PHP, plus the email to use the SMTP protocol, and read a lot of English, and have never been studied. I finally found an article for a day, and sent an email with Socket. I won it to the treasure to copy it, and transform it into a PHP available class for everyone to use. The original article is just a simple example, and there are some mistakes. In my multiple experiments, the transformation finally changed it into a class directly using Socket, sending a message to the specified mailbox, if everyone and the previous message MIME's article can be implemented on websites that do not support mail () functions. Because the process of sending mail is required, it may not be exactly the same as the mail () process mechanism, so speed is slow, but you can solve the urgent need to send the email function, and you can also use PHP to make Socket programming. Here is the principle of this class to everyone, and explain some basic knowledge about SMTP. Socket Programming Introduction to everyone, I am not a TCP / IP programming expert, so I just talked about my understanding and experience. Use the fsockopen function to open an Internet connection, function grammatical format: int fsockopen (String hostname, int port, int [errno], string [errstr], int [timeout]); Measure means that I don't want to talk, here you want to use The SMTP protocol, so the port number is 25. After the connection is successful, a Socket handle will be returned, and it can be used as the file handle. The operation available is FPUTS (), FGETS (), FeOf (), Fclose (), etc. It's very simple to introduce it to here. SMTP's basic TCP / IP Internet protocol general command format is implemented by request / answer mode, which is text information, so it is easy to handle. SMTP is a brief image of a simple mail transfer protocol that enables the client to send mail to the server. So below the command refers to the request instruction to the server to the server, and the response means information that the server returns to the client. SMTP is divided into two parts: command head and information. The command head mainly completes the connection, verification of the client and the server. The entire process consists of multiple commands. After each command is sent to the server, the response information is given by the server, typically 3-digit response code and response text. The response code returned by the different servers is observed, but it is not necessary to respond to a textbook. Each command and the response have a roller, which uses FPUTS () and fgets () to process the command and response. SMTP commands and response information are single lines. The information body is the body part of the message, and the final ending should be ended as a separate "." As the end line.
The client's common SMTP instruction is: Helo Hostname: Say and tell the client name with the server, you can fill in the mail from: sender_id: tell the server to send people the address RCPT to: Receiver_ID: Tell the server to the address of the server Data : The following starts to transfer the contents content, and finally to end the RESET: Cancel the just command, from the new start verify userid: check the account exists (this instruction is an optional instruction, the server may not be supported) Quit: Exit connection, end the response information returned by the server is (format: Response code space interpretation): 220 Service Ready (this information is returned when the socket connection is successful) 221 is processing 250 request email action correct, complete (Helo, Mail from, RCPT TO, QUIT instruction execution will return this information) 354 Start sending data, ending. (DATA instructions will return this information, client should send information) 500 syntax error, command cannot recognize 550 commands cannot be performed Email the mailbox invalid 552 interrupt processing: User exceeds the file space below to give a simple command head (this is done after opening socket), is the test result of I sent to stmp.263.net: Helo Limodou 250 SMTP.263 .NET Mail from: chatme@263.net 250 ok rpt to: chatme@263.net 250 ok data 354 end data with. to: chat@263.net from: chat@263.net Subject: test from: chatme @ 263 .NET TEST. Quit 250 OK: Queued AS C46411C5097E0 This is some simple knowledge of SMTP. Related content can be found in RFC. RFC 821 defines related instructions for receiving / email. RFC 822 develops the format of the message content. RFC 2045-2048 has formatted the format of multimedia mail, RFC 1113, 1422-1424 is discussed how to enhance the confidentiality of email. The implementation of the Send_mail class is now introducing the send mail class I have written. With the above preparatory knowledge, the following is achieved. Class member variables VAR $ lastMessage; // Record the last return response information var $ lastact; // final action, string form var $ welcome; // Welcome to user var $ debug; // Whether to display Debugging information var $ SMTP; // SMTP server var $ port; // SMTP port number var $ fp; // socket handle where $ LastMessage and $ Lastact are used to record the last response information and execution command, when an error occurs Users can use them. For testing, I also define $ debug variables, when their value is TRUE, some execution information is displayed during the run, otherwise no output. $ FP is used to save the open Socket handle.
Class constructor ----------------------------------------------- --------------------------------- Function Send_mail ($ SMTP, $ Welcome = ", $ debug = false) {IF (Empty ($ SMTP)) DIE ("SMTP Cannt Be Null!"); $ this-> SMTP = $ SMTP; if ($ Welcome)) {$ this-> Welcome = gethostbyaddr ("localhost") Else $ this-> Welcome = $ Welcome; $ this-> debug = $ debug; $ this-> lastmessage = "; $ this-> lastact ="; $ this-> port = "25";} -------------------------------------------------- ---------------------------- This constructor mainly completes some of the initial values and settings. $ Welcome is used in the Helo directive to tell the server user's name. The Helo Directive requires the machine name, but it is not possible. If the user does not give $ Welcome, the local machine name is automatically found. 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 $} $ {message} font> "; 15} 16} ---------------------------------------- --------------------------------------- This function is used to display debugging information. You can specify in $ inout whether the command is uploaded or the response returned. If the upload command is used, "OUT" is used; "IN" if the response returned. On line 3, it is determined whether debugging information is to be output. On the 5th line, it is determined whether or not the response information. Lines 11-12, determining whether the information string is a newline, if not, add HTML wrap tag. Thirteen 13 will turn the line into the wrap tag of HTML. On the 14th line, output the entire information, and the information color is placed as a gray to distinguish between.
Perform 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-> la castmessage, "in"); 8 if (! EREG ("^ $ Code", $ this-> lastmessage)) 9 {10 returnaf 11} 12 else 13 returnography; 14} ---------------------------------------- ---------------------------------------- Write the Socket processing section discovering, some commands Treatment is similar, such as Helo, Mail from, RCPT TO, Quit, Data commands, requests to display the relevant content according to whether to display debugging information, while if it is desired, if it is desired, if not, if not It should be interrupted. So in order to clear and simplify, the processing of these commands has written a general processing function. In the parameter of the function, $ code is the expected response code, if the response code is the same, the process is successful, otherwise an error. On line 3, record the last execution command. On line 4, the upload command is displayed. On line 5, use the FPUTS to actually switch instructions to the server. On line 6, the reception response information from the server will place in the final response message variable. On line 7, the response information is displayed. Chapter 8, determining if the response information is expected, if it is the end of the 13th line, it will return failure at the 10th line (FALSE). In this way, the function of this function completes the display function of the instruction and information, and does not determine whether the returned response is successful. The mail delivery processing is true, you have to look at it.
:) ------------------------------------------------ ------------------------------ 1 Function Send ($ To, $ from, $ SUBJECT, $ Message) 2 { 3 4 // Connection 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 ; 20 else 21 {22 $ this-> Lastact = "Helo". $ This-> Welcome. "/ N"; 23 if (! $ This-> do_command ($ this-> lastact, "250"))))) 24 {25 fclose ($ this-> fp); 26 returnaf 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 returnaf false; 41} 42 43 // Send body 44 $ this-> Lastact = "DATA / N"; 45 if (! $ This-> do_command ($ this-> Lastact, "354")) 46 {47 fclose ($ this-> fp); 48 returnaf 49} 50 51 // Handling Subject Head 52 $ Head = "Subject: $ Subject / N"; 53 if (! Empty ($ SUBJECT) &&! EREG ($ Head, $ Message) 54 {55 $ message = $ HEAD . $ message; 56} 57 58 // Handling from head 59 $ head = "from: $ from / n"; 60 if (! Empty ($ from) &&! EREG ($ head, $ message)) 61 {62 $ Message = $ head. $ message; 63} 64 65 // Handling TO header 66 $ head = "to: $ to / n";
67 if (! EMPTY ($ to) &&! EREG ($ head, $ message)) 68 {69 $ message = $ head. $ Message; 70} 71 72 // Added 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 returnaf false; 91} 92} ------- -------------------------------------------------- ----------------------- I don't say it very clearly. This function has four parameters, which are $ TO indicating that the recipient, $ from represented the sender, $ SUBJECT Sign Email theme and $ Message indicate the mail body. Returns false if the handle is successful. Chapter 8, connected to the mail server, if the success response code should be 220. Chapter 12, set the blocking mode, indicating that the information must return to continue. Detailed explanation. On the 16th line, it is determined whether the response code is 220. If so, continue processing, otherwise the error returns. Rows 22-27, process the HELO directive, and the desired response code is 250. Rows 29-34, processing the Mail from instruction, and expect the response code to 250. THE 36-41, process the RCPT TO directive, and the desired response code is 250. Channel 44-49, process the DATA instruction, and the desired response code is 354. Rows 51-76, generate a mail body, and send it. Rows 52-56, if $ subject is not empty, find a topic section in the mail body, if not, add the topic section. 59-63, if the $ from is not empty, find a part of the sender in the mail body, if not, add the sender part. Line 66-70, if the $ TO is not empty, find if there is a partner part in the mail body, if not, add the acceptor part. Sections 73-74, find if the mail body has ended, if not, add the end of the mail body (in "." As a special line of a separate line). Chapter 76, send mail body. Sections 78-83, executing quit is not connected to the server, and the desired response code is 250. Chapter 85, return processing success mark (TRUE). Articles 81-91, processing with the server connection failure. The above is the implementation of the entire Send_mail class, it should not be difficult. An example is given below.
Mail Send instance gives a simplest instance: -------------------------------------- ------------------------------------------ 1 incrude "sendmail.class .php3 "; 2 $ email =" Hello, this is a test letter! "; 3 $ sendmail = new send_mail (" smtp.263.net "," limitedou ", true); // Display adjustment information 4 IF ( $ Sendmail-> Send ("chatme@263.net", "chatme@263.net", "test", $ email) 5 {6 echo "Send success!
"; 7} 8 else 9 {10 Echo "Send Failure!
"; 11}?> ---------------------------------------------------------------------------------------------------------------------- ------------------------------------------- 1st line, load Send_mail class. Line 3, create a class instance, and set the display signal, if you don't want to display, you can $ sendmail = new send_mail ("smtp.263.net") ;. Chapter 4, send mail. Very simple, isn't it? An example of a previous transmission MIME message is given below, and an example of sending an HTML attachment is given.