Skip to content
Inizia con 100 crediti di verifica gratuiti
Qualisend
Tutti gli articoli
Ingegneria / 12 giugno 2026

Validare un indirizzo email in Laravel, dalla regola alla casella

7 min di lettura

Qualisend team
Validare un indirizzo email in Laravel, dalla regola alla casella

Si è tentati di considerare la validazione di un indirizzo email in Laravel una questione da una riga: aggiungi email a un array di validazione e passi oltre. Quella regola è un buon inizio, ma risponde solo alla prima delle tre domande che pone una vera validazione. L'indirizzo ha la forma corretta? Il suo dominio può ricevere posta? La casella esiste davvero? Laravel ha la particolarità che la sua regola integrata email può rispondere alle prime due in una sola riga; la terza è un problema di rete che conviene delegare. Questa guida costruisce ogni livello sopra il validatore di Laravel e mostra esattamente dove si ferma il framework. Estende la guida alla validazione delle email in PHP: Laravel racchiude gli stessi elementi di base di PHP (e filter_var è a una parola chiave di distanza) in un'API molto più comoda.

In breve#

Usa la regola email:rfc,dns di Laravel per sintassi e ricerca MX in un solo passaggio, poi un'API di verifica per il controllo SMTP della casella: si parte dal più economico e ci si ferma con bail non appena un livello è risolutivo. Non provare ad aprire una sessione SMTP dalla tua app per testare direttamente le caselle: la porta 25 in uscita è bloccata dalla maggior parte degli host e la risposta dipende dalla reputazione dell'IP di invio e dal greylisting, cose che non vuoi reimplementare. Ogni livello esclude indirizzi a un costo minore del successivo; solo l'ultimo può confermarne uno.

Livelli 1 e 2: sintassi e DNS in una sola regola#

La regola email si appoggia al pacchetto egulias/email-validator e accetta degli stili che ne decidono il rigore. Per impostazione predefinita applica lo stile rfc (grammatica RFC 5321/5322). Quello che conta per la validazione è dns, che aggiunge una ricerca in tempo reale e conferma che il dominio si risolva in un instradamento della posta: un record MX, con un record A come ripiego. Chiedili entrambi e Laravel controlla sintassi e dominio in una sola regola:

public function store(Request $request)
{
    $validated = $request->validate([
        'email' => ['required', 'email:rfc,dns'],
    ]);

    // $validated['email'] is well-formed AND its domain can receive mail.
}

Vale la pena conoscere anche gli altri stili. email:filter esegue filter_var($email, FILTER_VALIDATE_EMAIL) di PHP, lo stesso identico controllo della guida PHP, e filter_unicode ammette alcune parti locali Unicode. strict rifiuta gli avvisi su punti finali e consecutivi che il parser RFC tollera. E spoof protegge dai caratteri omografi ingannevoli, quindi per un modulo di iscrizione pubblico email:rfc,dns,spoof è un default sensato. In una form request si scrive così:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreSubscriberRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'email' => ['required', 'email:rfc,dns,spoof'],
        ];
    }
}

Perché email:rfc,dns non è ancora un via libera#

Superare email:rfc,dns significa che la stringa è ben formata e che il dominio può ricevere posta. Non dice nulla sull'esistenza della casella specifica. noreply-9f2x@gmail.com passa. Passa anche definitely-fake@gmail.com. Entrambi sono non recapitabili, perché il record MX è un fatto che riguarda il dominio e la casella è un fatto che puoi scoprire solo chiedendolo al server di posta. È lo stesso muro che fa sì che la validazione delle email con le regex non funzioni: nessun pattern matching e nessuna ricerca DNS permettono di passare da "il dominio accetta posta" a "questo indirizzo la accetta".

Se vuoi vedere questo divario con i tuoi occhi, incolla un indirizzo sintatticamente perfetto nella verifica email gratuita e guarda una stringa approvata dalla regola tornare undeliverable.

Livello 3: la casella esiste davvero?#

Confermare una casella specifica richiede la conversazione SMTP di consegna: connettersi all'host di posta, inviare RCPT TO, leggere la risposta e disconnettersi prima di spedire qualsiasi cosa. In linea di principio potresti scriverlo in PHP, ma non dovresti eseguirlo dal tuo server applicativo: la maggior parte dei provider cloud blocca la porta 25 in uscita, la risposta dipende dalla reputazione dell'IP da cui ti connetti e i server riceventi applicano il greylisting e limitano la frequenza dei mittenti sconosciuti. E non è tutto: come funziona la verifica email illustra l'intera pipeline, compresi i domini catch-all che accettano qualsiasi indirizzo e vanificano un test ingenuo. Questo è il livello da delegare.

Chiamare Qualisend da una regola di validazione personalizzata#

Laravel rende pulita la delega: racchiudi la chiamata API in un oggetto regola e inseriscilo nello stesso array di regole. Generane uno con Artisan:

php artisan make:rule DeliverableEmail

Tieni la chiave fuori dal codice collegandola tramite config/services.php, che la legge dal tuo .env:

// config/services.php
'qualisend' => [
    'key' => env('QUALISEND_API_KEY'),
],

Poi la regola chiama l'endpoint di verifica con la facade Http, legge l'involucro result e fallisce solo quando l'esito è undeliverable:

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Facades\Http;

class DeliverableEmail implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        try {
            $response = Http::withToken(config('services.qualisend.key'))
                ->timeout(10)
                ->post('https://app.qualisend.com/api/v1/verify', ['email' => $value]);
        } catch (ConnectionException $e) {
            // A timeout or network error: let the signup through, verify later.
            return;
        }

        // 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() imposta l'intestazione di autenticazione bearer, ->post() invia il corpo JSON e $response->json('result') estrae l'oggetto annidato result con l'accesso a notazione puntata. Un timeout o un errore di connessione solleva una ConnectionException invece di restituire una risposta, quindi la regola intercetta anche quella e lascia passare l'iscrizione. Il riferimento API contiene la forma completa della richiesta, e la prima risposta si presenta così:

