Vai al contenuto principale
Per fornire da un pacchetto distribuito una regola stringa come acme_tracking:AC, registra la logica di validazione nella Factory della validazione. Dalle form request dell’applicazione che la utilizza, potrà essere usata con la stessa sintassi delle regole integrate. Questa pagina si basa sull’implementazione ufficiale di Laravel Framework v13.40.0. Integra l’esempio di base delle regole di validazione personalizzate e tratta la registrazione, la traduzione e il ciclo di vita dello stato quando la regola viene mantenuta come API pubblica di un pacchetto.

Scegliere tra questo approccio e gli oggetti regola

Gli oggetti ValidationRule presentati dalla documentazione ufficiale possono essere usati anche nei pacchetti. Se poterli specificare come stringa non è di per sé un requisito, valuta un oggetto che riceva argomenti tipizzati nel costruttore. Anche se il nome è lo stesso, validate(), il contratto di chiamata è diverso. Se passi una classe che implementa ValidationRule così com’è come stringa di classe a Factory::extend(), il tipo del terzo argomento e il valore di ritorno non corrispondono.

Separare registrazione, creazione e validazione

extend() della facade Validator è una chiamata a Illuminate\Validation\Factory. È un oggetto distinto dall’istanza Illuminate\Validation\Validator che valida l’input. Il diagramma mostra il percorso quando viene eseguita una regola stringa. I casi in cui la regola viene saltata per input mancante o nullable sono descritti più avanti. La Factory è registrata come singleton con la chiave validator, ma il Validator restituito da make() nell’implementazione standard viene creato nuovo ogni volta. Le registrazioni successive sulla Factory non aggiornano l’array delle estensioni dei Validator già creati.

Registrare regole specifiche del pacchetto

Come esempio, validiamo un codice di tracciamento fittizio composto da un prefisso in lettere maiuscole, un trattino e 8 cifre. È un esempio di formato come AC-00000001, non la specifica dei numeri di un corriere reale. Si presuppone una configurazione in cui il namespace del pacchetto Acme\Courier\ corrisponde a src/ tramite PSR-4 di Composer e viene caricato un normale Service Provider non differito. Per il caricamento del provider, consulta Rilevamento automatico dei pacchetti.

Separare la logica di validazione in una classe

In src/Validation/TrackingCode.php prepara un handler per la regola stringa. Questa classe non implementa l’interfaccia ValidationRule.
Alla callback vengono passati quattro argomenti: il nome dell’attributo, il valore di input, l’array dei parametri e il Validator in corso di validazione. Nel caso di acme_tracking:AC, l’array dei parametri è ['AC']. Anche la regola verifica il tipo del valore, così da non generare errori di tipo quando viene usata da sola. Un prefisso non valido o un numero di parametri errato vengono trattati come eccezione, poiché sono errori di configurazione nella definizione della regola e non errori di input dell’utente. Quando la regola viene saltata per un valore vuoto, nemmeno questo controllo di configurazione viene eseguito, quindi servono anche test con valori non vuoti validi.

Registrare dopo la risoluzione della Factory

Da boot() di src/CourierServiceProvider.php, registra la regola e la logica di sostituzione del messaggio.
callAfterResolving() attende la creazione se la Factory non è ancora stata risolta, e registra immediatamente anche su una Factory già risolta. I dettagli dell’hook stesso sono spiegati in Hook dopo la risoluzione dei servizi nei pacchetti. La stringa di classe TrackingCode::class.'@validate' risolve la classe tramite il container al momento della validazione e ne chiama il metodo. Anche con il solo nome della classe, omettendo @validate, il nome del metodo predefinito è validate. Se esistono dipendenze nel costruttore, effettua i binding necessari affinché possano essere risolte dal container. In questo esempio non ci sono registrazioni singleton dell’handler né proprietà che memorizzano l’input. I dati di validazione vengono gestiti tramite gli argomenti, con un design che non cattura stato specifico della richiesta nelle closure mantenute dalla Factory.

Specificarla dall’applicazione che la utilizza

bail interrompe le regole successive se una regola precedente dello stesso attributo fallisce. I ruoli vengono separati: l’obbligatorietà con required, il formato con acme_tracking. Uniforma i nomi pubblici in snake case univoci come acme_tracking. Le registrazioni con lo stesso nome per lo stesso tipo di estensione vengono sovrascritte da quella successiva. Inoltre, quando esiste un metodo integrato come validateRequired(), quel metodo viene chiamato direttamente, quindi non è possibile sostituire una validazione integrata con un’estensione omonima.

Preservare i messaggi di errore dell’utente

Il messaggio di una normale regola stringa viene selezionato approssimativamente secondo l’ordine di priorità seguente. Rami speciali come le regole di dimensione non sono trattati qui. Il replacer personalizzato viene chiamato dopo che Laravel ha sostituito :attribute e simili. Gli argomenti del replacer sono cinque: il messaggio selezionato, il nome dell’attributo, il nome della regola, l’array dei parametri e il Validator. Nell’esempio precedente il quinto argomento, non utilizzato, è omesso.
Se il replacer sostituisce sempre l’intero messaggio con un testo fisso, ignora le sovrascritture fatte dall’utente con messages() o con le traduzioni. L’esempio precedente sostituisce solo :prefix nel $message ricevuto.
Per specificare il testo predefinito in giapponese lato applicazione, aggiungi acme_tracking all’array restituito dal file esistente lang/ja/validation.php. L’esempio sotto mostra la voce da aggiungere e non elimina gli altri messaggi integrati.
Per la preparazione dei file di traduzione e la configurazione della locale, consulta Localizzazione. Se esegui __('...') al momento della registrazione e lo salvi come fallback, nella Factory resta la stringa della locale di quel momento. Nelle applicazioni che cambiano locale, usa la traduzione al momento della generazione dell’errore.

