Validazione

Introduzione

Laravel offre diversi approcci per validare i dati in arrivo della tua applicazione. Il metodo più comune è utilizzare validate, disponibile in tutte le richieste HTTP in entrata. Tuttavia, discuteremo anche altri metodi di validazione.

Laravel include una vasta gamma di regole di validazione utili che puoi applicare ai dati, offrendo anche la possibilità di verificare se i valori sono unici in una determinata tabella del database. Tratteremo ciascuna di queste regole di validazione in dettaglio, così da farti conoscere tutte le funzionalità di validazione di Laravel.

Avvio Veloce della Validazione

Per conoscere le potenti funzionalità di validazione di Laravel, esaminiamo un esempio completo di validazione di un modulo e visualizzazione dei messaggi di errore all’utente. Leggendo questa panoramica generale, potrai ottenere una buona comprensione di come validare i dati delle richieste in arrivo utilizzando Laravel:

Definire le Route

Per prima cosa, supponiamo di avere le seguenti route definite nel nostro file routes/web.php:

use App\Http\Controllers\PostController;

Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);

La route GET mostrerà un modulo per permettere all’utente di creare un nuovo post del blog, mentre la route POST salverà il nuovo post nel database.

Creazione del Controller

Successivamente, diamo un’occhiata a un controller semplice che gestisce le richieste in arrivo a queste rotte. Lasceremo il metodo store vuoto per ora:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PostController extends Controller
{
    /**
     * Mostra il modulo per creare un nuovo post del blog.
     */
    public function create(): View
    {
        return view('post.create');
    }

    /**
     * Memorizza un nuovo post del blog.
     */
    public function store(Request $request): RedirectResponse
    {
        // Valida e memorizza il post del blog...

        $post = /** ... */

        return to_route('post.show', ['post' => $post->id]);
    }
}

Scrivere la Logica di Validazione

Ora siamo pronti a completare il nostro metodo store con la logica per validare il nuovo post del blog. Per fare questo, useremo il metodo validate fornito dall’oggetto Illuminate\Http\Request. Se le regole di validazione vengono superate, il tuo codice continuerà a eseguire normalmente; tuttavia, se la validazione fallisce, verrà lanciata un’eccezione Illuminate\Validation\ValidationException e la risposta di errore appropriata sarà inviata automaticamente all’utente.

Se la validazione fallisce durante una richiesta HTTP tradizionale, verrà generata una risposta di reindirizzamento all’URL precedente. Se la richiesta in arrivo è una richiesta XHR, verrà restituita una risposta JSON contenente i messaggi di errore di validazione.

Per capire meglio il metodo validate, torniamo al metodo store:

/**
 * Memorizza un nuovo post del blog.
 */
public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // Il post del blog è valido...

    return redirect('/posts');
}

Come puoi vedere, le regole di validazione vengono passate al metodo validate. Non preoccuparti – tutte le regole di validazione disponibili sono documentate. Ancora una volta, se la validazione fallisce, la risposta appropriata verrà generata automaticamente. Se la validazione ha successo, il nostro controller continuerà a eseguire normalmente.

In alternativa, le regole di validazione possono essere specificate come array di regole invece che come una singola stringa delimitata da |:

$validatedData = $request->validate([
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required'],
]);

Inoltre, puoi usare il metodo validateWithBag per validare una richiesta e memorizzare i messaggi di errore all’interno di un error bag:

$validatedData = $request->validateWithBag('post', [
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required'],
]);

Interrompere al Primo Fallimento della Validazione

A volte potresti voler interrompere l’esecuzione delle regole di validazione su un attributo dopo il primo fallimento. Per farlo, assegna la regola bail all’attributo:

    $request->validate([
        'title' => 'bail|required|unique:posts|max:255',
        'body' => 'required',
    ]);

In questo esempio, se la regola unique sull’attributo title fallisce, la regola max non verrà verificata. Le regole saranno validate nell’ordine in cui sono assegnate.

Nota sugli attributi annidati

Se la richiesta HTTP in arrivo include dati di campo "annidati", puoi specificare questi campi nelle tue regole di validazione usando la sintassi a punto:

    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'author.name' => 'required',
        'author.description' => 'required',
    ]);

Tuttavia, se il nome del tuo campo contiene un punto letterale, puoi evitare che venga interpretato come sintassi a punto aggiungendo una barra rovesciata prima del punto:

    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'v1\.0' => 'required',
    ]);

Visualizzazione degli Errori di Validazione

Allora, cosa succede se i campi della richiesta in arrivo non soddisfano le regole di validazione? Come menzionato in precedenza, Laravel reindirizzerà automaticamente l’utente alla sua posizione precedente. Inoltre, tutti gli errori di validazione e l’input della richiesta verranno automaticamente memorizzati nella sessione.

Una variabile $errors è condivisa con tutte le viste della tua applicazione dal middleware Illuminate\View\Middleware\ShareErrorsFromSession, fornito dal gruppo middleware web. Quando questo middleware è applicato, una variabile $errors sarà sempre disponibile nelle tue viste, permettendoti di presumere comodamente che la variabile $errors sia sempre definita e possa essere usata in sicurezza. La variabile $errors sarà un’istanza di Illuminate\Support\MessageBag. Per maggiori informazioni su come lavorare con questo oggetto, consulta la sua documentazione.

Quindi, nel nostro esempio, l’utente verrà reindirizzato al metodo create del nostro controller quando la validazione fallisce, permettendoci di mostrare i messaggi di errore nella vista:

<!-- /resources/views/post/create.blade.php -->

<h1>Create Post</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- Create Post Form -->

Personalizzare i Messaggi di Errore

Le regole di validazione predefinite di Laravel hanno ciascuno un messaggio di errore che si trova nel file lang/en/validation.php della tua applicazione. Se la tua applicazione non ha una directory lang, puoi far sì che Laravel la crei usando il comando Artisan lang:publish.

All’interno del file lang/en/validation.php, troverai un’associazione per ogni regola di validazione. Puoi modificare questi messaggi secondo le esigenze della tua applicazione.

Inoltre, puoi copiare questo file in un’altra directory di lingua per tradurre i messaggi nella lingua della tua applicazione. Per saperne di più sulla localizzazione in Laravel, consulta la documentazione completa sulla localizzazione.

Di default, lo scheletro dell’applicazione Laravel non include la directory lang. Se desideri personalizzare i file di lingua di Laravel, puoi pubblicarli tramite il comando Artisan lang:publish.

Richieste XHR e Validazione

In questo esempio, abbiamo usato un modulo tradizionale per inviare dati all’applicazione. Tuttavia, molte applicazioni ricevono richieste XHR da un frontend basato su JavaScript. Quando si utilizza il metodo validate durante una richiesta XHR, Laravel non genererà una risposta di reindirizzamento. Invece, Laravel genera una risposta JSON contenente tutti gli errori di validazione. Questa risposta JSON verrà inviata con un codice di stato HTTP 422.

La direttiva @error

Puoi usare la direttiva @error di Blade per verificare rapidamente se esistono messaggi di errore di validazione per un determinato attributo. All’interno di una direttiva @error, puoi stampare la variabile $message per mostrare il messaggio di errore:

<!-- /resources/views/post/create.blade.php -->

<label for="title">Titolo del Post</label>

<input
    id="title"
    type="text"
    name="title"
    class="@error('title') is-invalid @enderror"
/>

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

Se stai usando error bag, puoi passare il nome dell’error bag come secondo argomento alla direttiva @error:

<input ... class="@error('title', 'post') is-invalid @enderror">

Ripopolare i Moduli

Quando Laravel genera una risposta di reindirizzamento a causa di un errore di validazione, il framework memorizza temporaneamente tutti i dati della richiesta nella sessione. Questo permette di accedere facilmente ai dati nella richiesta successiva e ripopolare il modulo che l’utente ha tentato di inviare.

Per recuperare i dati memorizzati dalla richiesta precedente, utilizza il metodo old su un’istanza di Illuminate\Http\Request. Il metodo old recupera i dati precedentemente memorizzati nella sessione:

$title = $request->old('title');

Laravel fornisce anche un helper globale old. Se stai mostrando dati precedenti all’interno di un template Blade, è più comodo usare l’helper old per ripopolare il modulo. Se non esistono dati precedenti per il campo specificato, verrà restituito null:

<input type="text" name="title" value="{{ old('title') }}">

Una nota sui campi facoltativi

Per impostazione predefinita, Laravel include i middleware TrimStrings e ConvertEmptyStringsToNull nello stack dei middleware globali della tua applicazione. Per questo motivo, spesso sarà necessario contrassegnare i campi di richiesta "facoltativi" come nullable se non vuoi che il validatore consideri i valori null come non validi. Ad esempio:

    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
        'publish_at' => 'nullable|date',
    ]);

In questo esempio, specifichiamo che il campo publish_at può essere null oppure una rappresentazione valida di una data. Se il modificatore nullable non viene aggiunto alla definizione della regola, il validatore considererebbe null come una data non valida.

Formato di Risposta per Errori di Validazione

Quando la tua applicazione genera un’eccezione Illuminate\Validation\ValidationException e la richiesta HTTP in arrivo si aspetta una risposta JSON, Laravel formatterà automaticamente i messaggi di errore per te e restituirà una risposta HTTP 422 Unprocessable Entity.

Di seguito puoi vedere un esempio del formato di risposta JSON per errori di validazione. Nota che le chiavi degli errori annidati sono appiattite nel formato a notazione "puntata":

{
    "message": "Il nome del team deve essere una stringa. (e altri 4 errori)",
    "errors": {
        "team_name": [
            "Il nome del team deve essere una stringa.",
            "Il nome del team deve avere almeno 1 carattere."
        ],
        "authorization.role": [
            "Il ruolo authorization.role selezionato non è valido."
        ],
        "users.0.email": [
            "Il campo users.0.email è obbligatorio."
        ],
        "users.2.email": [
            "Il campo users.2.email deve essere un indirizzo email valido."
        ]
    }
}

