9.4 Net_POP3 

Besprochene Version: 1.3.3 | Lizenz: BSD |
Klassendatei(en): Net/POP3.php |
Das POP3-Protokoll ist das Protokoll, das meist zum Abholen von E-Mails genutzt wird. Auch hierbei handelt es sich um ein Protokoll, das die Datenübertragung nicht verschlüsselt. Das »Post Office Protocol – Version 3« wurde im Mai 1996 veröffentlicht und ist im RFC 1939 [Sie finden den RFC beispielsweise unter http://www.faqs.org/rfcs/rfc1939.html. ] definiert.
Nachdem Sie ein Objekt der Klasse abgeleitet haben, muss eine Verbindung zum Server aufgebaut werden. Die Methode connect() bekommt den Namen des Servers und den Port übergeben, mit dem die Verbindung aufgebaut werden soll. Normalerweise handelt es sich hierbei um den Port 110. Nach dem Verbindungsaufbau erfordert das Protokoll eine Authentifizierung, die mithilfe der Methode login() [In der aktuellen Version 1.3.3 hat die Methode noch einen kleinen Bug, siehe http: //pear.php.net/bugs/bug.php?id=2646. ] vorgenommen wird. Sie bekommt den Benutzernamen und das dazugehörige Passwort im Klartext übergeben und ermittelt dann selbstständig, welches das beste Authentifizierungsverfahren ist.
Wurde eine Verbindung mit der Mailbox erfolgreich aufgebaut, können Sie Mails oder Teile davon abrufen. Die Kommunikation ist hierbei relativ einfach geregelt. Die Mails liegen einfach durchnummeriert im Postfach. Das heißt, die erste (älteste) Mail im Postfach hat die Nummer eins, die nächste die zwei und so weiter. Dazu müssen Sie natürlich erst einmal herausfinden, wie viele Mails überhaupt in dem Postfach vorhanden sind. Dies können Sie mit der Methode numMsg() auslesen. Üblicherweise arbeiten Webmailer auf der Basis, dass zuerst eine Übersicht der vorhandenen Mails angezeigt wird. Dazu müssen die Header der einzelnen Mails in einer Schleife ausgelesen werden.
include('Net/POP3.php'); // Schrittweite zum Blaettern durch die Nachrichten define ("STEP",10); //Wurde ein Startwert uebergeben? if (true===isset($_GET['start'])) { $start=$_GET["start"]; } else { $start=1; } // Neues Objekt instanziieren $pop3 = new Net_POP3(); // Verbindung zum Server aufbauen $erg=$pop3->connect('pop.netviser.de', 110); if (PEAR::isError($erg)) { echo $erg->getMessage(); } // Am Server anmelden $erg=$pop3->login('user', 'geheim'); if (PEAR::isError($erg)) { echo $erg->getMessage(); } // Anzahl der Nachrichten auslesen $anzahl=$pop3->numMsg(); echo '<table>'; echo '<tr><th>Von</th><th>Betreff</th><th>Datum</th></tr>'; // Schleife zum Auslesen der Mails for ($cnt=$start; $cnt<=(STEP+$start) && $cnt<=$anzahl; $cnt+=1) { echo '<tr>'; $hdrs=$pop3->getParsedHeaders($cnt); echo "<td>$hdrs[From]</td>"; echo "<td><a href=\"anzeigen.php?num=$cnt\" target=\"_blank\"> $hdrs[Subject] </a></td>"; echo "<td>$hdrs[Date]</td>"; echo '</tr>'; } // Zeile zum Vor- und Zurueckblaettern echo '<tr><td>'; if ($start > 1) { echo "<a href=\"$_SERVER[PHP_SELF]?start=".($start-STEP)."\">"; echo "zurück</a>"; } echo "</td><td></td><td>"; if (($start+STEP) < $anzahl ) { echo "<a href=\"$_SERVER[PHP_SELF]?start=".($start+STEP)."\">"; echo "vor</a>"; } echo '</table>';
Listing 9.3 Script für die Oberfläche eines Webmailers
In Listing 9.3 finden Sie ein Script, das eine Übersicht über alle Mails erzeugt, die in einer Mailbox vorhanden sind. Das Script liest immer nur die Header von 10 Mails aus. Die Schrittweite wird durch die Konstante STEP gesteuert. Innerhalb der Schleife, die die Mails ausliest, werden der Absender der jeweiligen Mail, die Betreffzeile und das Datum ausgegeben.
Die Methode getParsedHeaders() liefert die Header für eine Mail in Form eines Arrays zurück. Die Namen der wichtigsten Schlüssel finden Sie in Tabelle 9.2.
Die Information, welche Mail als erste dargestellt werden soll, wird als Query-String weitergereicht. Die Ausgabe des Scripts finden Sie in Abbildung 9.2.
Abbildung 9.2 Oberfläche des Webmailers
Auch wenn es in diesem Screenschot nicht auf Anhieb sichtbar ist, werden Sie feststellen, dass Zeichensatzprobleme nicht unüblich sind. Beim Versand von Mails dürfen nur Zeichen des ASCII-1-Zeichensatzes genutzt werden. Sonderzeichen in den Header-Feldern müssen entsprechend des RFC-1522 [Den kompletten RFC finden Sie unter http://www.faqs.org/rfcs/rfc1522.html. ] kodiert werden. Da ich den RFC nicht komplett erläutern möchte, folgt hier nur das Wichtigste in Kürze. Die kodierten Sonderzeichen müssen also wieder in lesbare Zeichen übersetzt werden. Dazu müssen Sie zuerst feststellen, welcher Zeichensatz in der ursprünglichen Nachricht genutzt wurde. Die kodierten Zeichen müssen dann entsprechend wieder dekodiert werden. Die Funktion decode_string() bekommt ein Header-Feld übergeben und dekodiert es dadurch, dass sie eine Funktion mithilfe von preg_replace_callback() einbindet. Allerdings sind nur Funktionalitäten für die Kodierungen vorgesehen, die am häufigsten genutzt werden (ISO-8859–1 Quoted printable, ISO-8859–1 Binary und UTF-8 Binary).
function iso_quoted($match) { $decoded=str_replace("=","%",$match[1]); $decoded=str_replace("_"," ",$decoded); return urldecode($decoded); } function iso_binary($match) { return base64_decode($match[1]); } function utf_binary($match) { return utf8_decode(base64_decode($match[1])); } // Funktion zum Dekodieren der Sonderzeichen function decode_string ($string) { $decoded=$string; // ISO 8859–1 Quoted printable? if (true==stristr($string,"=?ISO-8859–1?Q?")) { $decoded=preg_replace_callback ("/=\?ISO-8859–1\?Q\?(.+)\?=/iU", "iso_quoted",$string); } // ISO 8859–1 Binary? if (true==stristr($string,"=?ISO-8859–1?B?")) { $decoded=preg_replace_callback ("/=\?ISO-8859–1\?B\?(.+)\?=/iU", "iso_binary",$string); } // UTF-8 Binary? if (true==stristr($string,"=?UTF-8?B?")) { $decoded=preg_replace_callback ("/=\?UTF-8\?B\?(.+)\?=/iU", "utf_binary",$string); } return $decoded; }
Listing 9.4 Funktion zum Dekodieren der Header-Felder
Nachdem Sie einen Überblick über die Mails erzeugt haben, wäre es natürlich noch sinnvoll, sich den Inhalt einer Mail anzeigen zu lassen. Dazu ist im Script schon ein Link auf eine Datei namens anzeigen.php vorgesehen. Die Nummer der gewünschten Mail wird an den Namen der Datei angehängt und steht in der Datei somit im Array $_GET zur Verfügung. Die Datei zum Darstellen der Mail muss dann den Body, also den eigentlichen Inhalt der Mail, abrufen.
include('Net/POP3.php'); $num=$_GET["num"]; // Neues Objekt instanziieren $pop3 = new Net_POP3(); // Verbindung zum Server aufbauen $erg=$pop3->connect('pop.1und1.com', 110); if (PEAR::isError($erg)) { echo $erg->getMessage(); } // Am Server anmelden $erg=$pop3->login('m8110734–1', 'king01'); if (PEAR::isError($erg)) { echo $erg->getMessage(); } // Body der Mail einlesen $body=$pop3->getBody($num); // Entfernen der Zeilenumbrueche $body=preg_replace("/=[\n|\r\n|\n\n]/","",$body); // = durch % ersetzen $body=str_replace("=","%",$body); // Sonderzeichen wieder einfuegen $body=urldecode($body); echo nl2br($body);
Listing 9.5 Auslesen des E-Mail-Bodys
Der Body wird mit der Methode getBody() beim Server abgeholt. Da der E-Mail-Inhalt nach 76 Zeichen umbrochen wird, müssen zuerst die entsprechenden Umbrüche entfernt werden. Danach werden auch hier wieder die Umlaute wiederhergestellt. In diesem Beispiel wird davon ausgegangen, dass es sich um eine reine Text-E-Mail handelt, deren Inhalt nach RFC 1521 [http://www.faqs.org/rfcs/rfc1521.html ] kodiert ist. Auch ist hier noch keine Behandlung von Datei-Anhängen nach RFC 2045 [http://www.faqs.org/rfcs/rfc2045.html ] vorgesehen.
In den meisten Fällen ist es sicher noch üblich, den Empfänger, die Betreffzeile und Ähnliches mit anzuzeigen, wozu es allerdings nötig wäre, den Header der Mail beim Server abzuholen und zu analysieren.
Zu guter Letzt darf nicht unerwähnt bleiben, dass eine Mail, die bereits abgeholt worden ist, nicht automatisch vom Server entfernt wird. Möchten Sie eine Mail löschen, muss das explizit mit der Methode deleteMsg() geschehen. Auch diese Methode bekommt die ID der Nachricht übergeben, die gelöscht werden soll. Gerade vor dem Hintergrund, dass die meisten Mailserver die maximale Anzahl der Mails oder die Größe des Postfachs beschränken, sollten Sie Mails nicht zu lange auf dem Server belassen. In diesem Zusammenhang kann es auch hilfreich sein, auszulesen, wie viel Speicherplatz die vorhandenen E-Mails belegen. Diese Information stellt Ihnen die Methode getSize() zur Verfügung.