Il est tentant de traiter la validation d'une adresse e-mail dans Laravel comme
une simple ligne de code — ajouter email à un tableau de validation et passer à
autre chose. Cette règle est un bon point de départ, mais elle ne répond qu'à la
première des trois questions que pose une véritable validation. L'adresse est-elle
correctement formée ? Son domaine peut-il recevoir du courrier ? La boîte de
réception existe-t-elle réellement ? Laravel a ceci de particulier que sa règle
email intégrée peut répondre aux deux premières en une seule ligne ; la
troisième est un problème réseau qu'il vaut mieux déléguer. Ce guide construit
chaque couche par-dessus le validateur natif de Laravel et montre précisément où
le framework s'arrête. Il prolonge le
guide de validation d'adresses e-mail en PHP :
Laravel enveloppe les mêmes briques PHP — et filter_var n'est qu'à un mot-clé de
distance — dans une API bien plus agréable.
La réponse courte#
Utilisez la règle email:rfc,dns de Laravel pour la syntaxe et la recherche MX en
un seul passage, puis une API de vérification pour le contrôle SMTP de la boîte de
réception — le moins coûteux d'abord, avec un court-circuit via bail dès qu'une
couche est décisive. N'essayez pas d'ouvrir vous-même une session SMTP depuis votre
application pour sonder les boîtes de réception : le port 25 sortant est bloqué sur
la plupart des hébergeurs, et la réponse dépend de la réputation de l'IP d'envoi et
du greylisting que vous ne voulez pas réimplémenter. Chaque couche écarte des
adresses plus économiquement que la précédente ; seule la dernière peut valider
une adresse positivement.
Couches 1 et 2 : syntaxe et DNS en une seule règle#
La règle email s'appuie sur le paquet egulias/email-validator, et elle accepte
des styles qui déterminent son niveau de rigueur. Par défaut, elle applique le
style rfc (grammaire des RFC 5321/5322). Celui qui compte pour la validation est
dns, qui ajoute une recherche en direct et confirme que le domaine résout une
route de messagerie — un enregistrement MX, avec un enregistrement A en solution de
repli. Demandez les deux et Laravel effectue la syntaxe et le contrôle du domaine en
une seule règle :
public function store(Request $request)
{
$validated = $request->validate([
'email' => ['required', 'email:rfc,dns'],
]);
// $validated['email'] is well-formed AND its domain can receive mail.
}
Les autres styles méritent d'être connus. email:filter exécute le
filter_var($email, FILTER_VALIDATE_EMAIL) de PHP — le contrôle exact du
guide PHP — et filter_unicode autorise
certaines parties locales en Unicode. strict rejette les avertissements liés aux
points finaux ou consécutifs que l'analyseur RFC tolère. Enfin, spoof protège
contre les caractères homographes trompeurs : pour un formulaire d'inscription
public, email:rfc,dns,spoof est donc une valeur par défaut judicieuse. Dans une
form request, cela donne :
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreSubscriberRequest extends FormRequest
{
public function rules(): array
{
return [
'email' => ['required', 'email:rfc,dns,spoof'],
];
}
}
Pourquoi email:rfc,dns n'est toujours pas un feu vert#
Un succès sur email:rfc,dns signifie que la chaîne est bien formée et que le
domaine peut recevoir du courrier. Cela ne dit rien sur l'existence de la boîte de
réception précise. noreply-9f2x@gmail.com passe. definitely-fake@gmail.com
aussi. Les deux sont non délivrables, car l'enregistrement MX est un fait relatif au
domaine alors que la boîte de réception est un fait que l'on ne peut connaître
qu'en interrogeant le serveur de messagerie. C'est le même mur qui fait
échouer la validation d'e-mail par regex :
aucune correspondance de motif, ni aucune recherche DNS, ne permet de passer de « le
domaine accepte le courrier » à « cette adresse le fait ».
Si vous voulez constater l'écart par vous-même, collez une adresse syntaxiquement
parfaite dans le vérificateur d'e-mail gratuit et regardez
une chaîne approuvée par la règle revenir undeliverable.
Couche 3 : la boîte de réception existe-t-elle réellement ?#
Confirmer une boîte de réception précise implique la conversation de livraison SMTP :
se connecter à l'hôte de messagerie, émettre RCPT TO, lire la réponse et se
déconnecter avant d'envoyer quoi que ce soit. En principe, vous pourriez scripter
cela en PHP, mais vous ne devriez pas l'exécuter depuis votre serveur applicatif —
la plupart des fournisseurs cloud bloquent le port 25 sortant, la réponse dépend de
la réputation de l'IP depuis laquelle vous vous connectez, et les serveurs de
réception appliquent greylisting et limitation de débit aux expéditeurs
inconnus. Il y a plus encore :
comment fonctionne la vérification d'e-mail
parcourt tout le pipeline, y compris les domaines catch-all qui acceptent toutes les
adresses et déjouent un sondage naïf. C'est la couche qu'il vaut la peine de
déléguer.
Appeler Qualisend depuis une règle de validation personnalisée#
Laravel rend cette délégation propre : encapsulez l'appel d'API dans un objet règle et déposez-le dans le même tableau de règles. Générez-en un avec Artisan :
php artisan make:rule DeliverableEmail
Gardez la clé hors de votre code en la câblant via config/services.php, qui la lit
depuis votre .env :
// config/services.php
'qualisend' => [
'key' => env('QUALISEND_API_KEY'),
],
La règle appelle ensuite le point de terminaison de vérification avec la façade
Http, lit l'enveloppe result et n'échoue que lorsque le verdict est
undeliverable :
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() définit l'en-tête d'authentification bearer, ->post() envoie le
corps JSON, et $response->json('result') extrait l'objet result imbriqué à l'aide
d'un accès par point. Le point de terminaison ci-dessus est un exemple générique —
consultez la référence de l'API pour connaître l'URL de base exacte et
la forme de la requête — mais la réponse se présente ainsi :
{
"result": {
"status": "deliverable",
"score": 95,
"reason": null,
"sub_flags": { "role": false, "disposable": false, "free": false, "catch_all": false }
}
}
status vaut deliverable, risky, undeliverable ou unknown. La règle
ci-dessus n'échoue franchement que sur undeliverable et laisse passer risky et
unknown, de sorte que vous pouvez décider en aval quoi en faire — poser un seuil sur
score, ou vous ramifier selon une entrée de sub_flags comme disposable — plutôt
que de transformer une adresse limite en erreur de formulaire. Considérez le JSON
ci-dessus comme la forme, non comme le contrat ; la liste complète des champs figure
dans la documentation développeur.
Assembler les couches pour valider une adresse e-mail dans Laravel#
Composez les trois dans une seule form request, le moins coûteux d'abord, et laissez
bail s'arrêter au premier échec pour que la règle d'API ne s'exécute que sur les
adresses ayant déjà passé la syntaxe et le contrôle MX :
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 est toute l'astuce. Une adresse mal formée ou un domaine inactif échoue
localement et ne dépense jamais un crédit d'API ; seules les adresses qui méritent
l'aller-retour réseau atteignent la couche SMTP. Typez la requête dans votre
contrôleur et Laravel exécute le pipeline avant même que le corps de votre méthode ne
s'exécute :
public function store(StoreSubscriberRequest $request)
{
// Every layer has passed — safe to persist.
$subscriber = Subscriber::create($request->validated());
return redirect()->route('subscribers.index');
}
C'est le superposage, et non le framework, qui rend la validation fiable — la même structure que la version PHP, Laravel condensant les deux premières couches en une seule règle. Exécutez le pipeline synchrone rapide à l'inscription et réservez le passage plus lent, confirmé par SMTP, au travail en back-office : le guide d'inscription serverless montre le schéma en temps réel, et comment nettoyer une liste d'e-mails couvre le volet par lots.
Foire aux questions#
La règle email de Laravel vérifie-t-elle si le domaine existe ?#
Uniquement si vous le lui demandez. La règle email simple valide la syntaxe avec le
paquet egulias/email-validator (le style rfc). Ajoutez le style dns —
email:rfc,dns — et Laravel confirme également que le domaine résout une route de
messagerie, de sorte qu'un domaine inventé ou inactif échoue lors du même passage.
Aucun de ces styles ne contacte la boîte de réception : un succès signifie donc
toujours « d'apparence délivrable », et non « délivrable ».
Quelle est la différence entre email:rfc, email:filter et email:dns ?#
rfc effectue la validation selon les RFC 5321/5322 via egulias et constitue la
valeur par défaut de Laravel. filter exécute le
filter_var($email, FILTER_VALIDATE_EMAIL) de PHP — le contrôle exact du guide PHP —
tandis que filter_unicode autorise certains caractères Unicode. dns ajoute une
recherche MX en direct, et spoof rejette les caractères homographes trompeurs. Vous
les combinez avec des virgules, si bien que email:rfc,dns constitue le garde-fou
pratique syntaxe-plus-domaine.
Comment vérifier qu'une boîte de réception existe dans Laravel ?#
Pas avec une règle intégrée : la confirmation de la boîte de réception nécessite une
conversation SMTP que vous ne devriez pas mener depuis votre serveur applicatif, car
le port 25 est largement bloqué et le résultat dépend de la réputation de votre IP
d'envoi. Encapsulez une API de vérification dans un objet ValidationRule
personnalisé, appelez-la avec la façade Http, lisez l'enveloppe result et échouez
sur undeliverable. Placez-la après email:rfc,dns avec bail pour qu'elle ne
s'exécute que sur les adresses ayant déjà passé les couches locales.
La règle dns va-t-elle ralentir la soumission de mes formulaires ?#
C'est possible. Le style dns effectue une recherche DNS en direct à chaque
validation : un résolveur lent ou inaccessible bloque donc la requête. C'est
acceptable pour un simple formulaire d'inscription, mais évitez-le sur les imports en
masse, et ne le cumulez pas avec un appel d'API synchrone sans avoir défini un délai
d'expiration sur le client Http — comme le fait la règle DeliverableEmail
ci-dessus avec ->timeout(10).
Prêt à ajouter la couche de la boîte de réception ? Déposez une adresse dans le
vérificateur d'e-mail gratuit pour voir une adresse approuvée
par la règle revenir non délivrable, puis câblez le même verdict dans votre
ValidationRule grâce aux exemples prêts à copier-coller de la
référence de l'API.