Validazione delle richieste del form

Creare le Form Request

Per scenari di validazione più complessi, potresti voler creare una "form request". Le form requests sono classi di richiesta personalizzate che incapsulano la propria logica di validazione e autorizzazione. Per creare una classe di form request, puoi usare il comando CLI Artisan make:request:

php artisan make:request StorePostRequest

La classe di form request generata verrà posizionata nella directory app/Http/Requests. Se questa directory non esiste, verrà creata quando esegui il comando make:request. Ogni form request generata da Laravel ha due metodi: authorize e rules.

Come avrai capito, il metodo authorize è responsabile di determinare se l’utente autenticato può eseguire l’azione rappresentata dalla richiesta, mentre il metodo rules restituisce le regole di validazione che dovrebbero applicarsi ai dati della richiesta:

    /**
     * Ottieni le regole di validazione che si applicano alla richiesta.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ];
    }

Puoi specificare qualsiasi dipendenza necessaria all’interno della firma del metodo rules tramite type-hinting. Saranno risolte automaticamente tramite il service container di Laravel.

Allora, come vengono valutate le regole di validazione? Tutto ciò che devi fare è specificare la richiesta nel metodo del tuo controller. La form request in arrivo viene validata prima che il metodo del controller venga chiamato, il che significa che non devi ingombrare il tuo controller con la logica di validazione:

    /**
     * Salva un nuovo post nel blog.
     */
    public function store(StorePostRequest $request): RedirectResponse
    {
        // La richiesta in arrivo è valida...

        // Recupera i dati di input validati...
        $validated = $request->validated();

        // Recupera una parte dei dati di input validati...
        $validated = $request->safe()->only(['name', 'email']);
        $validated = $request->safe()->except(['name', 'email']);

        // Salva il post nel blog...

        return redirect('/posts');
    }

Se la validazione fallisce, verrà generata una risposta di reindirizzamento per inviare l’utente alla posizione precedente. Gli errori verranno anche salvati nella sessione in modo che siano disponibili per la visualizzazione. Se la richiesta era una richiesta XHR, verrà restituita una risposta HTTP con codice di stato 422 che include una rappresentazione JSON degli errori di validazione.

Hai bisogno di aggiungere la validazione in tempo reale delle form request al tuo frontend Laravel basato su Inertia? Dai un’occhiata a Laravel Precognition.

Esecuzione di Validazioni Aggiuntive

A volte è necessario eseguire ulteriori validazioni dopo che la validazione iniziale è completata. Puoi fare ciò utilizzando il metodo after della richiesta di form.

Il metodo after dovrebbe restituire un array di callable o closure che verranno invocati dopo il completamento della validazione. I callable forniti riceveranno un’istanza di Illuminate\Validation\Validator, permettendoti di aggiungere ulteriori messaggi di errore se necessario:

use Illuminate\Validation\Validator;

/**
 * Ottieni i callable di validazione "after" per la richiesta.
 */
public function after(): array
{
    return [
        function (Validator $validator) {
            if ($this->somethingElseIsInvalid()) {
                $validator->errors()->add(
                    'field',
                    'Qualcosa non va con questo campo!'
                );
            }
        }
    ];
}

Come notato, l’array restituito dal metodo after può anche contenere classi invocabili. Il metodo __invoke di queste classi riceverà un’istanza di Illuminate\Validation\Validator:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
use Illuminate\Validation\Validator;

/**
 * Ottieni i callable di validazione "after" per la richiesta.
 */
public function after(): array
{
    return [
        new ValidateUserStatus,
        new ValidateShippingTime,
        function (Validator $validator) {
            //
        }
    ];
}

Fermarsi al primo fallimento della validazione

Aggiungendo una proprietà stopOnFirstFailure alla tua classe di richiesta, puoi informare il validatore di interrompere la validazione di tutti gli attributi non appena si verifica un singolo fallimento di validazione:

/**
 * Indica se il validatore deve fermarsi al primo fallimento della regola.
 *
 * @var bool
 */
protected $stopOnFirstFailure = true;

Personalizzare la Posizione di Reindirizzamento

Come discusso in precedenza, verrà generata una risposta di reindirizzamento per riportare l’utente alla posizione precedente quando la validazione della richiesta del modulo fallisce. Tuttavia, puoi personalizzare questo comportamento. Per farlo, definisci una proprietà $redirect nella tua richiesta del modulo:

    /**
     * L'URI a cui gli utenti saranno reindirizzati se la validazione fallisce.
     *
     * @var string
     */
    protected $redirect = '/dashboard';

Oppure, se desideri reindirizzare gli utenti a una route nominata, puoi definire invece una proprietà $redirectRoute:

    /**
     * La route a cui gli utenti saranno reindirizzati se la validazione fallisce.
     *
     * @var string
     */
    protected $redirectRoute = 'dashboard';

Autorizzare le Form Request

La classe di richiesta form contiene anche un metodo authorize. All’interno di questo metodo, puoi determinare se l’utente autenticato ha effettivamente l’autorità per aggiornare una risorsa specifica. Ad esempio, puoi verificare se un utente possiede effettivamente un commento del blog che sta tentando di aggiornare. Probabilmente, interagirai con le tue porte e politiche di autorizzazione all’interno di questo metodo:

use App\Models\Comment;

/**
 * Determina se l'utente è autorizzato a fare questa richiesta.
 */
public function authorize(): bool
{
    $comment = Comment::find($this->route('comment'));

    return $comment && $this->user()->can('update', $comment);
}

Poiché tutte le richieste di form estendono la classe di richiesta base di Laravel, possiamo usare il metodo user per accedere all’utente attualmente autenticato. Inoltre, nota la chiamata al metodo route nell’esempio sopra. Questo metodo ti permette di accedere ai parametri URI definiti sulla route chiamata, come il parametro {comment} nell’esempio seguente:

Route::post('/comment/{comment}');

Pertanto, se la tua applicazione sfrutta il route model binding, il tuo codice può essere reso ancora più conciso accedendo al modello risolto come proprietà della richiesta:

return $this->user()->can('update', $this->comment);

Se il metodo authorize restituisce false, verrà automaticamente restituita una risposta HTTP con codice di stato 403 e il tuo metodo del controller non verrà eseguito.

Se prevedi di gestire la logica di autorizzazione per la richiesta in un’altra parte della tua applicazione, puoi rimuovere completamente il metodo authorize, o semplicemente restituire true:

/**
 * Determina se l'utente è autorizzato a fare questa richiesta.
 */
public function authorize(): bool
{
    return true;
}

Puoi specificare il tipo di qualsiasi dipendenza di cui hai bisogno nella firma del metodo authorize. Verranno automaticamente risolte tramite il service container di Laravel.

Personalizzazione dei Messaggi di Errore

Puoi personalizzare i messaggi di errore utilizzati dalla richiesta del form sovrascrivendo il metodo messages. Questo metodo deve restituire un array di coppie attributo/regola e i relativi messaggi di errore:

/**
 * Ottiene i messaggi di errore per le regole di validazione definite.
 *
 * @return array<string, string>
 */
public function messages(): array
{
    return [
        'title.required' => 'Il titolo è obbligatorio',
        'body.required' => 'Un messaggio è obbligatorio',
    ];
}

Personalizzare gli attributi di validazione

Molti messaggi di errore delle regole di validazione di Laravel contengono un segnaposto :attribute. Se vuoi che il segnaposto :attribute nel tuo messaggio di validazione venga sostituito con un nome di attributo personalizzato, puoi specificare i nomi personalizzati sovrascrivendo il metodo attributes. Questo metodo deve restituire un array di coppie attributo/nome:

/**
 * Get custom attributes for validator errors.
 *
 * @return array<string, string>
 */
public function attributes(): array
{
    return [
        'email' => 'email address',
    ];
}

Preparazione dell’Input per la Validazione

Se hai bisogno di preparare o sanificare qualsiasi dato dalla request prima di applicare le tue regole di validazione, puoi usare il metodo prepareForValidation:

use Illuminate\Support\Str;

/**
 * Prepara i dati per la validazione.
 */
protected function prepareForValidation(): void
{
    $this->merge([
        'slug' => Str::slug($this->slug),
    ]);
}

Allo stesso modo, se hai bisogno di normalizzare qualsiasi dato della request dopo che la validazione è completa, puoi usare il metodo passedValidation:

/**
 * Gestisce un tentativo di validazione riuscito.
 */
protected function passedValidation(): void
{
    $this->replace(['name' => 'Taylor']);
}

Creazione Manuale dei Validator

Se non desideri utilizzare il metodo validate sulla richiesta, puoi creare manualmente un’istanza di validator utilizzando la facade Validator. Il metodo make sulla facade genera una nuova istanza di validator:

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class PostController extends Controller
{
    /**
     * Memorizza un nuovo post nel blog.
     */
    public function store(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

        if ($validator->fails()) {
            return redirect('/post/create')
                        ->withErrors($validator)
                        ->withInput();
        }

        // Recupera i dati validati...
        $validated = $validator->validated();

        // Recupera una parte dei dati validati...
        $validated = $validator->safe()->only(['name', 'email']);
        $validated = $validator->safe()->except(['name', 'email']);

        // Memorizza il post nel blog...

        return redirect('/posts');
    }
}

Il primo argomento passato al metodo make sono i dati da validare. Il secondo argomento è un array delle regole di validazione che devono essere applicate ai dati.

Dopo aver determinato se la validazione della richiesta è fallita, puoi utilizzare il metodo withErrors per inviare i messaggi di errore alla sessione. Quando utilizzi questo metodo, la variabile $errors sarà automaticamente condivisa con le tue viste dopo il reindirizzamento, permettendoti di mostrarle facilmente all’utente. Il metodo withErrors accetta un validator, un MessageBag o un array PHP.

Interrompere al Primo Fallimento di Validazione

