Heim > php教程 > PHP开发 > Hauptteil

E-Mail mit Socket (php) senden

高洛峰
Freigeben: 2016-12-02 10:12:15
Original
1120 Leute haben es durchsucht

Einführung in die Socket-Programmierung
Ich möchte allen sagen, dass ich kein Experte für TCP/IP-Programmierung bin, deshalb teile ich hier nur mein Verständnis und meine Erfahrung.

Verwenden Sie die Funktion fsockopen, um eine Internetverbindung zu öffnen. Das Syntaxformat der Funktion ist:

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

Über die Bedeutung der Parameter muss ich glaube ich nicht sprechen, da hier das SMTP-Protokoll verwendet wird, ist die Portnummer 25. Nachdem die Verbindung erfolgreich geöffnet wurde, wird ein
Socket-Handle zurückgegeben, das wie ein Dateihandle verwendet werden kann. Zu den verfügbaren Operationen gehören fputs(), fgets(), feof(), fclose()
usw.

Das war's für eine ganz einfache Einführung.

Grundlagen von SMTP
Das allgemeine Befehlsformat des auf TCP/IP basierenden Internetprotokolls wird durch die Anforderungs-/Antwortmethode implementiert und alle Textinformationen werden verwendet, sodass
einfacher zu verarbeiten ist. SMTP ist die Abkürzung für Simple Mail Transfer Protocol, das es dem Client ermöglicht, E-Mails an den Server zu senden. Also
Der unten erwähnte Befehl bezieht sich darauf, dass der Client eine Anforderungsanweisung an den Server sendet, und die Antwort bezieht sich auf die vom Server an den Client zurückgegebenen Informationen.

SMTP ist in zwei Teile unterteilt: Befehlskopf und Nachrichtentext. Der Befehlsheader vervollständigt hauptsächlich die Verbindung zwischen Client und Server, die Überprüfung usw. Der gesamte Vorgang besteht aus mehreren Befehlen
. Nachdem jeder Befehl an den Server gesendet wurde, gibt der Server Antwortinformationen aus, normalerweise einen dreistelligen Antwortcode und einen Antworttext. Die von verschiedenen Servern
zurückgegebenen Antwortcodes entsprechen dem Protokoll, der Antworttext jedoch nicht. Am Ende jedes Befehls und jeder Antwort steht ein Wagenrücklaufzeichen, sodass Befehle und Antworten mit fputs() und fgets() verarbeitet werden können. SMTP-Befehls- und Antwortnachrichten bestehen aus einzelnen Zeilen. Der Nachrichtentext ist der Hauptteil der E-Mail
, und die letzte Schlusszeile sollte ein separates „.“ sein.

Einige häufig verwendete SMTP-Befehle auf dem Client sind:

HELO-Hostname: Begrüßen Sie den Server und teilen Sie dem Client den verwendeten Computernamen mit. Sie können ihn beiläufig eingeben

MAIL FROM: Absender-ID : Weisen Sie den Server an, die Adresse des Empfängers zu senden
RCPT TO: Receiver_ID: Teilen Sie dem Server die Adresse des Empfängers mit
DATA: Der Inhalt des Briefes wird unten übertragen und mit einer speziellen Zeile abgeschlossen enthält nur .
RESET: Den vorherigen Befehl abbrechen und erneut starten. Ende
Die vom Server zurückgegebenen Antwortinformationen lauten (das Format ist: Antwortcode + Leerzeichen + Erklärung):

220 Dienst bereit (diese Informationen werden zurückgegeben, wenn die Socket-Verbindung erfolgreich ist)
221 Verarbeitung

250 Die angeforderte E-Mail-Aktion ist korrekt und abgeschlossen (HELO, MAIL FROM, RCPT TO, diese Informationen werden zurückgegeben, wenn der QUIT-Befehl erfolgreich ausgeführt wird)

354 Beginnen Sie mit dem Senden von Daten und beenden Sie mit (Diese Informationen wird zurückgegeben, wenn der DATA-Befehl erfolgreich ausgeführt wurde, der Client sollte die Informationen senden)
500 Syntaxfehler, Befehl kann nicht erkannt werden
550 Der Befehl kann nicht ausgeführt werden und das Postfach ist ungültig
552 Unterbrechungsverarbeitung: Der Benutzer hat den Dateibereich überschritten
Unten ist ein einfacher Befehlsheader angegeben (dies erfolgt nach dem Öffnen des Sockets). Ich sende eine E-Mail an stmp.263.net. Testergebnisse:

HELO limodou
250 smtp.263.net

MAIL VON: chatme@263.net

250 Ok
RCPT TO: chatme@263.net
250 Ok
DATEN
354 Enddaten mit .
An: chatme@263.net
Betreff: test
Von: chatme@263.net
BEENDEN
250 Ok: in der Warteschlange als C46411C5097E0

 Dies sind einige einfache Kenntnisse über SMTP. Verwandte Inhalte finden Sie im RFC.

RFC 821 definiert verwandte Befehle zum Empfangen/Versenden von E-Mails.
RFC 822 spezifiziert E-Mail?
RFC 2045-2048 spezifiziert Multimedia-E-Mail.

RFC 1113, 1422-1424 diskutiert, wie die Vertraulichkeit von E-Mail-Sex verbessert werden kann.

Implementierung der send_mail-Klasse

Lassen Sie uns nun die von mir geschriebene Klasse zum Senden von E-Mails vorstellen. Mit den oben genannten vorbereitenden Kenntnissen folgt die Umsetzung.

Mitgliedsvariablen der Klasse

var $lastmessage; //Die letzte zurückgegebene Antwortnachricht aufzeichnen

var $lastact; //Die letzte Aktion in Stringform
var $ willkommen ; //Wird hinter HELO verwendet, Benutzer sind willkommen

var $debug; //Ob Debugging-Informationen angezeigt werden sollen

var $smtp; //smtp-Portnummer

var $fp; //socket handle


Darunter werden $lastmessage und $lastact verwendet, um die letzten Antwortinformationen und den ausgeführten Befehl aufzuzeichnen. Wenn ein Fehler auftritt, kann der Benutzer sie verwenden
. Für Testzwecke habe ich auch die Variable $debug definiert. Wenn ihr Wert wahr ist, werden während des laufenden Prozesses einige Ausführungsinformationen angezeigt, andernfalls erfolgt keine
Ausgabe. $fp wird zum Speichern des geöffneten Socket-Handles verwendet.

Klassenaufbau