Quando si usano traduzioni con namespace del pacchetto

Chiamando loadTranslationsFrom(__DIR__.'/../lang', 'acme-courier') in boot(), puoi fare riferimento a file come lang/ja/validation.php del pacchetto con acme-courier::validation.tracking_code. Tuttavia, passare semplicemente una chiave di traduzione come terzo argomento di extend() non la traduce automaticamente. La Factory la conserva come semplice stringa di fallback. Sostituendo extend() e replacer() nell’hook precedente con la registrazione seguente, potrai ottenere la traduzione del pacchetto solo quando viene selezionato il fallback.
Prepara una voce tracking_code nel file validation.php di ogni locale del pacchetto. Per il testo giapponese puoi usare lo stesso della voce acme_tracking precedente. Qui, poiché il replacer ottiene una nuova stringa di traduzione, anche :attribute viene passato esplicitamente alla traduzione. La sostituzione standard di Laravel non viene applicata di nuovo a questo valore di ritorno. Se viene selezionato un messaggio personalizzato dell’utente, quel testo viene mantenuto. Per la sovrascrittura delle traduzioni distribuite, consulta Sovrascrittura e aggiornamento delle traduzioni dei pacchetti.

Comprendere le condizioni di esecuzione di Implicit e nullable

extendImplicit() registra una regola che diventa candidata alla validazione anche per attributi mancanti o stringhe vuote. Non significa “farla fallire sempre” né “ignorare tutte le altre condizioni di salto”. La tabella confronta le condizioni di esecuzione di ciascuna regola. I casi in cui l’elaborazione si interrompe prima a causa di bail, dell’esclusione di attributi, di stopOnFirstFailure() e simili sono un discorso a parte. Negli input HTTP le stringhe vuote possono essere convertite in null da un middleware, quindi testa separatamente la stringa vuota e null. Per la regola di formato di questo esempio, la combinazione di extend() normale e required è sufficiente. Cambiare una regola già pubblicata in Implicit può far fallire input che prima non venivano validati, quindi va trattato come una modifica di compatibilità.

Risolvere i riferimenti negli array con le regole Dependent

Per le regole che accettano come parametro il nome di un altro campo, puoi usare extendDependent(). Durante la validazione di items.*.confirmed_tracking, il parametro items.*.tracking viene convertito in items.0.tracking e simili della stessa riga. Con extend() normale questa sostituzione non avviene. Di seguito una regola di corrispondenza per verificare questo meccanismo. Se serve solo verificare una semplice corrispondenza, in un’applicazione reale puoi usare la regola integrata same. Consideralo un esempio da applicare a validazioni tra campi specifiche del pacchetto. Aggiungila alla Factory ricevuta dall’hook.
La registrazione come Dependent non garantisce il controllo di esistenza del campo referenziato né il suo stato di validazione. getData() del quarto argomento restituisce i dati soggetti a validazione, non solo i dati già validati. Definisci le regole necessarie sia per il campo che fa riferimento sia per quello referenziato. Inoltre, rendere una regola Dependent non la rende Implicit. Specifica separatamente l’obbligatorietà per valori mancanti o vuoti. L’implementazione applica ai parametri l’escape dei punti e la sostituzione di *, quindi evita API che mescolano stringhe arbitrarie diverse dai nomi dei campi.

Testare dalla registrazione alla validazione nell’applicazione

In un’applicazione Laravel 13 in cui vengono caricati il pacchetto e il Service Provider, crea tests/Feature/TrackingRuleTest.php. Oltre ai test unitari della classe, verifica la registrazione e la gestione dei messaggi attraverso la Factory reale.
L’ultimo test non modifica la Factory condivisa, ma crea una nuova Factory per verificare la copia delle registrazioni. Se fornisci anche gli esempi con traduzioni con namespace o con regole Dependent, prepara test aggiuntivi in un ambiente che includa le registrazioni corrispondenti.

Cosa verificare per la manutenzione a lungo termine

  • Documentare come API pubblica il nome della regola, il significato e il numero dei parametri, l’obbligatorietà e i tipi di valore accettati.
  • Validare parametri non validi, valori mancanti, stringhe vuote e null, e le combinazioni con nullable, sometimes e bail.
  • Verificare messages() dell’utente, i nomi visualizzati degli attributi, il cambio di locale e la sovrascrittura delle traduzioni del pacchetto.
  • Per le regole Dependent, verificare con più righe e array annidati che non vengano referenziati valori di altre righe.
  • Verificare la registrazione su Factory non risolte e già risolte, senza aspettarsi che le modifiche si riflettano retroattivamente sui Validator già creati.
  • Evitare collisioni di nomi con altri pacchetti e non mescolare lo stesso nome tra registrazioni normali, Implicit e Dependent.
  • Per applicare le modifiche ai worker di lunga durata riavvia i processi, e non lasciare input o informazioni sull’utente negli handler condivisi.
Per l’ambiente di verifica del pacchetto da solo consulta Testare i pacchetti, e per la gestione della compatibilità anche Gestione della compatibilità delle versioni dei pacchetti.

Fonti primarie consultate

Ultima modifica il 5 novembre 2026