Il metodo stopOnFirstFailure informa il validatore che deve interrompere la validazione di tutti gli attributi una volta che si è verificato un singolo fallimento di validazione:

if ($validator->stopOnFirstFailure()->fails()) {
    // ...
}

Reindirizzamento Automatico

Se desideri creare un’istanza del validatore manualmente ma sfruttare comunque il reindirizzamento automatico offerto dal metodo validate della richiesta HTTP, puoi chiamare il metodo validate su un’istanza di validatore esistente. Se la validazione fallisce, l’utente verrà automaticamente reindirizzato oppure, nel caso di una richiesta XHR, verrà restituita una risposta JSON:

    Validator::make($request->all(), [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ])->validate();

Puoi usare il metodo validateWithBag per memorizzare i messaggi di errore in un contenitore di errori nominato se la validazione fallisce:

    Validator::make($request->all(), [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ])->validateWithBag('post');

Sacche di Errori Nominati

Se hai più form su una singola pagina, potresti voler nominare il MessageBag che contiene gli errori di validazione, permettendoti di recuperare i messaggi di errore per un form specifico. Per fare ciò, passa un nome come secondo argomento a withErrors:

    return redirect('/register')->withErrors($validator, 'login');

Puoi quindi accedere all’istanza del MessageBag nominato dalla variabile $errors:

{{ $errors->login->first('email') }}

Personalizzazione dei Messaggi di Errore

Se necessario, puoi fornire messaggi di errore personalizzati che un’istanza del validatore dovrebbe utilizzare al posto dei messaggi di errore predefiniti forniti da Laravel. Ci sono diversi modi per specificare messaggi personalizzati. Prima di tutto, puoi passare i messaggi personalizzati come terzo argomento al metodo Validator::make:

    $validator = Validator::make($input, $rules, $messages = [
        'required' => 'Il campo :attribute è obbligatorio.',
    ]);

In questo esempio, il segnaposto :attribute verrà sostituito con il nome effettivo del campo in fase di validazione. Puoi anche utilizzare altri segnaposti nei messaggi di validazione. Per esempio:

    $messages = [
        'same' => 'Il :attribute e :other devono corrispondere.',
        'size' => 'Il :attribute deve essere esattamente :size.',
        'between' => 'Il valore :input di :attribute non è compreso tra :min - :max.',
        'in' => 'Il :attribute deve essere uno dei seguenti tipi: :values',
    ];

Specificare un Messaggio Personalizzato per un Attributo

A volte vuoi impostare un messaggio di errore personalizzato solo per un determinato attributo. Puoi farlo utilizzando la notazione a punti. Specifica prima il nome dell’attributo, seguito dalla regola:

$messages = [
    'email.required' => 'We need to know your email address!',
];

Specificare Valori Personalizzati per gli Attributi

Molti dei messaggi di errore predefiniti di Laravel includono un segnaposto :attribute che viene sostituito con il nome del campo o attributo in fase di validazione. Per personalizzare i valori usati per sostituire questi segnaposto per campi specifici, puoi passare un array di attributi personalizzati come quarto argomento al metodo Validator::make:

$validator = Validator::make($input, $rules, $messages, [
    'email' => 'email address',
]);

Eseguire una Validazione Aggiuntiva

A volte è necessario eseguire una validazione aggiuntiva dopo che la validazione iniziale è stata completata. Puoi fare ciò utilizzando il metodo after del validator. Il metodo after accetta una closure o un array di callable che verranno invocati una volta completata la validazione. I callable forniti riceveranno un’istanza di Illuminate\Validation\Validator, permettendoti di aggiungere messaggi di errore aggiuntivi se necessario:

    use Illuminate\Support\Facades\Validator;

    $validator = Validator::make(/* ... */);

    $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add(
                'field', 'Something is wrong with this field!'
            );
        }
    });

    if ($validator->fails()) {
        // ...
    }

Come accennato, il metodo after accetta anche un array di callable, il che è particolarmente comodo se la tua logica di "validazione aggiuntiva" è incapsulata in classi invocabili, le quali riceveranno un’istanza di Illuminate\Validation\Validator tramite il loro metodo __invoke:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;

$validator->after([
    new ValidateUserStatus,
    new ValidateShippingTime,
    function ($validator) {
        // ...
    },
]);

Lavorare con Input Validati

Dopo aver validato i dati della richiesta in entrata utilizzando una richiesta di modulo o un’istanza del validatore creata manualmente, potresti voler recuperare i dati della richiesta che sono effettivamente stati validati. Questo può essere fatto in diversi modi. Innanzitutto, puoi chiamare il metodo validated su una richiesta di modulo o un’istanza del validatore. Questo metodo restituisce un array dei dati che sono stati validati:

    $validated = $request->validated();
    
    $validated = $validator->validated();

In alternativa, puoi chiamare il metodo safe su una richiesta di modulo o un’istanza del validatore. Questo metodo restituisce un’istanza di Illuminate\Support\ValidatedInput. Questo oggetto offre i metodi only, except e all per recuperare un sottoinsieme dei dati validati o l’intero array dei dati validati:

    $validated = $request->safe()->only(['name', 'email']);
    
    $validated = $request->safe()->except(['name', 'email']);
    
    $validated = $request->safe()->all();

Inoltre, l’istanza di Illuminate\Support\ValidatedInput può essere iterata e accessibile come un array:

    // Validated data may be iterated...
    foreach ($request->safe() as $key => $value) {
        // ...
    }
    
    // Validated data may be accessed as an array...
    $validated = $request->safe();
    
    $email = $validated['email'];

Se desideri aggiungere campi aggiuntivi ai dati validati, puoi chiamare il metodo merge:

    $validated = $request->safe()->merge(['name' => 'Taylor Otwell']);

Se desideri recuperare i dati validati come un’istanza di collection, puoi chiamare il metodo collect:

    $collection = $request->safe()->collect();

Gestire i Messaggi di Errore

Dopo aver chiamato il metodo errors su un’istanza di Validator, otterrai un’istanza di Illuminate\Support\MessageBag, che offre diversi metodi utili per gestire i messaggi di errore. La variabile $errors che è resa automaticamente disponibile in tutte le viste è anch’essa un’istanza della classe MessageBag.

Recuperare il Primo Messaggio di Errore per un Campo

Per recuperare il primo messaggio di errore per un determinato campo, usa il metodo first:

$errors = $validator->errors();

echo $errors->first('email');

Recuperare Tutti i Messaggi di Errore per un Campo

Se hai bisogno di ottenere un array di tutti i messaggi per un determinato campo, usa il metodo get:

foreach ($errors->get('email') as $message) {
    // ...
}

Se stai validando un campo di tipo array nel form, puoi recuperare tutti i messaggi per ogni elemento dell’array usando il carattere *:

foreach ($errors->get('attachments.*') as $message) {
    // ...
}

Recuperare Tutti i Messaggi di Errore per Tutti i Campi

Per ottenere un array di tutti i messaggi per tutti i campi, utilizza il metodo all:

foreach ($errors->all() as $message) {
    // ...
}

Verificare se esistono Messaggi per un Campo

Il metodo has può essere utilizzato per verificare se ci sono messaggi di errore per un determinato campo:

if ($errors->has('email')) {
    // ...
}

Specificare Messaggi Personalizzati nei File di Lingua

Le regole di validazione integrate di Laravel hanno ciascuno un messaggio di errore situato nel file lang/en/validation.php della tua applicazione. Se la tua applicazione non ha una directory lang, puoi chiedere a Laravel di crearla usando il comando Artisan lang:publish.

All’interno del file lang/en/validation.php, troverai una voce di traduzione per ogni regola di validazione. Puoi modificare questi messaggi in base alle esigenze della tua applicazione.

Inoltre, puoi copiare questo file in un’altra directory di lingua per tradurre i messaggi nella lingua della tua applicazione. Per saperne di più sulla localizzazione in Laravel, consulta la documentazione completa sulla localizzazione.

Di default, lo scheletro dell’applicazione Laravel non include la directory lang. Se desideri personalizzare i file di lingua di Laravel, puoi pubblicarli tramite il comando Artisan lang:publish.

Messaggi Personalizzati per Attributi Specifici

Puoi personalizzare i messaggi di errore utilizzati per combinazioni specifiche di attributi e regole nei file di lingua per la validazione della tua applicazione. Per farlo, aggiungi le tue personalizzazioni dei messaggi all’array custom nel file di lingua lang/xx/validation.php della tua applicazione:

'custom' => [
    'email' => [
        'required' => 'We need to know your email address!',
        'max' => 'Your email address is too long!'
    ],
],

Specificare gli Attributi nei File di Lingua

Molti dei messaggi di errore predefiniti di Laravel includono un placeholder :attribute che viene sostituito con il nome del campo o dell’attributo in fase di validazione. Se desideri che la parte :attribute del tuo messaggio di validazione venga sostituita con un valore personalizzato, puoi specificare il nome dell’attributo personalizzato nell’array attributes del tuo file di lingua lang/xx/validation.php:

'attributes' => [
    'email' => 'indirizzo email',
],

Di default, lo scheletro dell’applicazione Laravel non include la directory lang. Se desideri personalizzare i file di lingua di Laravel, puoi pubblicarli tramite il comando Artisan lang:publish.

Specificare i Valori nei File di Lingua

Alcuni dei messaggi di errore delle regole di validazione incluse in Laravel contengono un segnaposto :value che viene sostituito con il valore corrente dell’attributo della richiesta. Tuttavia, potrebbe succedere di dover sostituire la parte :value del messaggio di validazione con una rappresentazione personalizzata del valore. Ad esempio, considera la seguente regola che specifica che è richiesto un numero di carta di credito se payment_type ha il valore cc:

Validator::make($request->all(), [
    'credit_card_number' => 'required_if:payment_type,cc'
]);

Se questa regola di validazione fallisce, verrà prodotto il seguente messaggio di errore:

