Eine Mailadresse prüfen, dass muss jeder Entwickler mal in seinem Code machen. Dass dabei eine Menge schief gehen kann, davon kann sicherlich jeder PHP-Programmierer ein Lied singen. Gemacht werden muss es aber, nur wie? Ich stelle die PHP eigene Funktion filter_var() gegen die Filterfunktion des Zend Frameworks und schaue mal, welche der beiden Lösungen denn „Praxistaugliche“ Antworten erzeugt.
Für die PHP eigenen Funktionen lasse ich filter_var mit Filteroption FILTER_VALIDATE_EMAIL antreten. Zur einfachen Übersicht baue ich eine Funktion „isEMailValid“. Diese soll bei korrekter Mailadresse true zurückliefern, ansonsten false; also eher trivial.
function isEMailValid($mail)
{
return (filter_var($mail, FILTER_VALIDATE_EMAIL) !== FALSE);
}
Für die Frameworks tritt das Zend Framework an und speziell dessen Zend_Validate_EmailAddress Klasse. Diese besitzt eine Funktion isValid, die das gleiche Verhalten zeigt wie unsere eigene „isEMailValid“ Funktion.
Als Beispiel gebe ich 4 ähnliche Mailadressen an, nur die erste ist eine „echte“ Mailadresse, bei allen anderen fehlt was bzw. ist ein Teil unvollständig. Sicherlich prüft das ganze nicht alle möglichen Fälle von Mailadressen ab, aber es zeigt einen (sinngemäßen) Fall, der mir Probleme bereitete und mich nun zum Wechsel von meiner „filter_var plus regex“-Methode zum ZendFramework bewegen konnte.
function isEMailValid($mail)
{
return (filter_var($mail, FILTER_VALIDATE_EMAIL) !== FALSE);
}
$mail1 = 'max.muster-mann@eine.beispieldomain.com';
$mail2 = 'max.muster-mann@com';
$mail3 = 'max.muster-mann eine.beispieldomain.com';
$mail4 = 'max.muster-manneine.beispieldomain.com';
printf('php-filter:'."\n");
var_dump(isEMailValid($mail1));
var_dump(isEMailValid($mail2));
var_dump(isEMailValid($mail3));
var_dump(isEMailValid($mail4));
printf('zend:'."\n");
require_once 'Zend/Validate.php';
require_once 'Zend/Validate/EmailAddress.php';
$mailvalidator = new Zend_Validate_EmailAddress();
var_dump($mailvalidator->isValid($mail1));
var_dump($mailvalidator->isValid($mail2));
var_dump($mailvalidator->isValid($mail3));
var_dump($mailvalidator->isValid($mail4));
Die Ausgabe:
php-filter:
bool(true)
bool(true)
bool(false)
bool(false)
zend:
bool(true)
bool(false)
bool(false)
bool(false)
Wie man sieht, die „normale“ filter_var() Funktion von PHP schlägt fehl und meldet die zweite Mailadresse als korrekt, was nicht richtig ist.
Allein das zeigt mir nun, dass ich mich auf die Ergebnisse der PHP eigenen Prüfung nicht verlassen kann. Ich werde das ganze weiterhin beobachten, allerdings wird das nächste Projekt dann Funktionen aus dem Zend Framework benutzen. Das schöne ist, dass ich nur einmal in meiner Prüfungsmethode meiner Validatorklasse die Prüfung ändern muss, damit Projektweit die „richtige“ Prüfung benutzt wird. OOP ist toll 😉
PHP-Version: 5.2.13
Nachtrag vom 24.09.2010
Die ersten 5 Kommentare brachten mich auf andere Wege und zu mehr „Erkentnis“ des ganzen. Danke an IchBinIch und SkaveRat für die Hinweise!
Nimmt man noch ein paar andere Abwandlungen der Mailadressen zeigt sich ein Bild, dass man erklären sollte, denn filter_var und Zend arbeiten anscheinend völlig unterschiedlich. Oder doch nicht?
Was soll man nun benutzen? filter_var oder doch die Zend-Funktionen?
Die Antwortet lautet: Es kommt drauf an!
Je nachdem, was man mit der Prüfung erreichen will, benötigt man entweder das eine oder das andere. Hier die beiden Möglichkeiten:
- 1. Prüfung für den Mailversand!
Der wohl häufigste Fall. Man möchte wissen, ob eine Mailadresse dazu taugt, etwas per SMTP dort auch hinsenden zu können (Zugangsdaten, Newsletter, …). Hier lautet die Antwort: Zend-Framework, denn das prüft, ob ein String eine versendbare Mailadresse nach RFC 5321 beinhaltet (siehe auch Kommentar 3 von SkaveRat).
- 2. Prüfung, ob es ganz generell eine Mailadresse sein könnte!
Hier ist die Antwort: filter_var, denn diese Funktion prüft die generelle Syntax des Strings, nicht dessen Nutzbarkeit. Dabei können auch Global-Parts wie ‚localhost‘ eingesetzt werden, allerdings werden auch Mailadressen wie ‚a@com‘ durchgelassen, da diese ja theoretisch auch Mailadressen sind.
Man sieht, dass es durchaus auf den Anwendungsfall ankommt, will man sich für eine Filterklasse entscheiden. Ich werde das auf jeden Fall bei der nächsten Prüfung berücksichtigen.