---------------- ------ ------------------------------------
Funktion send_mail($smtp , $welcome="" , $debug=false)
{
if(empty($smtp)) die("SMTP kann nicht NULL sein!");
$this->smtp=$smtp ;
if( empty($welcome))
{
$this->welcome=gethostbyaddr("localhost");
else
$this->welcome =$welcome;
$this->debug=
$this->lastmessage=""
$this-> ;port="25" ;
}
----------------------------------- ------------ -------------------------------------- -------
Dieser Konstruktor vervollständigt hauptsächlich die Bestimmung und Einstellung einiger Anfangswerte. $welcome wird in der HELO-Direktive verwendet, um dem Server den Namen des Benutzers mitzuteilen.
Der HELO-Befehl erfordert einen Maschinennamen, kann aber auch ohne verwendet werden. Wenn der Benutzer $welcome nicht angibt, wird automatisch nach dem Namen des lokalen Computers gesucht.

Debugging-Informationen anzeigen

------------------------------------------------ - -------------------------------------------

1 Funktion show_debug ($message, $inout)

2 {
3 if ($this->debug)
4 {
5 if($inout=="in") //Antwortinformationen
6 {
7 $m='<< ';
9 else
11 if(!ereg ( "n$", $message))
12 $message .= "
"
13 $message=nl2br($message);
14 echo "";
15 }
16 }
--------------------- ----- --------------------------------------------- ----- ----------
Diese Funktion wird verwendet, um Debugging-Informationen anzuzeigen. Sie können in $inout angeben, ob es sich um eine Upload-Anweisung oder eine zurückgegebene Antwort handelt,
verwenden Sie „out“, wenn es sich um eine zurückgegebene Antwort handelt.

Zeile 3 bestimmt, ob Debugging-Informationen ausgegeben werden.
Bestimmen Sie in Zeile 5, ob es sich um eine Antwortnachricht handelt. Fügen Sie vor den Informationen in Zeile 7 „<<“ hinzu. Andernfalls fügen Sie in Zeile 10 „>>“ hinzu. " um Upload-Anweisungen zu unterscheiden.
Bestimmen Sie in den Zeilen 11 bis 12, ob die letzte Zeile der Informationszeichenfolge ein Zeilenumbruchzeichen ist. Wenn nicht, fügen Sie eine HTML-Zeilenumbruchmarkierung hinzu. Zeile 13 wandelt alle Newline-Zeichen in HTML-

 -Newline-Tags um.

Zeile 14, geben Sie die gesamte Nachricht aus und setzen Sie die Farbe der Nachricht auf Grau, um den Unterschied anzuzeigen.

Befehl ausführen


-------------------------------- ----------------------------------------

1 Funktion do_command($command, $code)

2 {

3 $this->lastact=$command;

4 $this->show_debug($this->lastact, "out ");
5 fputs ( $this->fp, $this->lalastact ); $this->lastmessage, "in");
8 if(!ereg("^$code", $this->lastmessage))
9 {
10 return false; 11 }
12 else
13 return true; ------------------------------------------------ -- --------
Beim Schreiben des Socket-Verarbeitungsteils habe ich festgestellt, dass die Verarbeitung einiger Befehle sehr ähnlich ist, wie z. B. HELO, MAIL FROM, RCPT TO, QUIT und DATA Wenn der zurückgegebene Antwortcode erwartet wird, muss die Verarbeitung unterbrochen werden, je nachdem, ob sie angezeigt werden soll. Aus Gründen der Übersichtlichkeit und Vereinfachung wird daher eine allgemeine Verarbeitungsfunktion speziell für die Verarbeitung dieser Befehle geschrieben.
$code in den Parametern der Funktion ist der erwartete Antwortcode. Wenn der Antwortcode derselbe ist, bedeutet dies, dass die Verarbeitung erfolgreich ist, andernfalls tritt ein Fehler auf.

Zeile 3 zeichnet den zuletzt ausgeführten Befehl auf.
Zeile 4 zeigt den Upload-Befehl an.
Zeile 5 verwendet fputs, um Anweisungen tatsächlich an den Server zu übertragen.
Zeile 6: Die vom Server empfangenen Antwortinformationen werden in die letzte Antwortnachrichtenvariable eingefügt.
Zeile 7 zeigt die Antwortinformationen an.
Zeile 8 bestimmt, ob die Antwortinformationen erwartet werden. Wenn ja, gibt Zeile 13 Erfolg (true) zurück, andernfalls gibt Zeile 10 einen Fehler (false) zurück.

Auf diese Weise vervollständigt diese Funktion einerseits die Funktion des Sendens und Anzeigens von Anweisungen und Informationen und beurteilt andererseits, ob die zurückgegebene Antwort erfolgreich ist.

Verarbeitung des E-Mail-Versands

Das Folgende ist das wahre Geheimnis, aber Sie müssen es sorgfältig lesen. :)

--------------------------------- --------------------------------- 
1 Funktion send( $to,$from,$subject,$ Nachricht) 
2 { 

4 //连接服务器 
5 $this->lastact="connect"; 

7 $this->show_debug("Mit SMTP-Server verbinden: ".$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 sonst 
21 { 
22 $this->lastact="HELO " . $this->willkommen . "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 //发送正文 
44 $this->lastact="DATAn"; 
45 if(!$this->do_command($this->lastact, "354")) 
46 { 
47 fclose($this->fp); 
48 return false; 
49 } 
50 
51 //处理Subject头 
52 $head="Subject: $subjectn"; 
53 if(!empty($subject) && !ereg($head, $message)) 
54 { 
55 $message = $head.$message; 
56 } 
57 
58 //处理From头 
59 $head="From: $fromn"; 
60 if(!empty($from) && !ereg($head, $message)) 
61 { 
62 $message = $head.$message; 
63 } 
64 
65 //处理To头 
66 $head="To: $ton"; 
67 if(!empty($to) && !ereg($head, $message)) 
68 { 
69 $message = $head.$message; 
70 } 
71 
72 //加上结束串 
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="QUITn"; 
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 } 
------------------------------------- ------------------------------------------ 
  有些意思很清楚的我就不说了.

  这个函数一共有四个参数,分别是$to表示收信人,$from表示发信人,$subject表求邮件主题和$message 
表示邮件体。如果处理成功则返回true, 失败则返回false.

Zeile 8, Verbindung zum Mailserver herstellen, bei Erfolg sollte der Antwortcode 220 lauten.
Zeile 12 legt den Blockierungsmodus fest und gibt an, dass die Informationen zurückgegeben werden müssen, bevor fortgefahren werden kann. Detaillierte Anweisungen finden Sie im Handbuch.
Zeile 16: Bestimmen Sie, ob der Antwortcode 220 ist. Wenn ja, fahren Sie mit der Verarbeitung fort, andernfalls wird ein Fehler zurückgegeben.
Zeile 22-27, Verarbeitung des HELO-Befehls, der erwartete Antwortcode ist 250.
Die Zeilen 29–34 verarbeiten die MAIL FROM-Anweisung und der erwartete Antwortcode ist 250.
Zeile 36-41, Verarbeitung der RCPT TO-Anweisung, der erwartete Antwortcode ist 250.
Die Zeilen 44–49 verarbeiten den DATA-Befehl und der erwartete Antwortcode ist 354.
Zeilen 51–76: E-Mail-Text generieren und versenden.
Zeilen 52–56: Wenn $subject nicht leer ist, prüfen Sie, ob der E-Mail-Text einen Betreffteil enthält, und wenn nicht, fügen Sie den Betreffteil hinzu.
Zeilen 59-63: Wenn $from nicht leer ist, prüfen Sie, ob der E-Mail-Text einen Absenderteil enthält. Wenn nicht, fügen Sie den Absenderteil hinzu.
Zeilen 66-70: Wenn $to nicht leer ist, prüfen Sie, ob ein Empfängerteil im E-Mail-Text vorhanden ist. Wenn nicht, fügen Sie den Empfängerteil hinzu.
Überprüfen Sie in den Zeilen 73–74, ob der E-Mail-Text eine Endzeile hat. Wenn nicht, fügen Sie die Endzeile des E-Mail-Texts hinzu (mit „.“ als Sonderzeile als separate Zeile).
Zeile 76, E-Mail-Text senden.
Zeilen 78–83 führen QUIT aus, um die Verbindung mit dem Server zu beenden. Der erwartete Antwortcode ist 250.
Zeile 85 gibt das Verarbeitungserfolgsflag (true) zurück.
Zeilen 81-91, Verarbeitung einer fehlgeschlagenen Verbindung zum Server.

Das Obige ist die Implementierung der gesamten send_mail-Klasse, die nicht schwierig sein sollte. Nachfolgend finden Sie ein Beispiel.

Beispiel für den E-Mail-Versand
Geben wir zunächst das einfachste Beispiel:
----------------------------------------- -------------------------------------------------- ----
1 include "sendmail.class.php3";
2 $email="Hallo, das ist ein Testbrief!"; ("smtp.263.net", "limodou", true); //Zeige die Debugging-Informationen an
4 if($sendmail->send("chatme@263.net", "chatme@263.net" , "test", $email))
5 {
6 echo "Erfolgreich gesendet!
";
8 else
9 {
10 echo " Senden fehlgeschlagen!
";
11 }
?>
-------------------------- - ------------------------------------------------- - --
Zeile 1, lädt die send_mail-Klasse.
Zeile 3, erstellen Sie eine Instanz der Klasse und legen Sie die Anzeigeinformationen fest. Wenn Sie sie nicht anzeigen möchten, können Sie
$sendmail=new send_mail("smtp.263.net");.
Zeile 4, E-Mail senden.

Ziemlich einfach, nicht wahr? Als Nächstes geben wir ein Beispiel für das Senden eines HTML-Anhangs basierend auf dem vorherigen Beispiel für das Senden einer MIME-E-Mail.


---------------- ------ ------------------------------------


include „MIME.class.php3“

//Hinweis: Im Artikel über das Versenden von MIME-E-Mails heißt diese Klassendatei MIME.class. Hier habe ich sie in etwa so geändert:


$to = 'chatme @263.net'; //Geändert in die E-Mail-Adresse des Empfängers

$str = "Newsletter für ".date('M Y', time());


//Die Informationen wurden von mir geändert

$html_data = '' ' ="#ffffff">

Das ist ein Test
';

//Generiere eine MIME-Klasseninstanz
$mime = new MIME_mail(" chatme@263.net", $to, $str);

//HTML-Anhang hinzufügen

$mime->attach($html_data, "", HTML, BASE64);

//Kommentieren Sie es aus und nutzen Sie meine E-Mail-Versandverarbeitung

//$mime->send_mail();

//E-Mail generieren

$mime-> ;gen_email();

//E-Mail-Informationen anzeigen

//echo $mime->email."
";

//Sendmail-Datei einschließen

include "sendmail.class. php3";

//Instanz erstellen

$sendmail=new send_mail("smtp.263.net", "limodou", true);

/ /Mail senden

$sendmail->send("chatme@263.net", "chatme@263.net", $str, $mime->email);

?>


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!