Il campo numero della carta di credito è richiesto quando il tipo di pagamento è cc.

Invece di mostrare cc come valore del tipo di pagamento, puoi specificare una rappresentazione più comprensibile del valore nel tuo file di lingua lang/xx/validation.php definendo un array values:

'values' => [
    'payment_type' => [
        'cc' => 'credit card'
    ],
],

Per impostazione predefinita, lo scheletro dell’applicazione Laravel non include la directory lang. Se desideri personalizzare i file di lingua di Laravel, puoi pubblicarli tramite il comando Artisan lang:publish.

Dopo aver definito questo valore, la regola di validazione produrrà il seguente messaggio di errore:

Il campo numero della carta di credito è richiesto quando il tipo di pagamento è credit card.

Regole di Validazione Disponibili

Di seguito è riportato un elenco di tutte le regole di validazione disponibili e delle loro funzioni:

Accepted Accepted If Active URL After (Date) After Or Equal (Date) Alpha Alpha Dash Alpha Numeric Array Ascii Bail Before (Date) Before Or Equal (Date) Between Boolean Confirmed Contains Current Password Date Date Equals Date Format Decimal Declined Declined If Different Digits Digits Between Dimensions (Image Files) Distinct Doesnt Start With Doesnt End With Email Ends With Enum Exclude Exclude If Exclude Unless Exclude With Exclude Without Exists (Database) Extensions File Filled Greater Than Greater Than Or Equal Hex Color Image (File) In In Array Integer IP Address JSON Less Than Less Than Or Equal List Lowercase MAC Address Max Max Digits MIME Types MIME Type By File Extension Min Min Digits Missing Missing If Missing Unless Missing With Missing With All Multiple Of Not In Not Regex Nullable Numeric Present Present If Present Unless Present With Present With All Prohibited Prohibited If Prohibited Unless Prohibits Regular Expression Required Required If Required If Accepted Required If Declined Required Unless Required With Required With All Required Without Required Without All Required Array Keys Same Size Sometimes Starts With String Timezone Unique (Database) Uppercase URL ULID UUID

accepted

Il campo sottoposto a validazione deve essere "yes", "on", 1, "1", true o "true". Questo è utile per convalidare l’accettazione dei "Termini di Servizio" o campi simili.

accepted_if:anotherfield,value,…

Il campo da validare deve essere "yes", "on", 1, "1", true o "true" se un altro campo da validare è uguale a un valore specificato. Questo è utile per verificare l’accettazione dei "Termini di Servizio" o campi simili.

active_url

Il campo in fase di validazione deve avere un record A o AAAA valido secondo la funzione PHP dns_get_record. Il nome host dell’URL fornito viene estratto utilizzando la funzione PHP parse_url prima di essere passato a dns_get_record.

after:date

Il campo da validare deve essere una data successiva a una data specificata. Le date verranno passate alla funzione PHP strtotime per essere convertite in un’istanza valida di DateTime:

    'start_date' => 'required|date|after:tomorrow'

Invece di passare una stringa di data da valutare con strtotime, puoi specificare un altro campo con cui confrontare la data:

    'finish_date' => 'required|date|after:start_date'

after_or_equal:date

Il campo in fase di validazione deve essere una data successiva o uguale alla data specificata. Per maggiori informazioni, consulta la regola after.

alpha

Il campo da validare deve contenere solo caratteri alfabetici Unicode inclusi in \p{L} e \p{M}.

Per limitare questa regola di validazione ai caratteri nell’intervallo ASCII (a-z e A-Z), puoi usare l’opzione ascii nella regola di validazione:

'username' => 'alpha:ascii',

alpha_dash

Il campo deve contenere solo caratteri alfanumerici Unicode, inclusi \p{L}, \p{M}, \p{N}, oltre a trattini (-) e underscore (_) ASCII.

Per limitare questa regola ai soli caratteri ASCII (a-z e A-Z), puoi aggiungere l’opzione ascii alla regola di validazione:

'username' => 'alpha_dash:ascii',

alpha_num

Il campo da validare deve contenere solo caratteri alfanumerici Unicode presenti in \p{L}, \p{M}, e \p{N}.

Per limitare questa regola di validazione ai caratteri dell’intervallo ASCII (a-z e A-Z), puoi usare l’opzione ascii nella regola di validazione:

'username' => 'alpha_num:ascii',

array

Il campo da validare deve essere un array PHP.

Quando vengono forniti valori aggiuntivi alla regola array, ogni chiave nell’array di input deve essere presente nella lista dei valori forniti alla regola. Nell’esempio seguente, la chiave admin nell’array di input non è valida poiché non è inclusa nella lista dei valori forniti alla regola array:

    use Illuminate\Support\Facades\Validator;

    $input = [
        'user' => [
            'name' => 'Taylor Otwell',
            'username' => 'taylorotwell',
            'admin' => true,
        ],
    ];

    Validator::make($input, [
        'user' => 'array:name,username',
    ]);

In generale, dovresti sempre specificare le chiavi dell’array che possono essere presenti nel tuo array.

ascii

Il campo in fase di validazione deve contenere esclusivamente caratteri ASCII a 7 bit.

bail

Interrompe l’esecuzione delle regole di validazione per il campo dopo il primo fallimento.

Mentre la regola bail fermerà la validazione di un campo specifico quando incontra un fallimento, il metodo stopOnFirstFailure informa il validator di interrompere la validazione di tutti gli attributi una volta che si verifica un singolo fallimento di validazione:

    if ($validator->stopOnFirstFailure()->fails()) {
        // ...
    }

before:date

Il campo da validare deve essere un valore antecedente alla data specificata. Le date vengono passate alla funzione PHP strtotime per essere convertite in un’istanza valida di DateTime. Inoltre, come la regola after, può essere fornito il nome di un altro campo da validare come valore di date.

before_or_equal:date

Il campo in fase di validazione deve essere un valore precedente o uguale alla data fornita. Le date saranno passate alla funzione PHP strtotime per essere convertite in un’istanza valida di DateTime. Inoltre, come la regola after, può essere fornito il nome di un altro campo in fase di validazione come valore di date.

between:min,max

Il campo deve avere una dimensione compresa tra min e max (inclusi). Stringhe, numerici, array e file vengono valutati allo stesso modo della regola size.

boolean

Il campo sotto validazione deve poter essere convertito in un boolean. Gli input accettati sono true, false, 1, 0, "1" e "0".

confirmed

Il campo soggetto alla validazione deve avere un campo corrispondente chiamato {field}_confirmation. Ad esempio, se il campo soggetto alla validazione è password, deve essere presente un campo password_confirmation nell’input.

Puoi anche specificare un nome personalizzato per il campo di conferma. Ad esempio, confirmed:repeat_username richiederà che il campo repeat_username corrisponda al campo soggetto alla validazione.

contains:foo,bar,…

Il campo sotto validazione deve essere un array che contiene tutti i valori dei parametri forniti.

current_password

Il campo da validare deve corrispondere alla password dell’utente autenticato. Puoi specificare un authentication guard usando il primo parametro della regola:

'password' => 'current_password:api'

data

Il campo da validare deve essere una data valida e non relativa secondo la funzione PHP strtotime.

date_equals:date

Il campo in validazione deve essere uguale alla data specificata. Le date verranno passate alla funzione PHP strtotime per essere convertite in un’istanza valida di DateTime.

date_format:format,…

Il campo in validazione deve corrispondere a uno dei formati forniti. Devi usare o date o date_format quando validi un campo, non entrambi. Questa regola di validazione supporta tutti i formati supportati dalla classe DateTime di PHP.

decimal:min,max

Il campo in validazione deve essere numerico e deve contenere il numero specificato di cifre decimali:

// Deve avere esattamente due cifre decimali (9.99)...
'price' => 'decimal:2'

// Deve avere tra 2 e 4 cifre decimali...
'price' => 'decimal:2,4'

rifiutato

Il campo in validazione deve essere "no", "off", 0, "0", false o "false".

declined_if:anotherfield,value,…

Il campo in fase di validazione deve essere "no", "off", 0, "0", false o "false" se un altro campo in fase di validazione è uguale a un valore specificato.

#### different:_field_

Il campo in fase di validazione deve avere un valore diverso da _field_.

digits:value

L’intero da validare deve avere una lunghezza esatta di value.

digits_between:min,max

La validazione intera deve avere una lunghezza tra min e max.

dimensions

Il file in fase di validazione deve essere un’immagine che rispetta i vincoli sulle dimensioni specificati dai parametri della regola:

'avatar' => 'dimensions:min_width=100,min_height=200'

I vincoli disponibili sono: min_width, max_width, min_height, max_height, width, height, ratio.

Un vincolo di ratio deve essere rappresentato come larghezza divisa per altezza. Può essere specificato sia come frazione, ad esempio 3/2, sia come numero decimale, ad esempio 1.5:

'avatar' => 'dimensions:ratio=3/2'

Poiché questa regola richiede diversi argomenti, puoi usare il metodo Rule::dimensions per costruire la regola in modo fluido:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
    ],
]);

distinct

Durante la validazione degli array, il campo in validazione non deve contenere valori duplicati:

'foo.*.id' => 'distinct'

Per impostazione predefinita, distinct utilizza confronti non rigidi. Per usare confronti rigidi, puoi aggiungere il parametro strict alla definizione della regola di validazione:

'foo.*.id' => 'distinct:strict'

Puoi aggiungere ignore_case agli argomenti della regola di validazione per far sì che la regola ignori le differenze di maiuscole/minuscole:

'foo.*.id' => 'distinct:ignore_case'

doesnt_start_with:foo,bar,…

Il campo in convalida non deve iniziare con uno dei valori specificati.

doesnt_end_with:foo,bar,…

Il campo in validazione non deve terminare con uno dei valori forniti.

email

