acme_tracking:AC aan te bieden, registreer je de validatielogica bij de validatie-Factory. Vanuit de form requests van de gebruikende applicatie kan de regel dan met dezelfde notatie als de ingebouwde regels worden gebruikt.
Deze pagina is gecontroleerd aan de hand van de officiële implementatie van Laravel Framework v13.40.0. Ze vult de basisvoorbeelden van Aangepaste validatieregels aan en behandelt registratie, vertaling en de levensduur van state wanneer je de regel onderhoudt als publieke API van een package.
Kiezen tussen dit en regelobjecten
DeValidationRule-objecten die in de officiële documentatie worden geïntroduceerd, kun je ook in packages gebruiken. Als het niet expliciet een vereiste is dat de regel als string kan worden opgegeven, overweeg dan een object dat getypeerde argumenten via de constructor ontvangt.
Ook al heten ze allebei
validate(), het aanroepcontract verschilt. Als je een klasse die ValidationRule implementeert direct als klassestring aan Factory::extend() doorgeeft, komen het type van het derde argument en de retourwaarde niet overeen.
Registratie, aanmaak en validatie scheiden
extend() op de Validator-facade is een aanroep naar Illuminate\Validation\Factory. Dat is een ander object dan de Illuminate\Validation\Validator-instantie die de invoer valideert.
Het diagram toont het pad wanneer een stringregel wordt uitgevoerd. Het overslaan door ontbrekende invoer of nullable wordt verderop behandeld.
De Factory wordt geregistreerd als singleton onder de sleutel validator, maar de Validator die de standaardimplementatie van make() retourneert, wordt elke keer opnieuw aangemaakt. Latere registraties bij de Factory werken de extensie-arrays van reeds aangemaakte Validators niet bij.
Package-specifieke regels registreren
Als voorbeeld valideren we een fictieve trackingcode die bestaat uit een prefix van hoofdletters, een koppelteken en acht cijfers. Het gaat om een voorbeeldformaat zoalsAC-00000001, niet om de nummerspecificatie van een bestaande vervoerder.
We gaan uit van een opzet waarin de package-namespace Acme\Courier\ via Composer PSR-4 naar src/ verwijst en een gewone, niet-uitgestelde service provider wordt geladen. Zie Package discovery voor het laden van providers.
De validatielogica in een klasse onderbrengen
Maak insrc/Validation/TrackingCode.php een handler voor de stringregel. Deze klasse implementeert de ValidationRule-interface niet.
acme_tracking:AC is de parameterarray ['AC']. Ook de regel zelf controleert het type van de waarde, zodat er geen typefout optreedt wanneer de regel op zichzelf wordt gebruikt.
Een ongeldig prefix of een onjuist aantal parameters wordt niet als invoerfout van de gebruiker behandeld, maar als configuratiefout in de regeldefinitie en leidt tot een exception. Wanneer de regel bij een lege waarde wordt overgeslagen, wordt ook deze configuratiecontrole niet uitgevoerd, dus je hebt ook tests nodig met een geldige, niet-lege waarde.
Registreren nadat de Factory is geresolved
Registreer de regel en de verwerking voor het vervangen van meldingen vanuitboot() in src/CourierServiceProvider.php.
callAfterResolving() wacht op de aanmaak als de Factory nog niet is geresolved, en registreert direct bij een Factory die al wel is geresolved. De hook zelf wordt in detail uitgelegd in Hooks na het resolven van services in packages.
Bij de klassestring TrackingCode::class.'@validate' wordt de klasse tijdens de validatie via de container geresolved en wordt de methode aangeroepen. Ook als je @validate weglaat en alleen de klassenaam opgeeft, is de standaardmethodenaam validate. Als de constructor afhankelijkheden heeft, bind ze dan zodat de container ze kan resolven.
Dit voorbeeld registreert de handler niet als singleton en heeft geen properties die invoer opslaan. Verwerk de gegevens tijdens de validatie via de argumenten, en ontwerp het zo dat er geen requestspecifieke state wordt vastgelegd in closures die de Factory bewaart.
Opgeven vanuit de gebruikende applicatie
bail stopt de volgende regels zodra een eerdere regel voor dat attribuut faalt. Verdeel de rollen: required voor de verplichting en acme_tracking voor het formaat.
Gebruik voor de publieke naam consequent een unieke snake case zoals acme_tracking. Bij registratie onder dezelfde naam voor hetzelfde soort extensie overschrijft de latere registratie de eerdere. Bovendien wordt, als er een ingebouwde methode zoals validateRequired() bestaat, die methode direct aangeroepen, dus je kunt ingebouwde validatie niet vervangen met een extensie met dezelfde naam.
De foutmeldingen van de gebruiker behouden
De melding voor een gewone stringregel wordt grofweg in de volgende volgorde van prioriteit gekozen. Speciale vertakkingen zoals bij grootteregels vallen hier buiten.
Nadat Laravel onder andere
:attribute heeft vervangen, wordt de aangepaste replacer aangeroepen. De replacer ontvangt vijf argumenten: de gekozen melding, de attribuutnaam, de regelnaam, de parameterarray en de Validator. In het eerdere voorbeeld is het ongebruikte vijfde argument weggelaten.
Om in de applicatie een standaardtekst in het Japans op te geven, voeg je acme_tracking toe aan de geretourneerde array in de bestaande lang/ja/validation.php. Het onderstaande voorbeeld toont de toe te voegen entry en verwijdert geen andere ingebouwde meldingen.
__('...') uitvoert en het resultaat als fallback opslaat, blijft de string van de toen actieve locale in de Factory achter. Gebruik in applicaties die van locale wisselen de vertaling op het moment dat de fout wordt gegenereerd.
Bij gebruik van vertalingen met package-namespace
Als je inboot() loadTranslationsFrom(__DIR__.'/../lang', 'acme-courier') aanroept, kun je onder andere de lang/ja/validation.php van het package benaderen met acme-courier::validation.tracking_code.
Alleen een vertaalsleutel als derde argument aan extend() doorgeven, leidt echter niet tot automatische vertaling. De Factory bewaart die als gewone fallbackstring. Als je extend() en replacer() in de eerdere hook vervangt door de volgende registratie, wordt de vertaling van het package alleen opgehaald wanneer de fallback wordt gekozen.
validation.php van elke locale in het package van een tracking_code-entry. Voor de Japanse tekst kun je dezelfde tekst gebruiken als in de eerdere acme_tracking-entry.
Omdat hier binnen de replacer een nieuwe vertaalstring wordt opgehaald, wordt ook :attribute expliciet aan de vertaling doorgegeven. Laravels standaardvervanging wordt niet opnieuw op deze retourwaarde toegepast. Wanneer een eigen melding van de gebruiker wordt gekozen, blijft die tekst behouden. Zie Packagevertalingen overschrijven en bijwerken voor het overschrijven van gedistribueerde vertalingen.
De uitvoeringsvoorwaarden van Implicit en nullable begrijpen
extendImplicit() registreert een regel die ook bij ontbrekende attributen of lege strings in aanmerking komt voor validatie. Het betekent niet “altijd laten falen” of “alle andere voorwaarden voor overslaan negeren”.
De tabel vergelijkt de uitvoeringsvoorwaarden per regel. Gevallen waarin de verwerking eerder stopt door
bail, het uitsluiten van attributen, stopOnFirstFailure() en dergelijke staan hier los van. Bij HTTP-invoer kunnen lege strings door middleware naar null worden omgezet, dus test lege strings en null afzonderlijk.
Voor de formaatregel in dit voorbeeld volstaat de combinatie van de gewone extend() en required. Als je een gepubliceerde regel naar Implicit wijzigt, kan invoer die voorheen niet werd gevalideerd gaan falen, dus behandel dat als een compatibiliteitswijziging.
Verwijzingen binnen arrays resolven met Dependent-regels
Voor regels die de naam van een ander veld als parameter nemen, kun jeextendDependent() gebruiken. Bij het valideren van items.*.confirmed_tracking wordt de parameter items.*.tracking omgezet naar bijvoorbeeld items.0.tracking in dezelfde rij. Met de gewone extend() vindt deze vervanging niet plaats.
Hieronder volgt een overeenkomstregel om dit mechanisme te verkennen. Voor een eenvoudige controle op overeenkomst kun je in een echte applicatie de ingebouwde regel same gebruiken. Beschouw dit als voorbeeld voor het toepassen op package-specifieke validatie tussen velden.
Voeg de regel toe aan de Factory die je vanuit de hook ontvangt.
getData() op het vierde argument geeft de te valideren gegevens, niet alleen de gevalideerde gegevens. Definieer de benodigde regels voor zowel het verwijzende veld als het doelveld.
Een Dependent-regel wordt bovendien niet Implicit. Geef de verplichting bij ontbrekende of lege waarden apart op. De implementatie past op de parameters escaping van punten en vervanging van * toe, dus vermijd API’s die willekeurige strings anders dan veldnamen in de parameters mengen.
Van registratie tot validatie testen in een applicatie
Maaktests/Feature/TrackingRuleTest.php aan in een Laravel 13-applicatie waarin het package en de service provider worden geladen. Naast tests van de klasse op zich valideer je registratie en meldingsverwerking via de echte Factory.
Aandachtspunten voor langdurig onderhoud
- Documenteer de regelnaam, de betekenis en het aantal parameters, de verplichting en de geaccepteerde waardetypen als publieke API.
- Valideer ongeldige parameters, ontbrekende waarden, lege strings en
null, en combinaties vannullable,sometimesenbail. - Controleer
messages()van de gebruiker, weergavenamen van attributen, het wisselen van locale en het overschrijven van packagevertalingen. - Controleer bij Dependent-regels met meerdere rijen en geneste arrays dat er niet naar waarden in andere rijen wordt verwezen.
- Controleer registratie bij zowel niet-geresolvede als geresolvede Factories, en verwacht niet dat wijzigingen met terugwerkende kracht in reeds aangemaakte Validators doorwerken.
- Voorkom naamconflicten met andere packages en meng dezelfde naam niet over gewone, Implicit- en Dependent-registraties.
- Herstart het proces om wijzigingen in langlevende workers door te voeren, en laat geen invoer of gebruikersgegevens achter in gedeelde handlers.
Geraadpleegde primaire bronnen
- Officiële Laravel-documentatie: aangepaste regels en Implicit-regels
- Officiële Laravel-documentatie: service providers en vertalingen van packages
- Factory: make, extend, extendImplicit, extendDependent en replacer
- Validator: uitvoeringsvoorwaarden, registratie van extensies en het resolven van klassen
- ValidationRuleParser: het parsen van stringregels
- FormatsMessages: prioriteit en vervanging van meldingen
- ValidationServiceProvider: singletonregistratie van validator
- ServiceProvider: callAfterResolving
- Officiële tests: doorgeven van extensies en fallbacks vanuit de Factory
- Officiële tests: string-, klasse-, Implicit- en Dependent-regels