Eine E-Mail-Adresse in Laravel zu validieren ist verlockend als Einzeiler zu
behandeln – man fügt email zu einem Validierungs-Array hinzu und macht weiter.
Diese Regel ist ein guter Anfang, aber sie beantwortet nur die erste der drei
Fragen, die echte Validierung stellt. Hat die Adresse die richtige Form? Kann
ihre Domain Mail empfangen? Existiert das Postfach überhaupt? Laravel ist
insofern ungewöhnlich, als seine eingebaute email-Regel die ersten beiden in
einer einzigen Zeile beantworten kann; die dritte ist ein Netzwerkproblem, das
man besser abgibt. Dieser Leitfaden baut jede Schicht auf Laravels eigenem
Validator auf und zeigt genau, wo das Framework aufhört. Er erweitert den
Leitfaden zur E-Mail-Validierung in PHP:
Laravel verpackt dieselben PHP-Bausteine – und filter_var ist nur ein
Schlüsselwort entfernt – in eine deutlich angenehmere API.
Die kurze Antwort#
Verwenden Sie Laravels Regel email:rfc,dns für Syntax und MX-Lookup in einem
Durchlauf und anschließend eine Verifizierungs-API für die SMTP-Postfachprüfung –
das Günstigste zuerst, mit bail als Kurzschluss, sobald eine Schicht
entscheidend ist. Versuchen Sie nicht, selbst eine SMTP-Sitzung aus Ihrer App zu
öffnen, um Postfächer abzufragen: Der ausgehende Port 25 ist auf den meisten
Hosts gesperrt, und die Antwort hängt von der Reputation der sendenden IP sowie
von Greylisting ab, das Sie nicht nachbauen möchten. Jede Schicht schließt
Adressen günstiger aus als die vorherige; nur die letzte kann eine Adresse
einschließen.
Schicht 1 und 2: Syntax und DNS in einer Regel#
Die email-Regel wird vom Paket egulias/email-validator gestützt und nimmt
Stile entgegen, die entscheiden, wie streng sie ist. Standardmäßig wendet sie
den rfc-Stil an (Grammatik nach RFC 5321/5322). Der für die Validierung
entscheidende ist dns, der einen Live-Lookup ergänzt und bestätigt, dass die
Domain eine Mail-Route auflöst – einen MX-Eintrag, ersatzweise einen A-Eintrag.
Verlangen Sie beides, erledigt Laravel Syntax- und Domain-Prüfung in einer
einzigen Regel:
public function store(Request $request)
{
$validated = $request->validate([
'email' => ['required', 'email:rfc,dns'],
]);
// $validated['email'] is well-formed AND its domain can receive mail.
}
Die anderen Stile sind es wert, gekannt zu werden. email:filter führt PHPs
filter_var($email, FILTER_VALIDATE_EMAIL) aus – genau die Prüfung aus dem
PHP-Leitfaden – und filter_unicode lässt
einige Unicode-Local-Parts zu. strict weist die Warnungen zu abschließenden und
aufeinanderfolgenden Punkten zurück, die der RFC-Parser toleriert. Und spoof
schützt vor täuschenden Homograph-Zeichen, sodass für ein öffentliches
Anmeldeformular email:rfc,dns,spoof ein sinnvoller Standard ist. In einem Form
Request liest sich das so:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreSubscriberRequest extends FormRequest
{
public function rules(): array
{
return [
'email' => ['required', 'email:rfc,dns,spoof'],
];
}
}
Warum email:rfc,dns noch kein grünes Licht ist#
Ein bestandener email:rfc,dns-Check bedeutet, dass die Zeichenkette wohlgeformt
ist und die Domain Mail empfangen kann. Er sagt nichts darüber aus, ob das
konkrete Postfach existiert. noreply-9f2x@gmail.com besteht. Ebenso
definitely-fake@gmail.com. Beide sind unzustellbar, denn der MX-Eintrag ist
eine Tatsache über die Domain, während das Postfach eine Tatsache ist, die Sie
nur durch Nachfragen beim Mailserver erfahren können. Das ist dieselbe Wand, an
der E-Mail-Validierung per Regex scheitert:
Kein noch so ausgefeiltes Pattern-Matching und kein DNS-Lookup schafft den
Übergang von „die Domain nimmt Mail an“ zu „diese Adresse tut es“.
Wenn Sie die Lücke selbst sehen möchten, fügen Sie eine syntaktisch perfekte
Adresse in den kostenlosen E-Mail-Checker ein und
beobachten Sie, wie eine von der Regel abgesegnete Zeichenkette als
undeliverable zurückkommt.
Schicht 3: Existiert das Postfach überhaupt?#
Ein konkretes Postfach zu bestätigen bedeutet die SMTP-Zustellkonversation: sich
mit dem Mailhost verbinden, RCPT TO absetzen, die Antwort lesen und die
Verbindung trennen, bevor irgendetwas gesendet wird. Prinzipiell könnten Sie das
aus PHP heraus skripten, aber Sie sollten es nicht von Ihrem Anwendungsserver aus
tun – die meisten Cloud-Anbieter sperren den ausgehenden Port 25, die Antwort
hängt von der Reputation der IP ab, von der aus Sie sich verbinden, und
empfangende Server greylisten und drosseln unbekannte Absender. Es steckt noch
mehr dahinter: Wie E-Mail-Verifizierung funktioniert
durchläuft die vollständige Pipeline, einschließlich Catch-all-Domains, die jede
Adresse annehmen und eine naive Prüfung aushebeln. Das ist die Schicht, die es
wert ist, delegiert zu werden.
Qualisend aus einer eigenen Validierungsregel aufrufen#
Laravel macht die Delegation sauber: Verpacken Sie den API-Aufruf in ein Regel-Objekt und legen Sie es in dasselbe Regel-Array. Erzeugen Sie eines mit Artisan:
php artisan make:rule DeliverableEmail
Halten Sie den Schlüssel aus Ihrem Code heraus, indem Sie ihn über
config/services.php einbinden, das ihn aus Ihrer .env liest:
// config/services.php
'qualisend' => [
'key' => env('QUALISEND_API_KEY'),
],
Anschließend ruft die Regel den Verify-Endpunkt mit der Http-Fassade auf, liest
den result-Umschlag und schlägt nur fehl, wenn das Urteil undeliverable
lautet:
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Http;
class DeliverableEmail implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$response = Http::withToken(config('services.qualisend.key'))
->timeout(10)
->post('https://api.qualisend.com/v1/verify', ['email' => $value]);
// On our own outage or a rate limit, don't block a real signup.
if ($response->failed()) {
return;
}
$result = $response->json('result');
if (($result['status'] ?? null) === 'undeliverable') {
$fail('This email address appears to be undeliverable.');
}
}
}
Http::withToken() setzt den Bearer-Auth-Header, ->post() sendet den
JSON-Body, und $response->json('result') zieht das verschachtelte
result-Objekt per Punktzugriff heraus. Der Endpunkt oben ist ein Platzhalter –
prüfen Sie die API-Referenz für die genaue Basis-URL und die Form
der Anfrage –, doch die Antwort liest sich so zurück:
{
"result": {
"status": "deliverable",
"score": 95,
"reason": null,
"sub_flags": { "role": false, "disposable": false, "free": false, "catch_all": false }
}
}
status ist eines von deliverable, risky, undeliverable oder unknown.
Die Regel oben lässt nur undeliverable hart fehlschlagen und lässt risky und
unknown durch, sodass Sie nachgelagert entscheiden können, was damit geschieht
– anhand von score filtern oder auf einen sub_flags-Eintrag wie disposable
verzweigen –, statt eine Grenzfall-Adresse in einen Formularfehler zu verwandeln.
Behandeln Sie das JSON oben als die Form, nicht als den Vertrag; die vollständige
Feldliste steht in der Entwicklerdokumentation.
Die Schichten zusammensetzen, um eine E-Mail-Adresse in Laravel zu validieren#
Setzen Sie alle drei in einem Form Request zusammen, das Günstigste zuerst, und
lassen Sie bail beim ersten Fehlschlag stoppen, sodass die API-Regel nur bei
Adressen läuft, die Syntax und MX-Prüfung bereits bestanden haben:
namespace App\Http\Requests;
use App\Rules\DeliverableEmail;
use Illuminate\Foundation\Http\FormRequest;
class StoreSubscriberRequest extends FormRequest
{
public function rules(): array
{
return [
'email' => [
'bail',
'required',
'email:rfc,dns',
new DeliverableEmail(),
],
];
}
public function messages(): array
{
return [
'email.email' => 'Enter a valid email address on a real domain.',
];
}
}
bail ist der ganze Trick. Eine fehlerhafte Adresse oder eine tote Domain
scheitert lokal und verbraucht nie ein API-Guthaben; nur Adressen, die den
Netzwerk-Roundtrip wert sind, erreichen die SMTP-Schicht. Type-hinten Sie den
Request in Ihrem Controller, und Laravel durchläuft die Pipeline, bevor Ihr
Methoden-Body überhaupt ausgeführt wird:
public function store(StoreSubscriberRequest $request)
{
// Every layer has passed — safe to persist.
$subscriber = Subscriber::create($request->validated());
return redirect()->route('subscribers.index');
}
Die Schichtung, nicht das Framework, macht die Validierung zuverlässig – dieselbe Form wie die PHP-Version, wobei Laravel die ersten beiden Schichten in eine Regel zusammenfasst. Führen Sie die schnelle synchrone Pipeline bei der Anmeldung aus und behalten Sie den langsameren, SMTP-bestätigten Durchlauf der Backoffice-Arbeit vor: Der Leitfaden zur serverlosen Anmeldung zeigt das Echtzeit-Muster, und wie man eine E-Mail-Liste bereinigt deckt die Batch-Seite ab.
Häufig gestellte Fragen#
Prüft Laravels email-Regel, ob die Domain existiert?#
Nur, wenn Sie es verlangen. Die schlichte email-Regel validiert die Syntax mit
dem Paket egulias/email-validator (dem rfc-Stil). Ergänzen Sie den
dns-Stil – email:rfc,dns –, dann bestätigt Laravel zusätzlich, dass die
Domain eine Mail-Route auflöst, sodass eine erfundene oder tote Domain im selben
Durchlauf durchfällt. Kein Stil kontaktiert das Postfach, ein bestandener Check
bedeutet also weiterhin „zustellbar aussehend“ und nicht „zustellbar“.
Was ist der Unterschied zwischen email:rfc, email:filter und email:dns?#
rfc validiert gegen die RFCs 5321/5322 mittels egulias und ist Laravels
Standard. filter führt PHPs filter_var($email, FILTER_VALIDATE_EMAIL) aus –
genau die Prüfung aus dem PHP-Leitfaden –, während filter_unicode einige
Unicode-Zeichen zulässt. dns ergänzt einen Live-MX-Lookup, und spoof weist
täuschende Homograph-Zeichen zurück. Sie kombinieren sie mit Kommas, sodass
email:rfc,dns das praxistaugliche Tor aus Syntax plus Domain ist.
Wie stelle ich in Laravel fest, ob ein Postfach existiert?#
Nicht mit einer eingebauten Regel – die Postfachbestätigung erfordert eine
SMTP-Konversation, die Sie nicht von Ihrem App-Server aus führen sollten, denn
Port 25 ist vielerorts gesperrt und das Ergebnis hängt von der Reputation Ihrer
sendenden IP ab. Verpacken Sie eine Verifizierungs-API in ein eigenes
ValidationRule-Objekt, rufen Sie sie mit der Http-Fassade auf, lesen Sie den
result-Umschlag und lassen Sie den Check bei undeliverable fehlschlagen.
Setzen Sie ihn mit bail hinter email:rfc,dns, damit er nur bei Adressen
läuft, die die lokalen Schichten bereits bestanden haben.
Verlangsamt die dns-Regel meine Formularübermittlungen?#
Das kann sein. Der dns-Stil führt bei jeder Validierung einen Live-DNS-Lookup
aus, sodass ein langsamer oder nicht erreichbarer Resolver die Anfrage ins
Stocken bringt. Für ein einzelnes Anmeldeformular ist das in Ordnung, halten Sie
ihn aber von Massenimporten fern und stapeln Sie ihn nicht mit einem synchronen
API-Aufruf, sofern Sie kein Timeout am Http-Client gesetzt haben – so wie es
die DeliverableEmail-Regel oben mit ->timeout(10) tut.
Bereit, die Postfach-Schicht zu ergänzen? Werfen Sie eine Adresse in den
kostenlosen E-Mail-Checker, um zu beobachten, wie eine von
der Regel abgesegnete Adresse als unzustellbar zurückkommt, und verdrahten Sie
anschließend dasselbe Urteil in Ihrer ValidationRule mit den
Copy-and-paste-Beispielen aus der API-Referenz.