Il campo sottoposto a validazione deve essere formattato come un indirizzo email. Questa regola di validazione utilizza il pacchetto egulias/email-validator per validare l’indirizzo email. Per impostazione predefinita, viene applicato il validatore RFCValidation, ma puoi applicare anche altri stili di validazione:

    'email' => 'email:rfc,dns'

L’esempio sopra applicherà le validazioni RFCValidation e DNSCheckValidation. Ecco una lista completa degli stili di validazione che puoi applicare:

  • rfc: RFCValidation
  • strict: NoRFCWarningsValidation
  • dns: DNSCheckValidation
  • spoof: SpoofCheckValidation
  • filter: FilterEmailValidation
  • filter_unicode: FilterEmailValidation::unicode()

Il validatore filter, che utilizza la funzione filter_var di PHP, è incluso in Laravel ed era il comportamento di validazione email predefinito di Laravel prima della versione 5.8.

I validatori dns e spoof richiedono l’estensione PHP intl.

ends_with:foo,bar,…

Il campo da validare deve finire con uno dei valori indicati.

enum

La regola Enum è una regola basata su classe che valida se il campo in fase di validazione contiene un valore enum valido. La regola Enum accetta il nome dell’enum come unico argomento del costruttore. Quando si validano valori primitivi, è necessario fornire un Enum supportato alla regola Enum:

use App\Enums\ServerStatus;
use Illuminate\Validation\Rule;

$request->validate([
    'status' => [Rule::enum(ServerStatus::class)],
]);

I metodi only ed except della regola Enum possono essere utilizzati per limitare quali casi dell’enum devono essere considerati validi:

Rule::enum(ServerStatus::class)
    ->only([ServerStatus::Pending, ServerStatus::Active]);

Rule::enum(ServerStatus::class)
    ->except([ServerStatus::Pending, ServerStatus::Active]);

Il metodo when può essere usato per modificare condizionalmente la regola Enum:

use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;

Rule::enum(ServerStatus::class)
    ->when(
        Auth::user()->isAdmin(),
        fn ($rule) => $rule->only(...),
        fn ($rule) => $rule->only(...),
    );

exclude

Il campo in fase di validazione verrà escluso dai dati della richiesta restituiti dai metodi validate e validated.

exclude_if:anotherfield,value

Il campo in fase di validazione sarà escluso dai dati della richiesta restituiti dai metodi validate e validated se il campo anotherfield è uguale a value.

Se è necessaria una logica di esclusione condizionale più complessa, puoi utilizzare il metodo Rule::excludeIf. Questo metodo accetta un booleano o una closure. Quando viene fornita una closure, la closure deve restituire true o false per indicare se il campo in fase di validazione deve essere escluso:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($request->all(), [
    'role_id' => Rule::excludeIf($request->user()->is_admin),
]);

Validator::make($request->all(), [
    'role_id' => Rule::excludeIf(fn () => $request->user()->is_admin),
]);

exclude_unless:anotherfield,value

Il campo sottoposto a validazione verrà escluso dai dati della richiesta restituiti dai metodi validate e validated a meno che il campo anotherfield non sia uguale a value. Se value è null (exclude_unless:name,null), il campo sottoposto a validazione verrà escluso a meno che il campo di confronto non sia null o manchi dai dati della richiesta.

exclude_with:anotherfield

Il campo in fase di validazione sarà escluso dai dati della richiesta restituiti dai metodi validate e validated se il campo anotherfield è presente.

exclude_without:anotherfield

Il campo in fase di validazione sarà escluso dai dati della richiesta restituiti dai metodi validate e validated se il campo anotherfield non è presente.

exists:table,column

Il campo in validazione deve esistere in una specifica tabella del database.

Utilizzo Base della Regola Exists

‘state’ => ‘exists:states’

Se l’opzione column non è specificata, verrà usato il nome del campo. Quindi, in questo caso, la regola verificherà che la tabella states nel database contenga un record con un valore nella colonna state che corrisponde al valore dell’attributo state della richiesta.

Specificare un Nome di Colonna Personalizzato

Puoi specificare esplicitamente il nome della colonna del database da utilizzare per la regola di validazione posizionandolo dopo il nome della tabella del database:

'state' => 'exists:states,abbreviation'

Occasionalmente, potresti dover specificare una connessione al database particolare da usare per la query exists. Puoi farlo aggiungendo il nome della connessione prima del nome della tabella:

'email' => 'exists:connection.staff,email'

Invece di specificare direttamente il nome della tabella, puoi indicare il modello Eloquent da utilizzare per determinare il nome della tabella:

'user_id' => 'exists:App\Models\User,id'

Se desideri personalizzare la query eseguita dalla regola di validazione, puoi usare la classe Rule per definire la regola in modo fluido. In questo esempio, specificheremo anche le regole di validazione come un array invece di usare il carattere | per separarli:

use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function (Builder $query) {
            $query->where('account_id', 1);
        }),
    ],
]);

Puoi specificare esplicitamente il nome della colonna del database da utilizzare per la regola exists generata dal metodo Rule::exists fornendo il nome della colonna come secondo argomento al metodo exists:

'state' => Rule::exists('states', 'abbreviation'),

extensions:foo,bar,…

Il file in fase di validazione deve avere un’estensione assegnata dall’utente che corrisponda a una delle estensioni elencate:

    'photo' => ['required', 'extensions:jpg,png'],

Non dovresti mai fare affidamento solo sull’estensione assegnata dall’utente per validare un file. Questa regola dovrebbe generalmente essere utilizzata sempre in combinazione con le regole mimes o mimetypes.

file

Il campo da validare deve essere un file caricato correttamente.

filled

Il campo in validazione non deve essere vuoto se è presente.

gt:field

Il campo in fase di validazione deve essere maggiore del field o del value fornito. I due campi devono essere dello stesso tipo. Stringhe, numeri, array e file vengono valutati secondo le stesse convenzioni della regola size.

gte:field

Il campo deve essere maggiore o uguale al field o al value specificato. Entrambi devono essere dello stesso tipo. Stringhe, numeri, array e file vengono valutati seguendo le stesse regole della regola size.

hex_color

Il campo in fase di validazione deve contenere un valore di colore valido in formato esadecimale.

image

Il file da validare deve essere un’immagine (jpg, jpeg, png, bmp, gif, svg o webp).

in:foo,bar,…

Il campo da validare deve essere incluso nell’elenco dei valori forniti. Poiché questa regola spesso richiede di implode un array, il metodo Rule::in può essere utilizzato per costruire fluentemente la regola:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($data, [
    'zones' => [
        'required',
        Rule::in(['first-zone', 'second-zone']),
    ],
]);

Quando la regola in viene combinata con la regola array, ogni valore nell’array di input deve essere presente nell’elenco dei valori forniti alla regola in. Nell’esempio seguente, il codice aeroportuale LAS nell’array di input non è valido poiché non è incluso nell’elenco degli aeroporti forniti alla regola in:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

$input = [
    'airports' => ['NYC', 'LAS'],
];

Validator::make($input, [
    'airports' => [
        'required',
        'array',
    ],
    'airports.*' => Rule::in(['NYC', 'LIT']),
]);

in_array:anotherfield.*

Il campo da validare deve esistere nei valori di anotherfield.

integer

Il campo da validare deve essere un intero.

Questa regola di validazione non verifica che l’input sia del tipo variabile "integer", ma solo che l’input sia di un tipo accettato dalla regola FILTER_VALIDATE_INT di PHP. Se hai bisogno di validare l’input come numero, utilizza questa regola in combinazione con la regola di validazione numeric.

ip

Il campo sottoposto a validazione deve essere un indirizzo IP.

ipv4

Il campo in fase di validazione deve essere un indirizzo IPv4.

ipv6

Il campo in verifica deve essere un indirizzo IPv6.

json

Il campo da validare deve essere una stringa JSON valida.

lt:field

Il campo in validazione deve essere minore del campo specificato field. I due campi devono essere dello stesso tipo. Stringhe, numeri, array e file vengono valutati secondo le stesse convenzioni della regola size.

lte:field

Il campo in fase di validazione deve essere minore o uguale al campo specificato field. I due campi devono essere dello stesso tipo. Stringhe, numerici, array e file vengono valutati seguendo le stesse convenzioni della regola size.

lowercase

Il campo in fase di validazione deve essere lowercase.

lista

Il campo da validare deve essere un array che rappresenta una lista. Un array è considerato una lista se le sue chiavi sono numeri consecutivi da 0 a count($array) - 1.

mac_address

Il campo da validare deve essere un indirizzo MAC.

max:value

Il campo da validare deve essere minore o uguale a un valore massimo value. Strings, numerics, arrays e files vengono valutati nello stesso modo della regola size.

max_digits:value

Il numero intero deve avere al massimo value cifre.

mimetypes:text/plain,…

Il file da validare deve avere uno dei MIME type specificati:

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'

Per determinare il MIME type del file caricato, verrà analizzato il contenuto del file e il framework cercherà di identificarne il MIME type, che potrebbe differire da quello fornito dal client.

mimes:foo,bar,…

Il file in fase di validazione deve avere un tipo MIME corrispondente a una delle estensioni elencate:

'photo' => 'mimes:jpg,bmp,png'

Anche se devi specificare solo le estensioni, questa regola valida effettivamente il tipo MIME del file leggendo il contenuto del file e determinando il suo tipo MIME. Un elenco completo dei tipi MIME e delle relative estensioni può essere trovato nella seguente posizione:

https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

Tipi MIME ed Estensioni

Questa regola di validazione non verifica la corrispondenza tra il tipo MIME e l’estensione assegnata dall’utente al file. Ad esempio, la regola di validazione mimes:png considererebbe un file contenente contenuto PNG valido come un’immagine PNG valida, anche se il file è chiamato photo.txt. Se desideri validare l’estensione assegnata dall’utente al file, puoi usare la regola extensions.

min:value

Il campo sotto validazione deve avere un valore minimo di value. Stringhe, numeri, array e file vengono valutati nello stesso modo della regola size.

min_digits:value

