SMTP ist das Simple Mail Transport Protocol , das Protokoll, das im Internet verwendet wird, um Mail bei einem Mailserver einzuliefern und Mail zwischen zwei Mailservern auszutauschen. SMTP ist ein textorientiertes Protokoll, das auf dem TCP-Port 25 abgewickelt wird. Daher kann man es mit dem Kommando telnet leicht simulieren und debuggen.
kris@valiant:~ > telnet mail 25 Trying 193.102.57.5... Connected to white.koehntopp.de. Escape character is '^]'. 220 white.koehntopp.de ESMTP Sendmail 8.9.3/8.9.3/SuSE Linux 8.9.3-0.1 HELO valiant.koehntopp.de 250 white.koehntopp.de Hello valiant.koehntopp.de [193.102.57.3], [..] MAIL FROM: kris@koehntopp.de 250 kris@koehntopp.de... Sender ok RCPT TO: kris@koehntopp.de 250 kris@koehntopp.de... Recipient ok DATA 354 Enter mail, end with "." on a line by itself From: ab@sen.der To: Mailingliste der Empfaenger <in@vali.de> Subject: Testmail Text der Nachricht . 250 LAA08243 Message accepted for delivery QUIT 221 white.koehntopp.de closing connection Connection closed by foreign host.
Nachdem die Verbindung mit dem empfangenden Mailer hergestellt worden ist, identifiziert sich der absendende Rechner mit dem Kommando HELO . Falls dieser Rechner berechtigt ist, überhaupt Mail einzuliefern, antwortet der empfangende Rechner mit einem Statuscode (hier: 250) und einer Textmeldung.
Der Absender nennt jetzt den tatsächlichen Absender ( MAIL FROM ) und den tatsächlichen Empfänger ( RCPT TO , "Receipt to") der Mail. Nach dem Kommando DATA beginnt die Übertragung der eigentlichen Mailnachricht, die mit einem einfachen Punkt abgeschlossen wird (das Protokoll verlangt, dass Punkte am Anfang einer Zeile, die Teil der Nachricht sind, verdoppelt werden).
Die Absender und Empfänger im Text der Mail sind bedeutungslos und werden vom Mailer nicht weiter ausgewertet: Entscheidend sind sie nur ganz am Anfang, wenn die Mail auf den Weg gebracht wird, ähnlich wie bei einem Brief, der in einen Umschlag getütet wird. Von Bedeutung sind nur die Absender und Empfänger im MAIL FROM und RCPT TO -Dialog. Diese beiden Adressen nennt man Envelope-From und Envelope-To, nach den Anschriften, die außen auf einem Briefumschlag (Envelope) stehen und für die Zustellung wichtig sind.
Dies bewirkt zum Beispiel, dass die Empfänger einer Mailingliste nicht alle in der To: -Zeile des Headers aufgelistet sind: Im To: steht nur der Name der Liste, der Listenroboter (Mailexploder) expandiert diesen Namen jedoch zu einer Liste der Empfänger im Envelope. Der Envelope-From einer Nachricht ist nach der Auslieferung einer Mail in eine Mailbox als From -Header (From-Space im Gegensatz zu From-Doppelpunkt, dem Body-From) ganz am Anfang der Nachricht enthalten. Der Envelope-To ist verschwunden, weil er nicht mehr gebraucht wird - daher ist es nicht möglich, eine einzelne POP3-Mailbox nach dem Download mit Fetchmail oder anderen Werkzeugen korrekt im Hause weiter aufzuteilen: Der tatsächliche Empfänger steht nicht mehr zur Verfügung und die Body-To-Zeilen liefern nur Anhaltspunkte.
Das Domain Name System ist eine verteilte Datenbank, die Namen in Domainform ( ein.wort.mit.punkten.darin ) beliebige getypte textuelle Information zuordnen kann. Man kann dem Domain Name System Fragen stellen, die die Form (name, typ) haben und bekommt dann einen oder mehrere Ressource Records des passenden Typs als Antwort.
Wichtige Ressource-Records sind A- und AAAA-Records, die die IP-Nummern von Rechnern darstellen, A-Records für IPv4-Adressen und AAAA-Records für IPv6-Adressen. Außerdem sind für die Mailzustellung MX-Records besonders wichtig, weil sie den für den Mailempfang zuständigen Rechner bezeichnen. Ebenfalls häufig findet man PTR-Records (Umwandlung von IP-Nummern zurück in Namen) und NS-Records (Finden von zuständigen Nameservern).
Mit Hilfe des Werkzeuges nslookup kann man in Unix und Windows Anfragen an das DNS stellen, außerdem kann man bequemer das Unix-Programm dig verwenden.
Ein Mailer wie das Unix-Programm sendmail richtet sich bei der Mailzustellung nach den MX-Records (MX steht für mail exchanger ) einer Domain.
kris@valiant:~ > nslookup Default Server: nuki.netuse.de Address: 193.98.110.1 > set type=mx > php.net. Server: nuki.netuse.de Address: 193.98.110.1 Non-authoritative answer: php.net mail exchanger = 10 synacor1.php.net. Authoritative answers can be found from: php.net nameserver = ns2.easydns.com. php.net nameserver = remote1.easydns.com. php.net nameserver = remote2.easydns.com. php.net nameserver = ns1.easydns.com. synacor1.php.net internet address = 208.210.50.162 ns1.easydns.com internet address = 216.220.40.243 ns2.easydns.com internet address = 216.220.40.244 remote1.easydns.com internet address = 64.39.29.212 > ^D kris@valiant:~ > kris@valiant:~ > dig php.net mx ; <<>> DiG 9.1.3 <<>> php.net mx ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 864 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 4 ;; QUESTION SECTION: ;php.net. IN MX ;; ANSWER SECTION: php.net. 21358 IN MX 10 synacor1.php.net. ;; AUTHORITY SECTION: php.net. 21358 IN NS ns2.easydns.com. php.net. 21358 IN NS remote1.easydns.com. php.net. 21358 IN NS remote2.easydns.com. php.net. 21358 IN NS ns1.easydns.com. ;; ADDITIONAL SECTION: synacor1.php.net. 21358 IN A 208.210.50.162 ns1.easydns.com. 140984 IN A 216.220.40.243 ns2.easydns.com. 140984 IN A 216.220.40.244 remote1.easydns.com. 140984 IN A 64.39.29.212 ;; Query time: 23 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Wed Apr 24 19:09:47 2002 ;; MSG SIZE rcvd: 205
Im Beispiel mit nslookup , das so unter Unix und unter Windows NT funktioniert, kann man sehen, dass der lokale Domain Name Server als Datenquelle verwendet wird. Durch das Kommando set type=mx legen wir fest, dass wir Informationen über MX-Records haben möchten. Durch einfaches Eingeben eines Namens (hier: php.net ) wird die Anfrage abgesendet und wir erhalten zwei Sorten von Informationen:
Der lokale Server hat uns die nicht-abschließende Information geliefert, dass Mail an php.net an den Rechner synacor1.php.net ausgeliefert werden soll. Wenn wir also eine Mailzustellung an eine Adresse der Form bla@php.net vornehmen sollen, müssen wir uns mit synacor1.php.net , Port 25 verbinden und die Mail dort abliefern.
Diese Information ist jedoch nicht-abschließend, weil der lokale Nameserver nicht Eigentümer der Domain php.net ist. Wenn wir abschließende Information wünschen, müßten wir uns an einen der vier definitiven Nameserver für die Domain wenden, die uns genannt werden: ns1.easydns.com , ns2.easydns.com , remote1.easydns.com oder remote2.easydns.com und die Frage dort noch einmal stellen. Die Adressen dieser Server werden uns auch gleich mitgeliefert.
Die Ausgabe von dig liefert diese Information noch einmal, nur in besser lesbarer und übersichtlicherer Form.
Ein Unix-System hat in der Regel ein Mailprogramm installiert, das Anfragen an das DNS-System stellen kann oder auf andere Weise die zur Auslieferung der Mail benötigten Informationen beschaffen kann. In den meisten Fällen ist dieses Mailprogramm /usr/lib/sendmail (oder /usr/sbin/sendmail ) und versteht eine Option -t , die bewirkt, dass man das Programm starten und eine Mail mit allen benötigten Headern auf der Standardeingabe hinterlassen kann. Das Programm wird dann auf der Basis der erhaltenen Headerinformationen den Envelope generieren, den Header vervollständigen und ggf. korrigieren, bevor die Mail dann abgesendet wird.
Der einfachste Weg, um ein Programm zu starten und dann seine Standardeingabe mit Daten zu füllen, ist die C-Funktion popen() . Die PHP-Funktion mail() verwendet diese C-Funktion, um das durch die Konfigurationsvariable sendmail_path definierte Mailprogramm zu starten und mit den benötigten Daten zu füttern.
mail("em@pfaeng.er",
"Testmail",
"Dies ist nur eine Testnachricht.",
"From: ab@send.er\r\nReply-To: devnull@send.er");
Hinweis: In vielen Versionen von PHP unter Windows funktioniert die Variante von mail() mit drei Parametern wegen eines Fehlers im Interpreter nicht. In diesem Fall ist die Funktion mail() zwingend mit vier Parametern aufzurufen, etwa indem als vierter Parameter der Wert Content-Type: text/plain; charset=iso-8859-1 angegeben wird.
Alternativ kann man diese Funktionalität auch manuell in PHP nachprogrammieren, also die PHP-Funktion popen() aufrufen und die Mail dann ausgeben. Beide Ansätze sind funktional gleich (aber mail() ist weniger Arbeit).
$fd = popen("/usr/sbin/sendmail -t ","w");
fputs($fd, "To: em@pfaeng.er\r\n");
fputs($fd, "From: ab@send.er\r\n");
fputs($fd, "Reply-To: devnull@send.er\r\n");
fputs($fd, "Subject: Testmail\r\n\r\n");
fputs($fd, "Das ist nur eine Testnachricht.\r\n");
pclose($fd);
In Windows kann man nicht davon ausgehen, dass wie in Unix ein Mailer installiert ist, der Mail selber zustellen kann. Daher muss man dem Windows-System einen Rechner mitteilen, der einen Mailer installiert hat, den das Windows-System über TCP/IP mitbenutzen darf. Das kann der lokale Rechner localhost sein, falls auf dem eigenen System ein Mailserver installiert ist, aber auch jedes andere System, das für uns seinen Relay- und Spamschutz abgeschaltet hat.
Die Funktion mail() baut unter Windows eine TCP/IP-Verbindung zum Port 25 dieses in der Konfigurationsvariable SMTP festgelegten Systems auf und erzeugt mit dem oben gezeigten SMTP-Dialog eine Mail. Dabei wird die in der Konfigurationsvariablen sendmail_from festgelegte Absenderadresse verwendet.
Anders als in Unix hat man hier also nicht die Freiheit, den Absender oder Blindkopienempfänger in der Mailfunktion frei definieren zu können, weil der entfernte Mailer diese Daten von uns nicht annimmt oder bei der späteren Headerkorrektur wieder überschreibt.
Alternativ kann man die Arbeit der Mailfunktion auch manuell nachprogrammieren - dabei sollte man jedoch bedenken, dass ein SMTP-Server nicht jede Headerzeile so annimmt oder unverfälscht durchläßt, wie man sie ihm vorwirft! Der hier gezeigte Code ist sehr unzuverlässig, denn er hat keine richtige Fehlerprüfung.
$hdr = "From: ab@send.er\r\n";
$hdr .= "To: em@pfaeng.er\r\n";
$hdr .= "Reply-To: devnull@send.er\r\n";
$hdr .= "Subject: Testmail\r\n";
$hdr .= "\r\n";
# Socket oeffnen.
$fp = fsockopen("mail.server.de", 25);
$result = fgets($fp, 1024);
if ($result+0 != 220)
die("Statuscode falsch (service not ready?): $result");
# HELO
fputs($fp, "HELO mein.eigener.servername.de\r\n");
$result = fgets($fp, 1024);
if ($result+0 != 250)
die("HELO Statuscode falsch: $result");
# MAIL FROM
fputs($fp, "MAIL FROM: ab@send.er\r\n");
$result = fgets($fp, 1024);
if ($result+0 != 250)
die("MAIL FROM Statuscode falsch: $result");
# RCPT TO
fputs($fp, "RCPT TO: em@pfaeng.er\r\n");
$result = fgets($fp, 1024);
if ($result+0 != 250)
die("RCPT TO: Statuscode falsch: $result");
# DATA
fputs($fp, "DATA\r\n");
$result = fgets($fp, 1024);
if ($result+0 != 354)
die("DATA: Statuscode falsch: $result");
# Header senden
fputs($fp, $hdr);
# Text senden
fputs($fp, "Das ist nur eine Testnachricht.");
# Ende von DATA: CRLF . CRLF
fputs($fp, "\r\n.\r\n");
$result = fgets($fp, 1024);
if ($result+0 != 250)
die("DATA(end): Statuscode falsch: $result");
# QUIT
fputs($fp, "QUIT\r\n");
$result = fgets($fp, 1024);
if ($result+0 != 221)
die("QUIT: Statuscode falsch: $result");
# Verbindung schließen
fclose($fp);
Wer sich diesen Code nicht zutraut, kann auch die SMTP Klasse von Manuel Lemos verwenden. Sie verbirgt das manuelle Senden der Daten über den Socket gegenüber dem Programmierer und erzeugt auch Fehlermeldungen, wenn mal etwas nicht klappte. Beispiel:
<?php
/* Funktionsklasse inkludieren. */
include "smtp.php";
$smtp = new smtp_class;
$smtp->host_name=getenv("HOSTNAME");
$smtp->localhost="localhost";
$from = "name@".$smtp->host_name;
$to = "da@irgendwo.de";
$inhalt = "Inhalt der Mail";
if ($smtp->SendMessage(
$from,
array($to),
array("From: $from","To: $to","Subject: test"),
$inhalt))
{
print "Mail wurde erfolgreich versandt.";
}
?>
Wenn man in Windows keinen eigenen Mailserver hat, den man zum Mailversand nutzen kann, muss man sich einen installieren. Die folgenden Produkte wurden in der Newsgroups zu diesem Zweck genannt:
Im Prinzip kann man auch den Mailserver des Providers benutzen; hierzu ist in der php.ini im Abschnitt [mail function] bei SMTP der SMTP-Server des Providers und bei sendmail_from die eigene EMail-Adresse bei diesem Provider anzugeben. Allerdings kann es hier wegen SMTP-after-POP oder gesichertem SMTP (SMTP-AUTH-Login) Probleme geben.
Die Mailfunktion in PHP hat einen optionalen vierten Parameter, mit dem man zusätzliche Headerzeilen definieren kann. Diese Headerzeilen können den MIME-Type einer Mail bestimmen, den Absender der Mail festlegen oder auch beliebige Nicht-Standard-Header ( X-Mailer: etc.) enthalten.
$message = "<h1>Hello world!<h1>";
$to = "empfaenger@system.de";
$subject = "Betrefftext";
$xtra = "From: ab@sender.de (Ab Sender)\r\n";
$xtra .= "Content-Type: text/html\r\nContent-Transfer-Encoding: 8bit\r\n";
$xtra .= "X-Mailer: PHP ". phpversion();
mail($to,
$subject,
$message,
$xtra);
Bei der mail() -Funktion von PHP kann man im vierten Argument jeden beliebigen zusätzlichen Header angeben. Attachments werden MIME-kodiert. Eine HTML Mime Mail class kapselt diese Funktionalität und macht die ganze Geschichte recht einfach. Unter der genannten URL finden sich auch Anwendungsbeispiele.
Am günstigsten und sichersten versendet man Mail an viele Empfänger, indem man eine spezialisierte Software dafür verwendet. Empfehlenswert sind Mailinglisten-Server wie majordomo , ezmlm oder Ecartis .
Alternativ kann man sich mit einer deutlich primitiveren Lösung in PHP behelfen, indem man gemäß den Beispielen oben zusätzliche Headerzeilen mit Bcc -Empfängern erzeugt. Auf diese Weise generiert man eine einzelne Mail an viele Empfänger, die vom Mailer sehr effizient verteilt werden kann. Gleichzeitig vermeidet man durch die Verwendung von blind carbon copy (BCC)-Empfängern, dass die Empfänger im Kopf der Mail mit aufgeführt werden und auf diese Weise ein Monsterheader entsteht.
# Empfaengerliste
$empfaenger = array("a@example.com", "b@example.com");
# Bcc generieren
foreach ($empfaenger as $k => $v) {
$bcc .= "Bcc: $v\r\n";
}
mail("em@pfaeng.er",
"Testmail",
"Dies ist nur eine Testnachricht.",
$bcc);
Der Mailer eines Systems kann die Mail dann zustellen, wenn das Domain Name System (DNS) für die Zieladresse einen Mail Exchanger (MX) Ressource Record (RR) oder einen Address (A) Ressource Record enthält. Wenn man testen möchte, ob die Empfängeradresse für eine Mail gültig ist, braucht man Zugriff auf das Internet und einen DNS-Server, den man befragen kann. Dann kann man die Anfrage, die der Mailer später einmal stellen wird, um die Mail zuzustellen, manuell mit Hilfe der Funktion checkdnsrr() nachvollziehen. Die Funktion liefert true , wenn ein passender RR vorhanden ist.
Eine DNS-Anfrage kann je nach Verfügbarkeit des DNS-Systems bis zu mehreren Minuten dauern. Der betreffende Webserverprozeß ist in diesem Zeitraum blockiert. Das Vorhandensein der benötigten RRs garantiert natürlich nicht, dass das Zielsystem auch mit uns redet oder dass der gewünschte Benutzer existiert und Mail empfangen kann. Die einzige Methode, zuverlässig zu testen, ob eine Mail zustellbar ist, ist sie zuzustellen.
$addr = "user@host.doma.in";
list($user, $host) = explode("@", $addr);
if (checkdnsrr($host, "MX") or checkdnsrr($host, "A")) {
print "Mail ist vielleicht zustellbar.<BR>\n";
} else {
print "Mail ist sicher nicht zustellbar.<BR>\n";
}
Im SIMPLE MAIL TRANSFER PROTOCOL (SMTP - RFC 0821 ) ist das Kommando VERIFY (VRFY) definiert. Hat man die Mailadresse "demouser@domain.tld" dann kann man theoretisch mittels "VERIFY demouser" beim für "domain.tld" zuständigen SMTP-Server anfragen, ob ein Postfach für "demouser" existiert. In der Praxis ist dieses Kommando aber bei fast allen SMTP-Servern deaktiviert, bzw. überhaupt nicht implementiert (Spam-/Datenschutz), so dass VERIFY keine praktikable Lösung ist.
Manche Mailer unterstützen Delivery Status Notification (DSN) nach RFC 1894 . Dies ist ein RFC auf der Internet Standards Track im Status proposed standard , er wird also in veränderter Form einmal Draft Standard und dann Internet Standard werden. Relevant im selben Zusammenhang ist die ganze Reihe der RFCs in diesem Bereich:
RFC 1891 ( SMTP Service Extension for Delivery Status Notifications )
RFC 1892 ( The Multipart/Report Content Type for the Reporting of Mail System Administrative Messages )
RFC 1893 ( Enhanced Mail System Status Codes )
und der bereits genannte RFC 1894 ( An Extensible Message Format for Delivery Status Notifications )
Die Anforderung von DSNs erfolgt mit Hilfe der in RFC 1891 beschriebenen SMTP Service Extension, ist also Bestandteil des SMTP Dialoges.
Auf Unix-Systemen wird der SMTP-Dialog durch das lokal installierte sendmail -Programm abgewickelt. Dieses versteht bestimmte Optionen ( -N und -R , die in der Manualpage von sendmail beschrieben sind), mit deren Hilfe DSNs angefordert werden können. Die Option -N <reportklasse> legt fest, für welche Fälle DSNs erzeugt werden sollen. Es können mehrere Reportklassen durch Komma getrennt spezifiziert werden: failure , wenn eine Benachrichtigung bei Zustellproblemen erzeugt werden soll, delay für eine Benachrichtigung bei Zustellverzögerungen und success , für Nachricht, wenn die Zustellung erfolgreich war. Mit der Zustellbenachrichtigung wird zugleich ein Teil der Originalnachricht zurück übermittelt, damit der Absender feststellen kann, auf welche Nachricht sich die Zustellbenachrichtigung bezieht. Die Option -R <return> legt fest, wieviel von der Originalnachricht zurück übermittelt werden soll: hdrs übermittelt nur die Headerzeilen der Originalnachricht zurück, während full die komplette Originalnachricht in der Zustellbenachrichtigung zurückgibt.
Auf Unix-Systemen kann man also DSNs anfordern, wenn man einen ausreichend neuen Sendmail (8.8.x oder besser) installiert hat und man die Konfigurationsvariable sendmail_path passend setzt:
sendmail_path = /usr/lib/sendmail -N failure,success -R hdrs -t
Auf Windows-Systemen wickelt PHP den SMTP-Dialog mit einem entfernten SMTP-Mailer ab. Es sind keine Eingriffsmöglichkeiten vorgesehen, mit deren Hilfe man den SMTP-Dialog erweitern kann. Entscheidet man sich, den SMTP-Dialog manuell abzuwickeln, damit man die SMTP-Erweiterungen gemäß RFC 1891 implementieren kann, ist unbedingt darauf zu achten, dass man das Vorhandensein dieser Erweiterungen im EHLO -Kommando des SMTP-Dialoges richtig abfragt, sonst schlägt die Mailzustellung fehl, wenn man auf einem Mailer einliefert, der kein DSN kann.
Das Resultat von aktivierten DSNs sind Nachrichten mit dem Mime-Typ multipart/report wie in RFC 1892 und RFC 1894 spezifiziert. Diese Nachrichten enthalten mindestens zwei, meist jedoch drei Teile, von denen einer message/delivery-status ist und eine maschinenlesbare DSN nach RFC 1894 enthält. Mit Hilfe eines POP3 oder IMAP-Clients kann man diese Nachrichten einsammeln und analysieren.
Im PEAR-Repository gibt es die Klasse Mail_RFC822 , die überprüfen kann, ob eine Adresse RFC-822-konform ist.
Ein einfacher regulärer Ausdruck reicht zur Prüfung nicht aus, da RFC822-Mailadressen eine relativ komplexe Syntax haben können. Die meisten Prüfungen auf der Basis einer einfachen Regexp lehnen viele legale Adressen ab (Es existieren zum Beispiel inzwischen gültige Toplevel-Domains mit mehr als 3 Buchstaben) und lassen zugleich ungültige Adressen zu.
Generell muss man bei der Verwendung von SMS zwei Arten unterscheiden:
Auf der einen Seite gibt es die Möglichkeit, eine SMS an eine vorher definierte Rufnummer (z.B. die des eigenen Handys) zu senden.
Die zweite Möglichkeit, die sehr häufig von Portalseiten (z.B. Lycos) genutzt wird, ist, dem Besucher der Seite die Möglichkeit zu geben, an eine Rufnummer seiner Wahl eine SMS zu senden. Diese SMS enthalten allerdings in der Regel einen kurzen Werbetext.
Variante 1 lässt sich mit der mail() -Funktion von PHP realisieren: Jeder Netzanbieter stellt jedem seiner Kunden auf Nachfrage eine eigene E-Mail-Adresse (z.B. <rufnummer>@smsmail.eplus.de) zur Verfügung. Nachrichten an diese E-Mail-Adresse werden als SMS an den Mobilfunkaccount des Kunden weitergeleitet. Dieser Service kostet je nach Anbieter einen gewissenen Betrag pro SMS. So würde zum Beispiel folgendes Skript eine SMS an die Nummer 0177-1234567 senden:
<?php
$subject = "Hello World";
$text = "Just another PHP hacker";
mail("491771234567@smsmail.eplus.de",$subject,$text,"From: sms-service@send.er");
?>
Mit dieser Variante lässt sich auf einfache Weise der Versand von SMS an eine vorher definierte Nummer (i.d.R. die eigene) realisieren. Ein Risiko, das man nicht unterschätzen sollte, ist die Gefahr des Missbrauchs: Ein böswilliger User sendet zum Beispiel 100 SMS in Folge und verursacht somit beim Empfänger auf einen Schlag beträchtliche Kosten. Hier müssen entsprechende Sicherheitsmechanismen wie zum Beispiel ein Limit an SMS pro IP oder Cookies ansetzen, die aber alle keine 100%-ige Sicherheit garantieren.
Die zweite Möglichkeit verwendet ein vollwertiges SMS-Gateway, um den Versand von SMS an beliebige Nummern zu realiseren.
Das SMS-Gateway ist entweder lokal auf dem eigenen Server installiert oder man verwendet einen Fremdanbieter, der eine SMS-Gateway zu entsprechenden Konditionen zur Verfügung stellt.
Nachrichten, die über die SMS-Gateway versendet werden sollen, werden nach dem gleichen Prinzip wie Variante 1 mit der PHP-Funktion mail() versendet. Der Unterschied besteht darin, dass neben dem Text der SMS auch entsprechende Steuersignale im E-Mail-Text enthalten sind, die für die SMS-Gateway die entsprechenden Informationen liefern, wohin die SMS gesendet werden soll. Bei der Verwendung eines Fremdanbieters sind des weiteren die nötigen Authentifizierungsdaten in der E-Mail enthalten, die den SMS-Versand ermöglichen.
Selbstverständlich birgt auch diese Variante die Möglichkeit des Missbrauchs, weshalb auch hier die gleichen Sicherheitsmechanismen wie bei Variante 1 angewendet werden müssen. Die meisten der grossen Anbieter von kostenlosem SMS-Versand reduzieren so zum Beispiel die Anzahl Nachrichten, die pro IP gesendet werden dürfen, auf eine gewisse Anzahl pro Tag.
Um im Mailprogramm des Empfängers einen bestimmten Absender anzuzeigen, muss in der Mail der From: -Header entsprechend gesetzt sein. Die Funktion mail() nimmt im vierten Parameter solche Header-Angaben entgegen:
mail("empfaenger@example.org",
"Betrefftext",
"Hello world!",
"From: Absender <absender@example.com>");
Eine Mailadresse mit Namen gibt man am besten in der Form Name <Adresse> an. Weitere Headerzeilen sind durch \r\n zu trennen.
Durch diesen Header wird nur der Absender in der Mail, nicht jedoch der Envelope-From: - quasi die Absenderangabe auf dem "Briefumschlag" der Mail - festgelegt. Nicht zustellbare Mails gehen daher an den Serveradministrator, und nicht an den tatsächlichen Absender zurück.
Seit PHP Version 4.0.5 kennt mail() hierzu einen fünften Parameter, dessen Inhalt direkt an das Mailprogramm weitergereicht wird. Im Falle des üblichen sendmail übergibt man den Absender für das Envelope-From: folgendermaßen:
mail("empfaenger@example.org",
"Betrefftext",
"Hello world!",
"From: Absender <absender@example.com>",
"-f absender@example.com");
Normalerweise fügt sendmail dann auch ein X-Authentication-Warning in den Header ein; um diese Warnung zu unterdrücken, sollte man den User, unter dessen Account der Webserver läuft, zu den "trusted users" in der sendmail-Konfiguration hinzufügen.