<?php
class EMailAdressValitadion
{
//Eigenschaften der Klasse:
//Liste der Trash-Mail-Anbieter
private $TrashProviderList = array("mailexpire.com", "spamtrail.com", "0815.ru", "10minutemail.com", "3d-painting.com",
"antichef.net", "BeefMilk.com", "bio-muesli.info", "bio-muesli.net", "cust.in",
"despammed.com", "DingBone.com", "discardmail.com", "discardmail.de",
"dontsendmespam.de", "edv.to", "emailias.com", "ero-tube.org", "film-blog.biz",
"FudgeRub.com", "geschent.biz", "great-host.in", "guerillamail.org", "imails.info",
"jetable.com", "kulturbetrieb.info", "kurzepost.de", "LookUgly.com", "mail4trash.com",
"mailinator.com", "mailnull.com", "nervmich.net", "nervtmich.net", "nomail2me.com",
"nurfuerspam.de", "objectmail.com", "owlpic.com", "proxymail.eu", "rcpt.at",
"recode.me", "s0ny.net", "sandelf.de", "SmellFear.com", "sneakemail.com",
"snkmail.com", "sofort-mail.de", "spam.la", "spambog.com", "spambog.de",
"spambog.ru", "spamex.com", "spamgourmet.com", "spammotel.com", "squizzy.de",
"super-auswahl.de", "teewars.org", "tempemail.net", "trash-mail.at", "trash-mail.com",
"trash2009.com", "trashmail.at", "trashmail.de", "trashmail.me", "trashmail.net",
"trashmail.ws", "watch-harry-potter.com", "watchfull.net", "wegwerf-email.net",
"wegwerfadresse.de", "wegwerfmail.de", "wegwerfmail.net", "wegwerfmail.org",
"willhackforfood.biz", "yopmail.com");
//Liste aller Top-Level-Domains
private $TopLevelDomainList = array("AC", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "ARPA", "AS",
"AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BM", "BN",
"BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI",
"CK", "CL", "CM", "CN", "CO", "COM", "CR", "CU", "CV", "CX", "CY", "CZ", "DE", "DJ",
"DK", "DM", "DO", "DZ", "EC", "EDU", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK",
"FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN",
"GOV", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT",
"HU", "ID", "IE", "IL", "IM", "IN", "INT", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP",
"KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI",
"LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MIL", "MK",
"ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY",
"MZ", "NA", "NC", "NE", "NET", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NT", "NU",
"NZ", "OM", "ORG", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT",
"PW", "PY", "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH",
"SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", "TF",
"TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW", "TZ", "UA",
"UG", "UK", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF",
"WS", "YE", "YT", "YU", "ZA", "ZM", "ZW");
//In dieser Variable speichern wir Validierungsfehler um sie nachher bei bedarf ausgeben zu können
private $ErrorMessage = "";
//Die Funktion CheckAdress erhält die Email-Adresse als ersten Parameter
//Den optionalen 2. Parameter der Standardmäßig true ist und angibt ob der Trash-Provider-Filter benutzt werden soll oder nicht.
//Der 3. optionale Parameter legt fest ob auch Spezialzeichen wie Leerzeichen oder Spitzeklammern die nur escapet zulässig sind
//akzeptiert werden sollen oder nicht. Der Standard ist false was bedeutet das diese Zeichen nicht akzeptiert werden.
public function CheckAdress ($EMailAdress, $UseTrashFilter = true, $AllowSpecialCharacters = false)
{
//Reset der Fehlertext-variable für den Fall das dies nicht der erste durchlauf für dieses Objekt ist
$this->ErrorMessage = "";
//Die variable für den Rückgabewert initialisieren
$Ruckgabe = true;
//Wenn der Lokalteil in doppelte Hochkommas gehült ist
$LokalTeilMaskiert = false;
//Leerzeichen glätten
$EMailAdress = Trim($EMailAdress);
//Länge der Email-Adresse prüfen
if (strlen($EMailAdress) > 254)
{
$this->ErrorMessage .= "Die Email-Adresse ist zu lang, eine Email-Adresse darf maximal 254 Stellen lang sein.\n";
$Ruckgabe = false;
}
//Die Emailadresse am @-Zeichen in die Hauptbestandteile aufsplitten
//Ist der Lokalteil in doppelte Hochkomma weil er zusätzliche Sonderzeichen wie Leerzeichen enthält?
if (substr($EMailAdress, 0, 1) == "\"" && $AllowSpecialCharacters)
{
$LokalTeilMaskiert = true;
//Nach maskierten doppletem Hochkomma suchen ( \" ) und die Positionen merken, dann selbige durch "AA" ersetzten
//Grund: maskierte dopplete Hochkomma können wenn sie vorhanden sind das zerteilen behindern.
$PregTrefferPos = array();
preg_match("/\\\\\"/", $EMailAdress, $PregTrefferPos, PREG_OFFSET_CAPTURE);
$EMailAdress = preg_replace("/\\\\\"/", "AA", $EMailAdress);
//Die Mailadresse an der Stelle von "@ zertrennen und das Hochkomma anschließend an den Lokalteil wieder anhängen
$EMailAdressMainParts = explode("\"@", $EMailAdress);
$EMailAdressMainParts[0] .= "\"";
//Nun prüfen wir ob alle zuvor entfernten maskierten doppelten Hochkommas auch wirklich im Lokalteil waren
//und nicht vielleicht im Domainteil wo sie nicht erlaubt wären
for ($i = 0; $i < sizeof($PregTrefferPos); $i++)
{
if ($PregTrefferPos[$i][1] >= strlen($EMailAdressMainParts[0]))
{
$this->ErrorMessage .= "Die Email-Adresse enthält im Domainteil das nicht zulässige doppelte Hochkomma.\n";
$Ruckgabe = false;
$i = sizeof($PregTrefferPos);
}
}
}
else
{
$LokalTeilMaskiert = false;
//Nach maskierten @-Zeichen suchen ( \@ ) und die Positionen merken, dann selbige durch "AA" ersetzten
//Grund: maskierte @-Zeichen können wenn sie vorhanden sind das zerteilen behindern.
$PregTrefferPos = array();
if ($AllowSpecialCharacters)
{
preg_match("/\\\\@/", $EMailAdress, $PregTrefferPos, PREG_OFFSET_CAPTURE);
$EMailAdress = preg_replace("/\\\\@/", "AA", $EMailAdress);
}
//Die Mailadresse an der Stelle von @ zertrennen
$EMailAdressMainParts = explode("@", $EMailAdress);
//Nun prüfen wir ob alle zuvor entfernten maskierten @-Zeichen auch wirklich im Lokalteil waren
//und nicht vielleicht im Domainteil wo sie nicht erlaubt wären
for ($i = 0; $i < sizeof($PregTrefferPos); $i++)
{
if ($PregTrefferPos[$i][1] >= strlen($EMailAdressMainParts[0]))
{
$this->ErrorMessage .= "Die Email-Adresse enthält im Domainteil das nicht zulässige @-Zeichen.\n";
$Ruckgabe = false;
$i = sizeof($PregTrefferPos);
}
}
}
//Wenn nicht genau 2 Bestandteile vorhanden sind (also kein oder mehr als 1 @-Zeichen vorkommt)
if (sizeof($EMailAdressMainParts) != 2)
{
//Wenn kein oder zuviele @-Zeichen vorhanden sind dies als Meldung wegschreiben und dann Abarbeitung beenden
if (sizeof($EMailAdressMainParts) < 2)
$this->ErrorMessage .= "Die Email-Adresse enthält kein @-Zeichen.\n";
else
$this->ErrorMessage .= "Die Email-Adresse enthält mehr als ein @-Zeichen.\n";
$Ruckgabe = false;
return $Ruckgabe;
}
//zunächst überprüfen wir nun den LokalTeil (also den vorderen Teil der Email-Adresse)
//Die Zeichenlänge des Lokalteils darf 64 Zeichen nicht übersteigen
if (strlen($EMailAdressMainParts[0]) > 64)
{
$this->ErrorMessage .= "Der Lokalteil der Email-Adresse darf nicht mehr als 64 Stellen haben.\n";
$Ruckgabe = false;
}
//Wenn der Lokalteil von doppelten Hochkomma umschlossen ist?
if ($LokalTeilMaskiert)
{
//Der Lokalteil darf neben den normal zulässigen Zeichen: A-Za-z0-9.!#$%&'*+-/=?^_`{|}~ auch die folgenden enthalten @ :,;<>()[] bestehen
if (preg_match("/^\"[a-zA-Z0-9\.\!\#\$\%\&\'\*\+\-\/=\?\^\_\`\{\|\}\~@:,; <>\(\)\[\]]+\"$/", $EMailAdressMainParts[0]) != 1)
{
$this->ErrorMessage .= "Die Email-Adresse enthält im Lokalteil nicht legale Zeichen.\n";
$Ruckgabe = false;
}
}
else
{
//Lokalteil ist nicht in doppelte Hochkomma eingeschlossen
if ($AllowSpecialCharacters)
{
//Mit \ escapde Sonderzeichen entfernen
$EMailAdressMainParts[0] = str_replace("\\ ", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\;", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\,", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\:", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\<", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\>", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\(", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\)", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\[", "", $EMailAdressMainParts[0]);
$EMailAdressMainParts[0] = str_replace("\\]", "", $EMailAdressMainParts[0]);
}
//Der Lokalteil darf nur aus A-Za-z0-9.!#$%&'*+-/=?^_`{|}~ bestehen
if (preg_match("/^[a-zA-Z0-9\.\!\#\$\%\&\'\*\+\-\/=\?\^\_\`\{\|\}\~]+$/",
$EMailAdressMainParts[0]) != 1)
{
$this->ErrorMessage .= "Die Email-Adresse enthält im Lokalteil nicht legale Zeichen.\n";
$Ruckgabe = false;
}
}
if (substr($EMailAdressMainParts[0], 0, 1) == "." ||
substr($EMailAdressMainParts[0], -1) == ".")
{
$this->ErrorMessage .= "Der Lokalteil der Email-Adresse darf nicht mit einem Punkt beginnen oder enden.\n";
$Ruckgabe = false;
}
//Nun überprüfen wir nun den DomainTeil (also den hinteren Teil der Email-Adresse)
//Zunächst zerlegen wir diesen Teil in die (möglicherweise vorhandenen)
//Subdomains, Domain und Top-Level-Domain (allgemein auch als Labels bezeichnet).
$EMailAdressDomainParts = explode(".", $EMailAdressMainParts[1]);
//Es muss mindestens eine Domain und Top-Level-Domain (also 2 Elemente im Array) geben
if (sizeof($EMailAdressDomainParts) < 2)
{
$this->ErrorMessage .= "Der Domainteil der Email-Adresse muss mindestens aus einer Domain und " .
"Top-Level-Domain mit Punkt getrennt bestehen.\n";
$Ruckgabe = false;
}
//Nun wird jedes Label des DomainTeil auf Ungültige Zeichen geprüft.
for ($i = 0; $i < sizeof($EMailAdressDomainParts); $i++)
{
if (preg_match("/^[a-zA-Z0-9\-]+$/", $EMailAdressDomainParts[$i]) != 1)
{
$this->ErrorMessage .= "Der Domainteil der Email-Adresse enthält das Label '" .
htmlspecialchars($EMailAdressDomainParts[$i]) .
"' dieses enthält ungültige Zeichen.\n";
$Ruckgabe = false;
}
if (substr($EMailAdressDomainParts[$i], 0, 1) == "-" ||
substr($EMailAdressDomainParts[$i], -1) == "-")
{
$this->ErrorMessage .= "Der Domainteil der Email-Adresse enthält das Label '" .
htmlspecialchars($EMailAdressDomainParts[$i]) .
"' dieses darf nicht mit einem - beginnen oder enden.\n";
$Ruckgabe = false;
}
if (strlen($EMailAdressDomainParts[$i]) > 63)
{
$this->ErrorMessage .= "Der Domainteil der Email-Adresse enthält das Label '" .
htmlspecialchars($EMailAdressDomainParts[$i]) .
"' dieses darf nicht mehr als 63 Stellen haben.\n";
$Ruckgabe = false;
}
}
//Abschließend prüfen wir noch ob die Top-Level-Domain existiert
if (!in_array(strtoupper($EMailAdressDomainParts[(sizeof($EMailAdressDomainParts) - 1)]), $this->TopLevelDomainList))
{
$this->ErrorMessage .= "Die Top-Level-Domain dieser Email-Adresse '" .
htmlspecialchars($EMailAdressDomainParts[(sizeof($EMailAdressDomainParts) - 1)]) .
"' ist nicht legal.\n";
$Ruckgabe = false;
}
//Wenn der Trashmailfilter benutzt werden soll ...
if ($UseTrashFilter)
{
//... dann die letzten beiden Glieder des Domain-Arrays prüfen.
if (in_array(strtolower($EMailAdressDomainParts[(sizeof($EMailAdressDomainParts) - 2)] . "." .
$EMailAdressDomainParts[(sizeof($EMailAdressDomainParts) - 1)]), $this->TrashProviderList))
{
$this->ErrorMessage .= "Trash-Mail-Adressen dürfen nicht verwendet werden.\n";
$Ruckgabe = false;
}
}
return $Ruckgabe;
}
//Die Funktion gibt den Fehlertext zurück, der Optionale Parameter $ForHtmlOutput ersetzt
//bei true das \n durch den <br>-Tag.
public function GiveErrorText ($ForHtmlOutput = true)
{
if ($ForHtmlOutput)
return nl2br($this->ErrorMessage);
else
return $this->ErrorMessage;
}
}
$MeinMailAdressChecker = new EMailAdressValitadion();
if ($MeinMailAdressChecker->CheckAdress("Max.Mustermann@Test.de"))
echo "<span style='color:green'>Email-Adresse hat die Prüfung bestanden</span>";
else
echo "<span style='color:red'>" . $MeinMailAdressChecker->GiveErrorText() . "</span>";
//Für einen ausführlichen Test:
$TestMailAdressen = array(array("Mit Leerzeichen@Fehler.de", true, false),
array("MitZwei@Zeichen@Fehler.de", true, false),
array("OhneTopLevelDomain@Fehler", true, false),
array("MitLeerSubLevelDomain@Sub..Fehler.de", true, false),
array("GanzOhneAtZeichenFehler.de", true, false),
array("@Fehler.de", true, false),
array(".AmAnfang@Fehler.de", true, false),
array("AmEndemit.@Fehler.de", true, false),
array("DomainMit-AmAnfang@-Fehler.de", true, false),
array("DomainMit-AmEnde@Fehler-.de", true, false),
array("Test@DomainDieVielZuLangeIst-WeilSieVielMehrZeichenAls63HatNaemlich64.de", true, false),
array("LokalTeilderVielZuLangeIstWeilErVielMehrZeichenAls64HatNaemlich65@Fehler.de", true, false),
array("EineTopLevelDomainDieEsNichtGibt@Fehler.xxx", true, false),
array("UmlauteinderDomain@Föhler.de", true, false),
array("VerboteneZeicheninderDomain@F_e&h(l#e%r.de", true, false),
array("\"Mit legalem Leerzeichen\"@Gut.de", true, true),
array("MitEscapten\\@zeichen@Gut.de", true, true),
array("MitEscapten\\@zeichenDasNichtErlaubtIst@Fehler.de", true, false),
array("\"Mit @zeichen und \\\"\"@Gut.de", true, true),
array("\"Mit @zeichen und \\\"\"@Fehler.de", true, false),
array("MitEscapten\\;Strichpunkt@Gut.de", true, true),
array("MitEscapten\\;StrichpunktDasNichtErlaubtIst@Fehler.de", true, false),
array("\"Mit, 'legalen', Sonderzeichen:<usw>\"@Gut.de", true, true),
array("\"Mit, _nichterlaubten_, 'legalen' Sonderzeichen:<usw>\"@Fehler.de", true, false),
array("Mit\\ 'legalescapten'\\ Sonderzeichen\\:\\<usw\\>@Gut.de", true, true),
array("Mit\\ _nichterlaubten_\\ 'legalescapten'\\ Sonderzeichen\\:\\<usw\\>@Fehler.de", true, false),
array("Viele*Sonderzeichen_Die-Alle#legal$sind?Ja!&das=toll@gut.de", true, false),
array("Noch'mehr`Sonderzeichen^die{legal}+toll%sind~oder/nicht|ja@gut.de", true, false),
array("TrashmailBeiAktiviertenFilter@Trash-Mail.com", true, false),
array("TrashmailBeiDeaktiviertenFilter@Trash-Mail.com", false, false));
$TestZeiten = array();
$GesamtZeit = 0;
for ($i = 0; $i < sizeof($TestMailAdressen); $i++)
{
$Start = explode(" ",microtime());
$Start = $Start[1] + $Start[0];
echo "<br><br>Prüfe Email-Adresse: <b>" . htmlspecialchars($TestMailAdressen[$i][0]) . "</b><br>Ergebniss:<br>";
if ($MeinMailAdressChecker->CheckAdress($TestMailAdressen[$i][0], $TestMailAdressen[$i][1], $TestMailAdressen[$i][2]))
echo "<span style='color:green'>Email-Adresse hat die Prüfung bestanden</span><br>";
else
echo "<span style='color:red'>" . $MeinMailAdressChecker->GiveErrorText() . "</span>";
$Ende = explode(" ",microtime());
$Ende = $Ende[1] + $Ende[0];
echo "<small>Verarbeitungszeit in Sekunden: " . number_format(($Ende - $Start), 7, ",", ".") . "</small><br>";
$TestZeiten[] = number_format(($Ende - $Start), 7, ",", ".");
$GesamtZeit += ($Ende - $Start);
}
sort($TestZeiten);
echo "<br><br>Laufzeitergebnis:<br>
<table border='0' width='33%'>
<tr><td>Durchläufe:</td><td>" . sizeof($TestMailAdressen) . "</td></tr>
<tr><td>Gesamtlaufzeit:</td><td>" . $GesamtZeit . " Sekunden</td></tr>
<tr><td>Durchschnittslaufzeit:</td><td>" .
number_format(round($GesamtZeit / sizeof($TestMailAdressen), 7), 7, ",", ".") .
" Sekunden</td></tr>
<tr><td>Kürzeste Laufzeit:</td><td>" . $TestZeiten[0] . " Sekunden</td></tr>
<tr><td>Längste Laufzeit:</td><td>" . $TestZeiten[sizeof($TestZeiten)-1] . " Sekunden</td></tr>
</table>";
?>