Il numero intero da validare deve avere una lunghezza minima di value.

multiple_of:value

Il campo in fase di validazione deve essere un multiplo di value.

missing

Il campo da validare non deve essere presente nei dati forniti.

missing_if:anotherfield,value,…

Il campo soggetto a validazione non deve essere presente se il campo anotherfield è uguale a qualsiasi value.

missing_unless:anotherfield,value

Il campo in fase di validazione non deve essere presente a meno che il campo anotherfield sia uguale a value.

missing_with:foo,bar,…

Il campo sottoposto a validazione non deve essere presente solo se uno qualsiasi degli altri campi specificati è presente.

missing_with_all: foo, bar, …

Il campo in validazione non deve essere presente solo se tutti gli altri campi specificati sono presenti.

not_in:foo,bar,…

Il campo da validare non deve essere incluso nella lista dei valori forniti. Il metodo Rule::notIn può essere utilizzato per costruire la regola in modo fluido:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'toppings' => [
        'required',
        Rule::notIn(['sprinkles', 'cherries']),
    ],
]);

not_regex:pattern

Il campo da validare non deve corrispondere all’espressione regolare fornita.

Internamente, questa regola utilizza la funzione PHP preg_match. Il pattern specificato deve seguire lo stesso formato richiesto da preg_match e quindi includere delimitatori validi. Ad esempio: 'email' => 'not_regex:/^.+$/i'.

Quando si usano i pattern regex o not_regex, potrebbe essere necessario specificare le regole di validazione usando un array anziché usare i delimitatori |, specialmente se l’espressione regolare contiene il carattere |.

nullable

Il campo in validazione può essere null.

numeric

Il campo in fase di validazione deve essere numeric.

present

Il campo in convalida deve esistere nei dati di input.

present_if:anotherfield,value,…

Il campo in validazione deve essere presente se il campo anotherfield è uguale a qualsiasi value.

present_unless:anotherfield,value

Il campo da validare deve essere presente a meno che il campo anotherfield non sia uguale a uno qualsiasi value.

present_with:foo,bar,…

Il campo da validare deve essere presente solo se uno degli altri campi specificati è presente.

present_with_all:foo,bar,…

Il campo in validazione deve essere presente solo se sono presenti tutti gli altri campi specificati.

prohibited

Il campo in fase di validazione deve essere mancante o vuoto. Un campo è "vuoto" se soddisfa uno dei seguenti criteri:

  • Il valore è null.
  • Il valore è una stringa vuota.
  • Il valore è un array vuoto o un oggetto Countable vuoto.
  • Il valore è un file caricato con un percorso vuoto.

prohibited_if:anotherfield,value,…

Il campo in validazione deve essere assente o vuoto se il campo anotherfield è uguale a uno qualsiasi dei value. Un campo è "vuoto" se soddisfa uno dei seguenti criteri:

  • Il valore è null.
  • Il valore è una stringa vuota.
  • Il valore è un array vuoto o un oggetto Countable vuoto.
  • Il valore è un file caricato con un percorso vuoto.

Se è necessaria una logica complessa di proibizione condizionale, puoi utilizzare il metodo Rule::prohibitedIf. Questo metodo accetta un booleano o una closure. Quando viene fornita una closure, essa dovrebbe restituire true o false per indicare se il campo in validazione deve essere proibito:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($request->all(), [
    'role_id' => Rule::prohibitedIf($request->user()->is_admin),
]);

Validator::make($request->all(), [
    'role_id' => Rule::prohibitedIf(fn () => $request->user()->is_admin),
]);

prohibited_unless:anotherfield,value,…

Il campo sottoposto a validazione deve essere assente o vuoto a meno che il campo anotherfield non sia uguale a uno dei value. Un campo è "vuoto" se soddisfa uno dei seguenti criteri:

  • Il valore è null.
  • Il valore è una stringa vuota.
  • Il valore è un array vuoto o un oggetto Countable vuoto.
  • Il valore è un file caricato con un percorso vuoto.

prohibits:anotherfield,…

Se il campo in validazione non è mancante o vuoto, tutti i campi in anotherfield devono essere mancanti o vuoti. Un campo è "vuoto" se soddisfa uno dei seguenti criteri:

  • Il valore è null.
  • Il valore è una stringa vuota.
  • Il valore è un array vuoto o un oggetto Countable vuoto.
  • Il valore è un file caricato con un percorso vuoto.

regex:pattern

Il campo in fase di validazione deve corrispondere all’espressione regolare fornita.

Internamente, questa regola utilizza la funzione PHP preg_match. Il pattern specificato deve rispettare lo stesso formato richiesto da preg_match e quindi includere i delimitatori validi. Ad esempio: 'email' => 'regex:/^.+@.+$/i'.

Quando si utilizzano i pattern regex / not_regex, potrebbe essere necessario specificare le regole in un array invece di usare i delimitatori |, specialmente se l’espressione regolare contiene il carattere |.

required

Il campo soggetto alla validazione deve essere presente nei dati di input e non vuoto. Un campo è "vuoto" se soddisfa uno dei seguenti criteri:

  • Il valore è null.
  • Il valore è una stringa vuota.
  • Il valore è un array vuoto o un oggetto Countable vuoto.
  • Il valore è un file caricato senza percorso.

required_if:anotherfield,value,…

Il campo in validazione deve essere presente e non vuoto se il campo anotherfield è uguale a uno dei value.

Se desideri creare una condizione più complessa per la regola required_if, puoi usare il metodo Rule::requiredIf. Questo metodo accetta un booleano o una closure. Se passi una closure, la closure deve restituire true o false per indicare se il campo in validazione è richiesto:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

Validator::make($request->all(), [
    'role_id' => Rule::requiredIf($request->user()->is_admin),
]);

Validator::make($request->all(), [
    'role_id' => Rule::requiredIf(fn () => $request->user()->is_admin),
]);

required_if_accepted:anotherfield,…

Il campo da validare deve essere presente e non vuoto se il campo anotherfield è uguale a "yes", "on", 1, "1", true o "true".

required_if_declined:anotherfield,…

Il campo in fase di validazione deve essere presente e non vuoto se il campo anotherfield è uguale a "no", "off", 0, "0", false o "false".

required_unless:anotherfield,value,…

Il campo da validare deve essere presente e non vuoto a meno che il campo anotherfield non sia uguale a uno qualsiasi dei value. Questo significa anche che anotherfield deve essere presente nei dati della richiesta a meno che value non sia null. Se value è null (required_unless:name,null), il campo da validare sarà obbligatorio a meno che il campo di confronto non sia null o manchi dai dati della richiesta.

required_with:foo,bar,…

Il campo da validare deve essere presente e non vuoto solo se uno degli altri campi specificati è presente e non vuoto.

required_with_all:foo,bar,…

Il campo in validazione deve essere presente e non vuoto solo se tutti gli altri campi specificati sono presenti e non vuoti.

required_without:foo,bar,…

Il campo in fase di validazione deve essere presente e non vuoto solo quando uno degli altri campi specificati è vuoto o non presente.

required_without_all:foo,bar,…

Il campo in validazione deve essere presente e non vuoto solo quando tutti gli altri campi specificati sono vuoti o non presenti.

required_array_keys:foo,bar,…

Il campo in validazione deve essere un array e deve contenere almeno le chiavi specificate.

same:field

Il campo specificato field deve corrispondere al campo in fase di validazione.

size:value

Il campo da validare deve avere una dimensione uguale al value specificato. Per le stringhe, value rappresenta il numero di caratteri. Per i numeri, value indica un valore intero specifico (l’attributo deve avere anche la regola numeric o integer). Per un array, size corrisponde al count dell’array. Per i file, size rappresenta la dimensione del file in kilobyte. Vediamo alcuni esempi:

// Verifica che una stringa abbia esattamente 12 caratteri...
'title' => 'size:12';

// Verifica che un intero fornito sia uguale a 10...
'seats' => 'integer|size:10';

// Verifica che un array abbia esattamente 5 elementi...
'tags' => 'array|size:5';

// Verifica che un file caricato sia esattamente di 512 kilobyte...
'image' => 'file|size:512';

starts_with:foo,bar,…

Il campo deve iniziare con uno dei valori forniti.

string

Il campo in validazione deve essere una stringa. Se desideri permettere che il campo sia anche null, dovresti assegnare al campo la regola nullable.

timezone

Il campo da validare deve essere un identificatore di fuso orario valido secondo il metodo DateTimeZone::listIdentifiers.

Puoi anche fornire a questa regola di validazione gli argomenti accettati dal metodo DateTimeZone::listIdentifiers:

'timezone' => 'required|timezone:all';

'timezone' => 'required|timezone:Africa';

'timezone' => 'required|timezone:per_country,US';

unique:table,column

Il campo sotto validazione non deve esistere all’interno della tabella del database specificata.

Specificare un Nome di Tabella/Campo Personalizzato:

Invece di specificare direttamente il nome della tabella, puoi specificare il modello Eloquent che dovrebbe essere usato per determinare il nome della tabella:

    'email' => 'unique:App\Models\User,email_address'

L’opzione column può essere usata per specificare la colonna del database corrispondente al campo. Se l’opzione column non è specificata, verrà usato il nome del campo sotto validazione.

    'email' => 'unique:users,email_address'

Specificare una Connessione al Database Personalizzata

Occasionalmente, potresti aver bisogno di impostare una connessione personalizzata per le query al database effettuate dal Validator. Per fare ciò, puoi anteporre il nome della connessione al nome della tabella:

    'email' => 'unique:connection.users,email_address'

Forzare una Regola Unica a Ignorare un ID Specifico:

A volte, potresti voler ignorare un ID specifico durante la validazione unica. Ad esempio, considera una schermata "aggiorna profilo" che include il nome dell’utente, l’indirizzo email e la posizione. Probabilmente vorrai verificare che l’indirizzo email sia unico. Tuttavia, se l’utente cambia solo il campo nome e non il campo email, non vuoi che venga generato un errore di validazione perché l’utente è già il proprietario dell’indirizzo email in questione.

