search
subnavi
Werbung

Mail lesen und schreiben

Frage: Was ist SMTP?

Antwort von Kristian Köhntopp:

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.

Frage: Was ist das Domain Name System?

Antwort von Kristian Köhntopp:

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.

Frage: Unix: Wie funktioniert der Mailversand?

Antwort von Kristian Köhntopp:

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); 

Frage: Windows: Wie funktioniert der Mailversand?

Antwort von Kristian Köhntopp:

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.";
  }

?> 

Frage: Windows: Wo finde ich Mailserver, die ich bei mir installieren kann?

Antwort von Kristian Köhntopp:

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.

Frage: Wie kann ich eine HTML-Mail versenden?

Antwort von Kristian Köhntopp:

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); 

Frage: Wie kann ich ein Attachment mit einer Mail versenden?

Antwort von Johannes Frömter:

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.

Frage: Wie kann ich eine Mail effizient an sehr viele Empfänger versenden?

Antwort von Kristian Köhntopp:

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); 

Frage: Wie kann ich die Gültigkeit einer Mailadresse testen?

Antwort von Kristian Köhntopp:

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";
  } 
Antwort von Guido Haeger:

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.

Frage: Wie kann ich überprüfen, ob eine versendete Mail tatsächlich angekommen ist?

Antwort von Kristian Köhntopp:

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.

Frage: Wie kann ich feststellen, ob eine Mailadresse äußerlich gültig ist?

Antwort von Kerry W. Lothrop:

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.

Frage: Wie versende ich SMS mit PHP?

Antwort von Martin Jansen:

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.

Frage: Wie kann ich den Absender meiner Mail festlegen?

Antwort von Johannes Frömter:

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.