Komisch aber war: E-Mails des lokalen Webservers werden manchmal richtig versandt, manchmal aber auch nicht. Warum und wieso war mir noch niemals richtig bewusst. Und ehrlich gesagt war ich auch jedes mal schlicht zu Faul nachzuschauen, warum das so ist. Was mich aber immer schon genervt hat ist die Tatsache, dass die E-Mails, die meine Testumgebung verlassen, nicht wirklich “abfangbar” waren. Bis jetzt. Denn ich habe eine coole Lösung gefunden, sie irgendwo – zur Ansicht bereit – abzulegen.
E-Mails per PHP des Webservers versenden
Beispiel: Im konkreten Fall ist es so, dass ein Kunde eine E-Mail möchte, wenn das im Dashboard festgelegte Datum eines Beitrags in WordPress überschritten wurde. Eine Nachricht, wenn ein Beitrag sozusagen abgelaufen ist. Schön und gut.
In der lokalen Entwicklungsumgebung arbeitet man wohl oder über irgendwann mit wp_mail(). Sie sorgt dafür, dass E-Mails über das WordPress Framework abgeschickt werden können. Die Frage ist nur: wie überprüft man den Code bzw. den Inhalt der E-Mail-Adresse?
Bis jetzt habe ich das immer so gemacht: ich habe in PHPStorm einen Breakpoint gesetzt und dann die Variable mit dem Inhalt angesehen. Was aber, wenn man manchmal keine Breakpoints gesetzt hat? Dann wird wp_mail() einfach aufgerufen und eine E-Mail wird verschickt. Oder auch nicht. Oder aber man muss den Aufruf der entsprechenden Funktion erneut anstoßen. Das ist zusätzliche Arbeit, die sich vermeiden lässt.
E-Mails des lokalen Webservers abfangen
Nach langem stöbern im Internet habe ich dann auch einen passenden Denkanstoß gefunden. Folgendes ist entstanden: ein PHP-Script (richtig gelesen) welches die E-Mails abfängt, in eine Textdatei schreibt und dann noch eine schöne Nachricht im Notification-Center von Mac OS X ausgibt. Somit bekommt man sofort mit, wann eine E-Mail verschickt wurde.
Schritt 1: php.ini modifizieren
Ich verwende MAMP Pro. Hier ist es sehr einfach, die php.ini zu verändert. Man öffnet einfach den Menüpunkt Ablage -> Vorlage editieren -> PHP -> PHP 7.0.0. php.ini.
Danach öffnet sich ein Editor. Dort sucht man sich dann folgende Zeile.
; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). sendmail_path = [...]
In der Regel ist der sendmail_path dann entsprechend “verlinkt”. Das wollen wir ändern.
Nehmen wir an, unser Script liegt später im Pfad /usr/local/bin/sendmail. Dann ändern wir die Zeile wie folgt:
; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). sendmail_path = /usr/local/bin/sendmail
Und das macht man dann mit allen PHP-Versionen so.
Schritt 2: PHP-Sendmail-Script anlegen
Danach öffnet man die Konsole und tippt folgendes ein (wer lieber mit vi arbeitet, kann das natürlich tun):
nano /usr/local/bin/sendmail
Die so geöffnete Datei sollte leer sein (sprich, sie sollte noch nicht existieren). Weil sie noch nicht existiert, wird sie nach dem Speichern neu angelegt.
In die Datei kopiert ihr jetzt folgenden Quelltext:
#!/usr/bin/php <?php # Auslesen des E-Mail Quellcodes $input = file_get_contents( 'php://stdin' ); # Auslesen der Empfänger E-Mail preg_match( '|^To: (.*)|', $input, $matches ); # temporären Dateinamen festlegen $filename = tempnam( '/var/log/phpmail', $matches[1] . '.' ); # Datei schreiben $f = fopen( $filename, 'w' ); $bytes = fwrite( $f, $input ); fclose($f); # Dateiberechtigung korrigieren if($bytes !== false){ chmod( $filename, 0644 ); } # Notification-Center benachrichtigen exec('osascript -e \'display notification "'.$filename.'" with title "PHPMail"\''); # Dateien im Verzeichnis auslesen $files = glob( '/var/log/phpmail*' ); if ( is_array( $files ) && count( $files ) > 0 ) { foreach ( $files as $file ) { # Dateien, die älter als eine Woche sind, löschen if ( filemtime( $file ) < ( time() - 604800 ) ) { unlink( $file ); } } }
Ich habe versucht, im Quellcode alles nötige zu beschreiben, damit hoffentlich jeder nachvollziehen und verstehen kann, was hier abgeht.
Schritt 3: Rechte korrekt setzen
Der MAMP-Webserver läuft bei mir nicht als root sondern als aktuell eingeloggter Benutzer (das ist in der Regel immer “floriansimeth”). Damit sendmail, der über den Webserver aufgerufen wird, die Berechtigung hat, auf das Logverzeichnis zuzugreifen, müssen die Rechte entsprechend angepasst werden:
# Verzeichnis erstellen (Passwort eingeben) sudo mkdir /var/log/phpmail # Benutzerrechte anpassen sudo chown floriansimeth:staff /var/log/phpmail # Dateirechte setzen chmod 755 /var/log/phpmail
Schritt 4: Test
Folgendes Script könnt ihr zu Testzwecken (test.php) nutzen. Dazu einfach in eine WordPress-Installation kopieren:
<?php require "wp-load.php"; wp_mail( 'wtf@ihr-wisst-was-ich-meine.com', 'Testmail', 'Testnachricht' );
Nach dem Abruf von z.B. http://localhost/wordpress/test.php solltet ihr folgende Meldung erhalten:
Die E-Mails findet ihr dann – wie zuvor festgelegt – im Orner /var/log/phpmail. Diesen erreicht über z.B. über den Finder über den Menüpunkt “Gehe zu” -> “Gehe zum Ordner” -> /var/log/phpmail.
Alternativ könnt ihr euch über die Konsole einen Symlink auf dem Desktop erzeugen:
ln -s /var/log/phpmail ~/Desktop/WebserverMails