Per istruire il validator a ignorare l’ID dell’utente, useremo la classe Rule per definire fluentemente la regola. In questo esempio, specificheremo anche le regole di validazione come un array invece di usare il carattere | per delimitare le regole:

    use Illuminate\Support\Facades\Validator;
    use Illuminate\Validation\Rule;

    Validator::make($data, [
        'email' => [
            'required',
            Rule::unique('users')->ignore($user->id),
        ],
    ]);

Non dovresti mai passare input di richiesta controllati dall’utente nel metodo ignore. Invece, dovresti passare solo un ID unico generato dal sistema, come un ID auto-incrementante o UUID da un’istanza del modello Eloquent. Altrimenti, la tua applicazione sarà vulnerabile ad attacchi di SQL injection.

Invece di passare il valore della chiave del modello al metodo ignore, puoi anche passare l’intera istanza del modello. Laravel estrarrà automaticamente la chiave dal modello:

    Rule::unique('users')->ignore($user)

Se la tua tabella usa un nome di colonna chiave primaria diverso da id, puoi specificare il nome della colonna quando chiami il metodo ignore:

    Rule::unique('users')->ignore($user->id, 'user_id')

Per impostazione predefinita, la regola unique verificherà l’unicità della colonna che corrisponde al nome dell’attributo in validazione. Tuttavia, puoi passare un nome di colonna diverso come secondo argomento al metodo unique:

    Rule::unique('users', 'email_address')->ignore($user->id)

Aggiungere Clausole Where Aggiuntive:

Puoi specificare condizioni di query aggiuntive personalizzando la query utilizzando il metodo where. Ad esempio, aggiungiamo una condizione di query che limita la ricerca a record che hanno un valore della colonna account_id pari a 1:

    'email' => Rule::unique('users')->where(fn (Builder $query) => $query->where('account_id', 1))

uppercase

Il campo sottoposto a validazione deve essere maiuscolo.

url

Il campo in fase di validazione deve essere un URL valido.

Se desideri specificare i protocolli URL che devono essere considerati validi, puoi passare i protocolli come parametri della regola di validazione:

'url' => 'url:http,https',

'game' => 'url:minecraft,steam',

ulid

Il campo in fase di validazione deve essere un Universally Unique Lexicographically Sortable Identifier (ULID) valido.

uuid

Il campo in fase di convalida deve essere un identificatore unico universale (UUID) valido secondo RFC 4122 (versione 1, 3, 4 o 5).

Aggiunta Condizionale delle Regole

Saltare la Validazione Quando i Campi Hanno Determinati Valori

A volte potresti voler non validare un campo se un altro campo ha un certo valore. Puoi farlo usando la regola di validazione exclude_if. In questo esempio, i campi appointment_date e doctor_name non saranno validati se il campo has_appointment ha il valore false:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($data, [
    'has_appointment' => 'required|boolean',
    'appointment_date' => 'exclude_if:has_appointment,false|required|date',
    'doctor_name' => 'exclude_if:has_appointment,false|required|string',
]);

In alternativa, puoi usare la regola exclude_unless per non validare un campo a meno che un altro campo abbia un certo valore:

$validator = Validator::make($data, [
    'has_appointment' => 'required|boolean',
    'appointment_date' => 'exclude_unless:has_appointment,true|required|date',
    'doctor_name' => 'exclude_unless:has_appointment,true|required|string',
]);

Validazione se Presente

In alcune situazioni, potresti voler eseguire controlli di validazione su un campo solo se quel campo è presente nei dati da validare. Per farlo rapidamente, aggiungi la regola sometimes alla tua lista di regole:

    $validator = Validator::make($data, [
        'email' => 'sometimes|required|email',
    ]);

Nell’esempio sopra, il campo email sarà validato solo se è presente nell’array $data.

Validazione Condizionale Complessa

A volte potresti voler aggiungere regole di validazione basate su logiche condizionali più complesse. Ad esempio, potresti voler rendere obbligatorio un campo solo se un altro campo ha un valore maggiore di 100. Oppure, potresti aver bisogno che due campi abbiano un certo valore solo quando un altro campo è presente. Aggiungere queste regole di validazione non deve essere complicato. Per prima cosa, crea un’istanza di Validator con le tue regole statiche che non cambiano mai:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

Supponiamo che la nostra applicazione web sia rivolta ai collezionisti di giochi. Se un collezionista si registra e possiede più di 100 giochi, vogliamo che spieghi perché ne ha così tanti. Ad esempio, potrebbe gestire un negozio di rivendita di giochi, oppure potrebbe semplicemente amare collezionare. Per aggiungere questa richiesta in modo condizionale, possiamo usare il metodo sometimes sull’istanza di Validator.

use Illuminate\Support\Fluent;

$validator->sometimes('reason', 'required|max:500', function (Fluent $input) {
    return $input->games >= 100;
});

Il primo argomento passato al metodo sometimes è il nome del campo che stiamo validando in modo condizionale. Il secondo argomento è l’elenco delle regole che vogliamo aggiungere. Se la funzione passata come terzo argomento restituisce true, le regole verranno aggiunte. Questo metodo semplifica notevolmente la creazione di validazioni condizionali complesse. Puoi anche aggiungere validazioni condizionali per diversi campi contemporaneamente:

$validator->sometimes(['reason', 'cost'], 'required', function (Fluent $input) {
    return $input->games >= 100;
});

Il parametro $input passato alla tua funzione sarà un’istanza di Illuminate\Support\Fluent e può essere utilizzato per accedere ai tuoi input e ai file in fase di validazione.

Validazione Condizionale Complessa Ad Array

A volte potresti voler validare un campo in base a un altro campo nello stesso array nidificato di cui non conosci l’indice. In queste situazioni, puoi permettere alla tua closure di ricevere un secondo argomento che sarà l’elemento corrente dell’array che viene validato:

    $input = [
        'channels' => [
            [
                'type' => 'email',
                'address' => 'abigail@example.com',
            ],
            [
                'type' => 'url',
                'address' => 'https://example.com',
            ],
        ],
    ];

    $validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {
        return $item->type === 'email';
    });

    $validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {
        return $item->type !== 'email';
    });

Come il parametro $input passato alla closure, il parametro $item è un’istanza di Illuminate\Support\Fluent quando i dati dell’attributo sono un array; altrimenti, è una stringa.

Validazione degli Array

Come discusso nella documentazione della regola di validazione array, la regola array accetta un elenco di chiavi dell’array consentite. Se sono presenti chiavi aggiuntive nell’array, la validazione fallirà:

    use Illuminate\Support\Facades\Validator;

    $input = [
        'user' => [
            'name' => 'Taylor Otwell',
            'username' => 'taylorotwell',
            'admin' => true,
        ],
    ];

    Validator::make($input, [
        'user' => 'array:name,username',
    ]);

In generale, dovresti sempre specificare le chiavi dell’array che sono consentite all’interno del tuo array. Altrimenti, i metodi validate e validated del validatore restituiranno tutti i dati validati, compreso l’array e tutte le sue chiavi, anche se queste chiavi non sono state validate da altre regole di validazione degli array annidati.

Validare input di array annidati

Validare campi di input basati su array annidati non deve essere complicato. Puoi usare la "dot notation" per validare attributi all’interno di un array. Ad esempio, se la richiesta HTTP in arrivo contiene un campo photos[profile], puoi validarlo in questo modo:

    use Illuminate\Support\Facades\Validator;

    $validator = Validator::make($request->all(), [
        'photos.profile' => 'required|image',
    ]);

Puoi anche validare ogni elemento di un array. Ad esempio, per validare che ogni email in un campo di input array dato sia unica, puoi fare quanto segue:

    $validator = Validator::make($request->all(), [
        'person.*.email' => 'email|unique:users',
        'person.*.first_name' => 'required_with:person.*.last_name',
    ]);

Allo stesso modo, puoi usare il carattere * quando specifichi messaggi di validazione personalizzati nei tuoi file di lingua, rendendo semplice usare un singolo messaggio di validazione per campi basati su array:

    'custom' => [
        'person.*.email' => [
            'unique' => 'Ogni persona deve avere un indirizzo email unico',
        ]
    ],

Accesso ai Dati degli Array Annidati

A volte potresti aver bisogno di accedere al valore di un elemento di array annidato quando assegni le regole di validazione all’attributo. Puoi farlo utilizzando il metodo Rule::forEach. Il metodo forEach accetta una closure che verrà invocata ad ogni iterazione dell’attributo array in fase di validazione e riceverà il valore dell’attributo e il nome esplicito e completamente espanso dell’attributo. La closure dovrebbe restituire un array di regole da assegnare all’elemento dell’array:

use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

$validator = Validator::make($request->all(), [
    'companies.*.id' => Rule::forEach(function (string|null $value, string $attribute) {
        return [
            Rule::exists(Company::class, 'id'),
            new HasPermission('manage-company', $value),
        ];
    }),
]);

Indici e Posizioni dei Messaggi di Errore

Quando si validano array, potresti voler fare riferimento all’indice o alla posizione di un elemento particolare che ha fallito la validazione all’interno del messaggio di errore visualizzato dalla tua applicazione. Per fare questo, puoi includere i segnaposto :index (a partire da 0) e :position (a partire da 1) nel tuo messaggio di validazione personalizzato:

use Illuminate\Support\Facades\Validator;

$input = [
    'photos' => [
        [
            'name' => 'BeachVacation.jpg',
            'description' => 'A photo of my beach vacation!',
        ],
        [
            'name' => 'GrandCanyon.jpg',
            'description' => '',
        ],
    ],
];

Validator::validate($input, [
    'photos.*.description' => 'required',
], [
    'photos.*.description.required' => 'Per favore descrivi la foto #:position.',
]);