{
  "job_id": "5b1f3c2a-8d4e-4f6a-9b7c-2e1d0a9f8c71",
  "result": {
    "status": "unknown",
    "score": 61,
    "reason": null,
    "smtp": "pending",
    "sub_flags": { "role": false, "disposable": false, "free_mail": false, "catch_all": false }
  }
}

status è uno tra deliverable, risky, undeliverable e unknown. La regola qui sopra fa fallire solo undeliverable e lascia passare risky e unknown, così puoi decidere a valle cosa farne (filtrare in base a score o cambiare comportamento in base a una voce di sub_flags come disposable) invece di trasformare un indirizzo dubbio in un errore del modulo. Considera il JSON qui sopra come la forma, non come il contratto; l'elenco completo dei campi si trova nella documentazione per sviluppatori.

Quel primo status è l'esito immediato. Quando result.smtp è "pending", come qui sopra, il test della casella è ancora in corso e l'esito definitivo arriva su GET https://app.qualisend.com/api/v1/jobs/{job_id} appena termina. Non tenere il modulo in attesa e non richiamare /verify: conserva il job_id, interrogalo da un job in coda (fuori dal percorso della richiesta) e agisci lì su un risultato undeliverable. Quando smtp è "cached" o "skipped", result è già definitivo.

Mettere insieme i livelli per validare un indirizzo email in Laravel#

Componi tutti e tre in una sola form request, partendo dal più economico, e lascia che bail interrompa tutto al primo errore, così la regola API viene eseguita solo sugli indirizzi che hanno già superato sintassi e controllo 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.',
        ];
    }
}

Tutto il segreto sta in bail. Un indirizzo malformato o un dominio inattivo falliscono in locale e non spendono mai un credito API; al livello SMTP arrivano solo gli indirizzi che meritano il round trip di rete. Specifica il tipo della request nel tuo controller e Laravel esegue la pipeline prima ancora che parta il corpo del metodo:

public function store(StoreSubscriberRequest $request)
{
    // Every layer has passed — safe to persist.
    $subscriber = Subscriber::create($request->validated());

    return redirect()->route('subscribers.index');
}

A rendere affidabile la validazione è la stratificazione, non il framework: è la stessa struttura della versione PHP, con Laravel che riunisce i primi due livelli in una sola regola. Esegui la pipeline veloce e sincrona all'iscrizione e riserva il passaggio più lento, confermato via SMTP, al lavoro di back office: la guida all'iscrizione serverless mostra lo schema in tempo reale e come pulire una lista email copre il lato batch.

Domande frequenti

01La regola email di Laravel controlla se il dominio esiste?

Solo se glielo chiedi. La semplice regola email valida la sintassi con il pacchetto egulias/email-validator (lo stile rfc). Aggiungi lo stile dns, cioè email:rfc,dns, e Laravel conferma anche che il dominio si risolva in un instradamento della posta, quindi un dominio inventato o inattivo fallisce nello stesso passaggio. Nessuno dei due stili contatta la casella, quindi superare il controllo significa comunque "sembra recapitabile", non "recapitabile".

02Qual è la differenza tra email:rfc, email:filter ed email:dns?

rfc valida rispetto alle RFC 5321/5322 tramite egulias ed è il valore predefinito di Laravel. filter esegue filter_var($email, FILTER_VALIDATE_EMAIL) di PHP, lo stesso identico controllo della guida PHP, mentre filter_unicode ammette alcuni caratteri Unicode. dns aggiunge una ricerca MX in tempo reale e spoof rifiuta i caratteri omografi ingannevoli. Li combini con le virgole, quindi email:rfc,dns è il filtro pratico per sintassi più dominio.

03Come verifico che una casella esista in Laravel?

Non con una regola integrata: la conferma della casella richiede una conversazione SMTP che non dovresti eseguire dal tuo server applicativo, perché la porta 25 è bloccata quasi ovunque e il risultato dipende dalla reputazione del tuo IP di invio. Racchiudi un'API di verifica in un oggetto ValidationRule personalizzato, chiamala con la facade Http, leggi l'involucro result e fai fallire la regola su undeliverable. Mettila dopo email:rfc,dns con bail, così viene eseguita solo sugli indirizzi che hanno già superato i livelli locali. Se result.smtp torna pending, il test della casella è ancora in corso: leggi l'esito definitivo da GET /api/v1/jobs/{job_id} in un job in coda, non dentro il validatore.

04La regola dns rallenterà l'invio dei miei moduli?

Può succedere. Lo stile dns esegue una ricerca DNS in tempo reale a ogni validazione, quindi un resolver lento o irraggiungibile blocca la richiesta. Per un singolo modulo di iscrizione va bene, ma evitalo nelle importazioni in blocco e non combinarlo con una chiamata API sincrona senza aver impostato un timeout sul client Http, come fa la regola DeliverableEmail qui sopra con ->timeout(10).


Vuoi aggiungere il livello della casella? Inserisci un indirizzo nella verifica email gratuita per vedere un indirizzo approvato dalla regola risultare non recapitabile, poi collega lo stesso esito alla tua ValidationRule con gli esempi pronti da copiare e incollare nel riferimento API.

La tua reputazione, protetta.

Pulisci la tua prima lista in pochi minuti. 100 crediti gratuiti, senza carta di credito.

Inizia