Ich habe eine Klasse, die jede Eingabe validiert, bevor ich sie an die Datenbankschicht sende. Beachten Sie, dass es bei meinem Problem nicht darum geht, zu entkommen oder so etwas. Meine Datenbankschicht behandelt das SQL-Injection-Problem. Ich möchte nur überprüfen, ob die E-Mail gültig ist oder nicht, da diese E-Mail später als „Senden an“ verwendet werden könnte. Beispielsweise erhält der Benutzer den Zugriff auf sein Konto über einen Link, der an die E-Mail gesendet wird. Ich lese viel darüber filter_var
und es gibt eine Menge Leute, die dagegen sind, und andere, die dafür sind. Wenn Sie den Fokus auf „Ich möchte nur E-Mails validieren und sie nicht nach Datenbank oder HTML oder XSS oder was auch immer filtern“ halten, gibt es ein Problem bei der Verwendung filter_var
?
Sollte ich filter_var verwenden, um E-Mails zu validieren?
Ja du solltest.
Die Verwendung der Standard-Bibliotheksvalidierung anstelle eines selbstgebrauten Produkts hat mehrere Vorteile:
- Viele Augäpfel haben bereits den Code (naja, mindestens zwei) gesehen, den Sie verwenden werden, hoffentlich mit Erfahrung in der E-Mail-Validierung, noch bevor er in eine Version eingebunden wird.
- Es ist Einheit getestet.
- Andere Leute verwenden die gleiche Prüfung und Fehler melden und Sie erhalten diese Korrekturen kostenlos bei PHP-Updates.
Das Überprüfen des Formats einer E-Mail-Adresse ist jedoch nur die erste Verteidigungslinie. Wenn Sie wirklich wissen wollen, ob es echt ist oder nicht, müssen Sie eine Nachricht an sie senden.
-
Leider gilt dies nur, wenn jemand eine solche Validierungsbibliothek tatsächlich pflegt und weiter verbessert. In diesem Fall mit
filter_var
hat einige Gefahren: UTF8 wird im lokalen Teil nicht unterstützt, obwohl dies schon seit geraumer Zeit gültig ist, und Sie müssen den Domänennamen tatsächlich mit konvertierenidn_to_ascii
Sie selbst internationale Domainnamen validieren, was nicht offensichtlich ist. Bereiten Sie sich auf viele fehlerhafte E-Mail-Adressen vor, die tatsächlich gültig sind, wenn Sie sie verwendenfilter_var
und dies wird nur noch viel schlimmer, wenn Unicode in E-Mail-Adressen häufiger verwendet wird.– Iquito
19. Mai 2016 um 17:54 Uhr
absfrm
Ja, sollten Sie verwenden filter_var
und so kannst du es einbauen:
if( filter_var( $email ,FILTER_VALIDATE_EMAIL ) )
{
/*
* Rest of your code
*/
}
Richplane
Ja. Aber checkdnsrr()
kann hier auch eine Erwähnung wert sein.
filter_var()
genehmigt Domänen, die unvollständig erscheinen, da sie in einem lokalen Kontext gültig sein könnten (z. B. [email protected]). Dies kann zu Fehlalarmen führen, bei denen Leute einfach die TLD oder den Punkt im Domainnamen übersehen (z. B. [email protected]).
Fangen Sie diese, indem Sie a checkdnsrr()
Suchen Sie in der Domain nach – wenn Sie einen MX-Eintrag für die Domain finden können und die Adresse gültig ist, haben Sie so ziemlich Ihr Bestes gegeben.
Beispielcode:
if(filter_var($email, FILTER_VALIDATE_EMAIL))
{
list($userName, $mailDomain) = explode("@", $email);
if (!checkdnsrr($mailDomain, "MX"))
{
// Email is unreachable.
}
}
else
{
// Email is bad.
}
checkdnsrr()
ist ziemlich augenblicklich (meiner Erfahrung nach) und ich habe noch keine Umgebung gefunden, in der es nicht funktioniert.
-
Ich werde es überprüfen, wenn ich etwas Zeit habe, aber ich kann Ihnen ohne Weiteres versichern, dass das von Ihnen erwähnte Beispiel @gmailcom NICHT von filter_var validiert wird.
– Marco Aurélio Deleu
11. Dezember 2014 um 18:37 Uhr
-
Wahr genug. Was an sich schon ein Problem ist, wenn auch nur unter ziemlich obskuren Umständen. Da ist ein PHP-Fehlerbericht Auflistung der Fehler von FILTER_VALIDATE_EMAIL; Das Ausführen von checkdnsrr() würde alle falschen positiven Ergebnisse abfangen, die im dortigen Codepad-Beispiel angegeben sind.
– Richplane
3. November 2015 um 11:00 Uhr
-
Beachten Sie, dass checkdnsrr einen Timeout von 20 Sekunden hat, der anscheinend nicht geändert werden kann (einige Domains reagieren so, dass er die 20 Sekunden erreicht, wie ich in meiner Anwendung erleben musste), und der Domainname sollte verarbeitet werden von
idn_to_ascii()
zuerst Domains mit Sonderzeichen (wie ö, é etc.) zu unterstützen. Ich bin auf telefonieren umgestiegendig
mitpassthru
So kann ich ein Timeout und die zu verwendenden Nameserver angeben.– Iquito
16. Mai 2016 um 23:23 Uhr
-
filter_var
schlägt bei einer E-Mail-Adresse wie [email protected] fehl – obwohl dies in manchen Kontexten eine gültige E-Mail-Adresse wäre.– Iquito
19. Mai 2016 um 17:48 Uhr
Leider, filter_var
unterstützt kein UTF8 im lokalen Teil (vor dem @) der Adresse, und um internationale Domänennamen zu unterstützen, müssen Sie den Domänennamen durchlaufen lassen idn_to_ascii
getrennt (was mühsam und nicht offensichtlich ist).
Das macht filter_var
Meiner Meinung nach ziemlich nutzlos: Je mehr Unicode-E-Mail-Adressen in freier Wildbahn auftauchen, desto mehr legitime E-Mail-Adressen werden scheitern, was insbesondere für Länder wie China oder Brasilien der Fall ist, wo eine offensichtliche Nachfrage nach diesen Adressen besteht. filter_var
erlaubt auch keine E-Mail-Adressen wie [email protected]
die gültig sind und in einem Serverkontext nützlich sein können.
Es wäre wirklich nützlich, wenn eine E-Mail-Bibliothek vorhanden wäre, um nach bestimmten Anweisungen zu validieren – sind nur Domänennamen zulässig oder auch beliebige Hosts wie localhost, oder gibt es eine Whitelist für benutzerdefinierte Domänen, die gültig sein sollten? Sollte Unicode erlaubt sein? Was sind häufige Tippfehler bei Freemail-Domainnamen (wie @homail.com), die ebenfalls fehlschlagen sollten?
Außerdem wäre es sinnvoll, einige Domänennamen auf spezifischere Weise zu validieren – hotmail.com erlaubt derzeit keine Unicode-Zeichen und hat bestimmte Einschränkungen für verwendbare Zeichen. Da die meisten verwendeten E-Mail-Adressen in PHP-Anwendungen auf vielleicht 100 verschiedene Domänen konzentriert sind, könnte dies verwendet werden, um diese Domänennamen besser zu validieren. Leider gibt es meines Wissens noch keine solche Bibliothek.
Einige der Kommentare, die ich gesehen habe, stimmten nicht mit meinen Tests überein, daher wollte ich auf die Funktionalität hinweisen, die ich mit PHP 5.x gefunden habe. Wenn Sie die E-Mail zuerst BEREINIGEN, werden alle unerwünschten Zeichen entfernt, dann können Sie VALIDIEREN. Ich habe zwei Funktionen, falls jemand nur die eine oder andere machen wollte.
Überprüfen Sie, ob die E-Mail gültig ist:
function isValidEmailAddress($email="", $check_domain = false)
{
if (empty($email)) {
return false;
} else {
$success = true;
}
if (!filter_var((string) $email, FILTER_VALIDATE_EMAIL)) {
$success = false;
}
if ($check_domain && $success) {
list($name, $domain) = explode('@', trim($email) . "@");
if (!checkdnsrr($domain, 'MX')) {
$success = false;
}
}
return array("success" => $success, "email" => $email);
}
Entfernen Sie <> und UTF8 usw.:
function sanitizeEmailAddress($email="") {
if (!empty($email)) {
$email = filter_var(strtolower(trim($email)), FILTER_SANITIZE_EMAIL);
}
return $email;
}
Beispielverwendung:
// test --
$list = array('goodÂ@bad.com', '[email protected]', '[email protected]', '[email protected]', '', '<[email protected]>', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]');
foreach($list as $email) {
$ret = isValidEmailAddress( sanitizeEmailAddress($email), false );
if ($ret['success']) {
echo "GOOD " . $ret['email'];
} else {
echo "BAD " .$email;
}
echo "\n";
}
Ergebnisse :
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
BAD [email protected]
BAD
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
wenn Sie die Domänenoption verwenden: $ret = isValidEmailAddress( sanitizeEmailAddress($email), true );
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
BAD [email protected]
BAD
GOOD [email protected]
GOOD [email protected]
GOOD [email protected]
BAD [email protected]
BAD [email protected]
BAD [email protected]
-
Beachten Sie unbedingt, dass Sie zuerst FILTER_SANITIZE_EMAIL verwenden sollten. Dadurch kann PHP es bereinigen, bevor es seinen einzigen Validierungsprozess durchläuft.
– Chris
28. Dezember 2018 um 19:11 Uhr
2021 Nr. filter_var
Die Validierungsimplementierung von (ab PHP 8) verifiziert keine internationalen Domainnamen, was meiner Meinung nach ein Grund genug ist, sie fallen zu lassen.
Eigenes von Symfony E-Mail-Validierung verwendet auch eine Regex, die keine UTF-8-Unterstützung hat.
Verwenden https://github.com/egulias/EmailValidator. Es folgt dem E-Mail-RFC und kann auch MX-Einträge überprüfen, um weiter zu überprüfen, ob die Domäne existiert.
-
Beachten Sie unbedingt, dass Sie zuerst FILTER_SANITIZE_EMAIL verwenden sollten. Dadurch kann PHP es bereinigen, bevor es seinen einzigen Validierungsprozess durchläuft.
– Chris
28. Dezember 2018 um 19:11 Uhr
Wenn Sie sicherstellen möchten, dass die E-Mail korrekt formatiert ist, ist dies für diesen Zweck in Ordnung. Wenn Sie wissen möchten, ob es sich um eine echte E-Mail-Adresse handelt, müssen Sie höchstwahrscheinlich für einen E-Mail-Validierungsdienst bezahlen.
– Jeremy Harris
22. Oktober 2013 um 15:30 Uhr
Sie müssen für einen Validierungsservice nichts bezahlen. Senden Sie einfach eine E-Mail mit einem Bestätigungslink.
– ComFreek
22. Oktober 2013 um 15:32 Uhr
JA, sollten Sie auf jeden Fall verwenden
filter_var
um zu überprüfen, ob dies eine gültige E-Mail-Adresse ist, da dies die einzige zuverlässige Möglichkeit in PHP ist, eine E-Mail-Adresse zu überprüfen…– Feeela
22. Oktober 2013 um 15:35 Uhr