Dato l’esempio sopra, la validazione fallirà e l’utente vedrà il seguente errore: "Per favore descrivi la foto #2."

Se necessario, puoi fare riferimento a indici e posizioni più profondamente annidati tramite second-index, second-position, third-index, third-position, ecc.

'photos.*.attributes.*.string' => 'Invalid attribute for photo #:second-position.',

Validare i File

Laravel offre diverse regole di validazione che puoi usare per convalidare i file caricati, come mimes, image, min e max. Anche se puoi specificare queste regole singolarmente quando validi i file, Laravel mette a disposizione anche un costruttore di regole di validazione dei file fluente che potrebbe esserti utile:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;

Validator::validate($input, [
    'attachment' => [
        'required',
        File::types(['mp3', 'wav'])
            ->min(1024)
            ->max(12 * 1024),
    ],
]);

Se la tua applicazione accetta immagini caricate dagli utenti, puoi usare il metodo image della regola File per indicare che il file caricato deve essere un’immagine. Inoltre, la regola dimensions può essere utilizzata per limitare le dimensioni dell’immagine:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;

Validator::validate($input, [
    'photo' => [
        'required',
        File::image()
            ->min(1024)
            ->max(12 * 1024)
            ->dimensions(Rule::dimensions()->maxWidth(1000)->maxHeight(500)),
    ],
]);

Maggiori informazioni sulla validazione delle dimensioni delle immagini si trovano nella documentazione della regola dimension.

Dimensioni dei file

Per comodità, le dimensioni minime e massime dei file possono essere specificate come stringhe con un suffisso che indica l’unità di misura. Sono supportati i suffissi kb, mb, gb e tb:

File::image()
    ->min('1kb')
    ->max('10mb')

Tipi di File

Anche se devi specificare solo le estensioni quando utilizzi il metodo types, questo metodo valida effettivamente il tipo MIME del file leggendo il contenuto e determinando il suo tipo MIME. Un elenco completo dei tipi MIME e delle relative estensioni è disponibile al seguente indirizzo:

https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

Convalida delle Password

Per garantire che le password abbiano un livello adeguato di complessità, puoi utilizzare l’oggetto regola Password di Laravel:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;

$validator = Validator::make($request->all(), [
    'password' => ['required', 'confirmed', Password::min(8)],
]);

L’oggetto regola Password ti permette di personalizzare facilmente i requisiti di complessità delle password per la tua applicazione, ad esempio specificando che le password richiedono almeno una lettera, un numero, un simbolo o caratteri con maiuscole e minuscole:

// Richiedi almeno 8 caratteri...
Password::min(8)

// Richiedi almeno una lettera...
Password::min(8)->letters()

// Richiedi almeno una lettera maiuscola e una minuscola...
Password::min(8)->mixedCase()

// Richiedi almeno un numero...
Password::min(8)->numbers()

// Richiedi almeno un simbolo...
Password::min(8)->symbols()

Inoltre, puoi assicurarti che una password non sia stata compromessa in una diffusione pubblica di dati tramite il metodo uncompromised:

Password::min(8)->uncompromised()

Internamente, l’oggetto regola Password utilizza il modello k-Anonymity per determinare se una password è stata filtrata tramite il servizio haveibeenpwned.com senza compromettere la privacy o la sicurezza dell’utente.

Per impostazione predefinita, se una password appare almeno una volta in una fuga di dati, sarà considerata compromessa. Puoi personalizzare questa soglia utilizzando il primo argomento del metodo uncompromised:

// Assicurati che la password appaia meno di 3 volte nella stessa fuga di dati...
Password::min(8)->uncompromised(3);

Naturalmente, puoi concatenare tutti i metodi negli esempi sopra:

Password::min(8)
    ->letters()
    ->mixedCase()
    ->numbers()
    ->symbols()
    ->uncompromised()

Definire le Regole Predefinite per le Password

Potrebbe essere comodo specificare le regole di validazione predefinite per le password in un’unica posizione della tua applicazione. Puoi farlo facilmente usando il metodo Password::defaults, che accetta una closure. La closure passata al metodo defaults dovrebbe restituire la configurazione predefinita della regola Password. Tipicamente, la regola defaults dovrebbe essere chiamata all’interno del metodo boot di uno dei service provider della tua applicazione:

use Illuminate\Validation\Rules\Password;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Password::defaults(function () {
        $rule = Password::min(8);

        return $this->app->isProduction()
                    ? $rule->mixedCase()->uncompromised()
                    : $rule;
    });
}

Successivamente, quando desideri applicare le regole predefinite a una particolare password in fase di validazione, puoi invocare il metodo defaults senza argomenti:

    'password' => ['required', Password::defaults()],

Occasionalmente, potresti voler aggiungere ulteriori regole di validazione alle tue regole di validazione password predefinite. Puoi usare il metodo rules per farlo:

    use App\Rules\ZxcvbnRule;

    Password::defaults(function () {
        $rule = Password::min(8)->rules([new ZxcvbnRule]);

        // ...
    });

Regole di Validazione Personalizzate

Utilizzo degli Oggetti Rule

Laravel offre una varietà di regole di validazione utili; tuttavia, potresti voler specificarne alcune personalizzate. Un metodo per registrare regole di validazione personalizzate è utilizzare gli oggetti rule. Per generare un nuovo oggetto rule, puoi usare il comando Artisan make:rule. Usiamo questo comando per generare una regola che verifica che una stringa sia in maiuscolo. Laravel posizionerà la nuova regola nella directory app/Rules. Se questa directory non esiste, Laravel la creerà quando esegui il comando Artisan per creare la tua regola:

php artisan make:rule Uppercase

Una volta creata la regola, siamo pronti a definire il suo comportamento. Un oggetto rule contiene un singolo metodo: validate. Questo metodo riceve il nome dell’attributo, il suo valore e una callback che dovrebbe essere invocata in caso di fallimento con il messaggio di errore di validazione:

    <?php

    namespace App\Rules;

    use Closure;
    use Illuminate\Contracts\Validation\ValidationRule;

    class Uppercase implements ValidationRule
    {
        /**
         * Esegue la regola di validazione.
         */
        public function validate(string $attribute, mixed $value, Closure $fail): void
        {
            if (strtoupper($value) !== $value) {
                $fail('Il campo :attribute deve essere maiuscolo.');
            }
        }
    }

Una volta definita la regola, puoi aggiungerla a un validatore passando un’istanza dell’oggetto rule insieme alle altre regole di validazione:

    use App\Rules\Uppercase;

    $request->validate([
        'name' => ['required', 'string', new Uppercase],
    ]);

Tradurre i Messaggi di Validazione

Invece di fornire un messaggio di errore letterale alla closure $fail, puoi anche fornire una chiave di stringa di traduzione e indicare a Laravel di tradurre il messaggio di errore:

    if (strtoupper($value) !== $value) {
        $fail('validation.uppercase')->translate();
    }

Se necessario, puoi fornire sostituzioni per i segnaposti e la lingua preferita come primo e secondo argomento al metodo translate:

    $fail('validation.location')->translate([
        'value' => $this->value,
    ], 'fr')

Accesso ai Dati Aggiuntivi

Se la tua classe di regola di validazione personalizzata necessita di accedere a tutti gli altri dati in fase di validazione, la tua classe può implementare l’interfaccia Illuminate\Contracts\Validation\DataAwareRule. Questa interfaccia richiede che la tua classe definisca un metodo setData. Laravel invoca automaticamente questo metodo (prima che la validazione proceda) con tutti i dati in fase di validazione:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements DataAwareRule, ValidationRule
{
    /**
     * Tutti i dati in fase di validazione.
     *
     * @var array<string, mixed>
     */
    protected $data = [];

    // ...

    /**
     * Imposta i dati in fase di validazione.
     *
     * @param  array<string, mixed>  $data
     */
    public function setData(array $data): static
    {
        $this->data = $data;

        return $this;
    }
}

Oppure, se la tua regola di validazione richiede l’accesso all’istanza del validatore che esegue la validazione, puoi implementare l’interfaccia ValidatorAwareRule:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Validation\Validator;

class Uppercase implements ValidationRule, ValidatorAwareRule
{
    /**
     * L'istanza del validatore.
     *
     * @var \Illuminate\Validation\Validator
     */
    protected $validator;

    // ...

    /**
     * Imposta il validatore corrente.
     */
    public function setValidator(Validator $validator): static
    {
        $this->validator = $validator;

        return $this;
    }
}

Utilizzo delle Closure

Se hai bisogno della funzionalità di una regola personalizzata solo una volta nell’applicazione, puoi usare una closure invece di un oggetto regola. La closure riceve il nome dell’attributo, il valore dell’attributo e una callback $fail che deve essere chiamata se la validazione fallisce:

use Illuminate\Support\Facades\Validator;
use Closure;

$validator = Validator::make($request->all(), [
    'title' => [
        'required',
        'max:255',
        function (string $attribute, mixed $value, Closure $fail) {
            if ($value === 'foo') {
                $fail("The {$attribute} is invalid.");
            }
        },
    ],
]);

Regole Implicite

Per impostazione predefinita, quando un attributo da validare non è presente o contiene una stringa vuota, le normali regole di validazione, incluse quelle personalizzate, non vengono eseguite. Ad esempio, la regola unique non viene applicata a una stringa vuota:

    use Illuminate\Support\Facades\Validator;

    $rules = ['name' => 'unique:users,name'];

    $input = ['name' => ''];

    Validator::make($input, $rules)->passes(); // true

Per far sì che una regola personalizzata venga eseguita anche quando un attributo è vuoto, la regola deve implicare che l’attributo è obbligatorio. Per creare rapidamente un nuovo oggetto regola implicita, puoi usare il comando Artisan make:rule con l’opzione --implicit:

php artisan make:rule Uppercase --implicit

Una regola "implicita" implica solo che l’attributo è obbligatorio. Se invalida effettivamente un attributo mancante o vuoto dipende da te.

Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *