Hoe te programmeren met Yii2 gespecialiseerde validaties

Wat je gaat creëren

Als je vraagt: "Wat is Yii?" bekijk mijn eerdere tutorial: Introductie tot het Yii Framework, die de voordelen van Yii bekijkt en een overzicht bevat van wat er nieuw is in Yii 2.0, uitgebracht in oktober 2014.

In deze serie Programming With Yii2 begeleid ik lezers in gebruik van het onlangs bijgewerkte Yii2 Framework voor PHP. Deze tutorial is ons tweede deel, kijkend naar de validators van Yii2. Validators vereenvoudigen de code die nodig is om invoer te valideren, d.w.z. conformiteit of niet-conformiteit van gegevensinvoer te verifiëren, typisch van gebruikers via webformulieren. We gaan specifiek een aantal van de ingebouwde speciale validaties onderzoeken die gemeenschappelijk zijn voor webontwikkeling.

Hier is een lijst met de ingebouwde Yii-validators en links naar documentatie die we gaan verkennen:

  • CaptchaValidator: Valideert een CAPTCHA-formulierverificatieveld.
  • CompareValidator: vergelijkt twee waarden van de vorm of een constante, bijvoorbeeld x moet kleiner zijn dan 99.
  • EmailValidator: zorgt ervoor dat een waarde een geldig e-mailadres is.
  • ExistValidator: zorgt ervoor dat een waarde bestaat in een andere tabel.
  • FileValidator: zorgt voor het bestaan ​​van een geüpload bestand.
  • ImageValidator: valideert beeld- en afbeeldingseigenschappen.
  • RangeValidator: zorgt ervoor dat een waarde binnen een lijst met waarden valt.
  • RegularExpressionValidator: voert validatie uit tegen een voorwaarde die is gedefinieerd door een reguliere expressie.
  • UniqueValidator: zorgt ervoor dat waarde uniek is binnen een tabel, zoals een e-mailadres.
  • UrlValidator: zorgt ervoor dat de waarde in het URL-formaat is, bijv. http://yourdomain.com.

Ik ga u door voorbeelden van elk van deze validaties leiden met behulp van de Hello-applicatie codebase van vorige tutorials en een paar van onze Building Your Startup Series die ook Yii2 gebruikt. Gebruik de GitHub-links op deze pagina om de code te krijgen.

Ter herinnering, ik neem wel deel aan de commentaarthreads hieronder. Ik ben vooral geïnteresseerd als je aanvullende ideeën hebt of onderwerpen wilt voorstellen voor toekomstige zelfstudies. Je kunt me ook @reifman bereiken via Twitter of e-mailen naar Lookahead Consulting.

Wat is een Validator?

Als u een webontwikkelaar bent, weet u waarschijnlijk dat gebruikersinvoer niet vertrouwd kan worden. Gebruikers kunnen bijvoorbeeld SQL-injectietechnieken gebruiken om te proberen query's uit te voeren die wachtwoorden wijzigen of ontmaskeren. Iemand gebruikte ooit een SQL-injectie tegen mijn open source PHPList-installatie en wist een van mijn wachtwoorden te achterhalen (PHPList heeft deze in gewone tekst opgeslagen). Meestal wilt u er alleen voor zorgen dat de gegevensgebruikers voldoen aan de typen, vormen en bereiken van uw toepassing.

Validators bouwen met de hand in PHP kost tijd. Het Yii Framework biedt een heleboel basislijnvalidatiefuncties, dus u hoeft ze niet vanaf nul te bouwen. Maar als u een aantal aangepaste extensies nodig hebt, is dat ook eenvoudig.

Validaties zijn nog een andere reden waarom ik denk dat het altijd zinvol is om applicaties te bouwen op een web framework zoals Yii in plaats van vanilla PHP.

In eerdere afleveringen hebben we ook veel gesproken over Yii's codegenerator, Gii. Een van de voordelen van Gii is dat het de juiste validatieregels voor uw modellen zal schrijven op basis van de definities van het SQL-type in het schema. Dit bespaart veel tijd.

Misschien wil je teruggaan naar onze laatste aflevering om meer te lezen over de basistypevalidaties van Yii2.

Laten we beginnen met het bekijken van de volgende set van Yii2's ingebouwde validators.

De volgende reeks validators

De Captcha-validator

Laten we beginnen met CaptchaValidator die controleert of er een correct antwoord is op een CAPTCHA-verificatieveld. CAPTCHA's helpen ervoor te zorgen dat een mens het formulier invult, hopelijk houdt het geautomatiseerde scripts van indienen.

Hier is een voorbeeld van de Yii Captcha in actie:

In onze Hello-codebasis heb ik ons ​​voorbeeldformulier vereenvoudigd om de Thought- en Captcha-velden voor nu toe te voegen. Hier volgt een overzicht van de regeldefinities van de modelcode:

class Sample extends \ yii \ db \ ActiveRecord public $ captcha; / ** * @inheritdoc * / public function rules () return [['thought'], 'string', 'max' => 255], [['thought'], 'trim'], [[' gedachte '],' vereist '], [[' captcha '],' captcha '],]; 

De captcha maakt geen deel uit van ons databaseschema - deze wordt alleen gebruikt om het formulier te verifiëren. Daarom heb ik een attribuut toegevoegd aan het model, bijv. public $ captcha;.

Dit is de weergavecode voor het formulier. We moeten de Captcha-bibliotheek bovenaan opnemen.

 
errorSummary ($ model); ?> field ($ model, 'thought') -> textInput (['maxlength' => 255])?> field ($ model, 'captcha') -> widget (\ yii \ captcha \ Captcha :: classname (), [// configureer hier extra widget eigenschappen])?>
isNewRecord? 'Maken': 'Update', ['class' => $ model-> isNewRecord? 'btn btn-success': 'btn btn-primary'])?>

Dit is hoe de Captcha-validatie eruit ziet in actie:

Als u op Captcha klikt, genereert Yii een nieuwe afbeelding.

De Compare Validator

Laten we nu verdergaan naar de CompareValidator. Deze validator vergelijkt twee waarden van het formulier of een enkele formulierwaarde met een constante, zoals x moet kleiner zijn dan 99.

Voor dit voorbeeld wil ik ervoor zorgen dat gebruikersinvoer voor rang groter is dan nul maar kleiner dan of gelijk aan 100.

Ten eerste zal ik het invoerveld voor het rangkenmerk toevoegen aan ons formulier:

 errorSummary ($ model); ?> field ($ model, 'thought') -> textInput (['maxlength' => 255])?> field ($ model, 'rank') -> textInput ()?> field ($ model, 'captcha') -> widget (\ yii \ captcha \ Captcha :: classname (), [// configureer hier extra widget eigenschappen])?> 

Vervolgens voeg ik twee vergelijkingsvalidatieregels toe aan ons model:

 public function rules () return [['thought'], 'string', 'max' => 255], [['thought'], 'trim'], [['thought'], 'required'] , [['captcha'], 'captcha'], [['rang'], 'integer'], ['rang', 'vergelijken', 'compareValue' => 0, 'operator' => '>'] , ['rang', 'vergelijken', 'comparewaarde' => 100, 'operator' => '<='], ];  

U kunt hier een volledige lijst met beschikbare vergelijkingsoperatoren zien.

Dit is hoe ons formulier eruitziet wanneer de gebruiker een ongeldig kenmerk indient:

Als we de specifieke beperkingsregels in één foutbericht willen weergeven, kunt u met Yii Validators de aan de gebruiker getoonde fout aanpassen, zoals deze:

Het implementeren van dit is vrij eenvoudig met de toevoeging van het berichtattribuut:

public function rules () return [['thought'], 'string', 'max' => 255], [['thought'], 'trim'], [['thought'], 'required'] , [['captcha'], 'captcha'], [['rang'], 'integer'], ['rang', 'vergelijken', 'comparewaarde' => 0, 'operator' => '>', 'message' => Yii :: t ('app', 'Rank moet tussen 0 en 100 inclusief zijn.')], ['rank', 'compare', 'compareValue' => 100, 'operator' => '<=','message'=>Yii :: t ('app', 'Rang moet tussen 0 en 100 liggen.')],]; 

Ons schema bijwerken om meer validaties te testen

Voor sommige van deze volgende validatietests ga ik u vragen om enkele velden aan de database toe te voegen.

In \ Migraties \ m150219_235923_create_sample_table.php, we zullen enkele nieuwe velden toevoegen om de volgende reeks validators te testen: e-mail, URL, bestandsnaam, enz.

$ this-> createTable ('% sample', ['id' => Schema :: TYPE_PK, 'thought' => Schema :: TYPE_STRING. 'NOT NULL DEFAULT ""', 'goodness' => Schema :: TYPE_SMALLINT. 'NOT NULL DEFAULT 0', 'rank' => Schema :: TYPE_INTEGER. 'NOT NULL', 'censorship' => Schema :: TYPE_STRING. 'NOT NULL', 'happened' => Schema :: TYPE_DATE . 'NOT NULL', 'email' => Schema :: TYPE_STRING. 'NOT NULL DEFAULT ""', 'url' => Schema :: TYPE_STRING. 'NOT NULL DEFAULT ""', 'bestandsnaam' => Schema :: TYPE_STRING. 'NOT NULL', 'avatar' => Schema :: TYPE_STRING. 'NOT NULL',], $ tableOptions); 

Voer de migratie vervolgens uit om de tabel te verwijderen en vervolgens omhoog:

Admins-MBP: hallo Jeff $ ./yii migrate / down 1 Yii Migration Tool (gebaseerd op Yii v2.0.2) Totale 1 migratie die moet worden teruggezet: m150219_235923_create_sample_table Keer de bovenstaande migratie terug? (ja | nee) [nee]: ja *** terugzetten m150219_235923_create_sample_table> drop table % sample ... done (tijd: 0.002s) *** teruggezet m150219_235923_create_sample_table (tijd: 0.005s) Migratie succesvol uitgevoerd. Admins-MBP: hallo Jeff $ ./yii migrate / up 1 Yii Migration Tool (gebaseerd op Yii v2.0.2) Totaal 1 nieuwe migratie die moet worden toegepast: m150219_235923_create_sample_table Pas de bovenstaande migratie toe? (ja | nee) [nee]: ja *** toepassen m150219_235923_create_sample_table> tabel maken % sample ... klaar (tijd: 0.007s) *** toegepast m150219_235923_create_sample_table (tijd: 0.010s) Migratie succesvol uitgevoerd.

We zijn nu klaar om de e-mail- en URL-validators te testen.

Validators voor e-mail en URL's

De EmailValidator zorgt ervoor dat een waarde een geldig e-mailadres is en de UrlValidator zorgt ervoor dat een waarde in URL-indeling is, bijvoorbeeld http://yourdomain.com. 

Het is vrij eenvoudig om regels te maken voor onze nieuwe e-mail- en URL-velden:

 public function rules () return [['thought'], 'string', 'max' => 255], [['email'], 'email'], [['url'], 'url'], 

Dit is de weergavecode voor het formulier. Merk op hoe ik aangepaste labels gebruik om de bruikbaarheid van formulieren te verbeteren:

errorSummary ($ model); ?> field ($ model, 'thought') -> textInput (['maxlength' => 255])?> veld ($ model, 'email') -> textInput () -> label (Yii :: t ('app', 'Uw e-mailadres'))?> field ($ model, 'url') -> textInput () -> label (Yii :: t ('app', 'Uw website'))?>

Hier zijn de validators in actie:

Deze zijn uiteraard zeer nuttig voor webtoepassingen.

De Exist Validator

De ExistValidator is super handig in bepaalde scenario's. Het kan ervoor zorgen dat een waarde bestaat in een andere tabel. En het kan op verschillende manieren worden gebruikt - hier zijn enkele voorbeelden gegeven in de documentatie:

// a1 moet bestaan ​​['a1', 'exist'] // a1 moet bestaan, maar de waarde ervan zal a2 gebruiken om te controleren op het bestaan ​​['a1', 'exist', 'targetAttribute' => 'a2' ] // a1 en a2 moeten samen bestaan, en beide zullen een foutmelding ontvangen [['a1', 'a2'], 'exists', 'targetAttribute' => ['a1', 'a2']] // a1 en a2 moeten samen bestaan, alleen a1 zal een foutmelding ontvangen ['a1', 'exist', 'targetAttribute' => ['a1', 'a2']] // a1 moet bestaan ​​door het bestaan ​​van beide te controleren a2 en a3 (met behulp van de waarde a1) ['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']]

De Yii-documentatie benadrukt dat Exist kan worden gebruikt om "te controleren of een buitenlandse sleutel een waarde bevat die kan worden gevonden in de buitenlandse tabel."

Voor ons voorbeeld ga ik een regel maken die controleert of het e-mailadres in het formulier al bestaat in onze geregistreerde gebruikerstabel. Om dit te doen, gebruiken we de targetClass die aan Yii vertelt welke klasse (of modeltabel) het e-mailadres van de gebruiker opzoekt voor validatie. 

Dit is de regeldefinitie - let op de opname van ons gebruikersmodel bovenaan:

 255], [['email'], 'email'], [['email'], 'exist', 'targetClass' => '\ app \ modellen \ Gebruiker', 'bericht' => Yii :: t ( 'app', 'Sorry, die persoon heeft nog niet geregistreerd')], [['url'], 'url'],

Dit geeft Yii de opdracht om de gebruikerstabel te doorzoeken om er zeker van te zijn dat het opgegeven e-mailadres overeenkomt met een eerder geregistreerde gebruiker.

Hier is hoe het eruit ziet in actie:

U kunt hier meer informatie vinden over de Exist-validatie en de bijbehorende permutaties.

De bestands- en beeldvalidators

Vervolgens toon ik voorbeelden van de FileValidator, die het bestaan, het MIME-type en de grootte van een geüploade bestand garandeert, en de ImageValidator, die de afbeelding en de eigenschappen ervan valideert.

Om de Bestands- en Beeldvalidators te verkennen, laten we eens kijken naar een voorbeeld uit de Building Your Startup With PHP series: Gebruikersinstellingen, Profielafbeeldingen en Contactgegevens. In die aflevering in het model UserSettings staan ​​we gebruikers toe om een ​​bestand te uploaden voor hun profielafbeelding.

Het afbeeldingskenmerk accepteert het geüploade bestand:

 public function rules () return [[[user_id ',],' required '], [[' user_id ',],' unique '], [[' image '],' safe '], [[' afbeelding '],' bestand ',' extensies '=>' jpg, gif, png '], [[' afbeelding '],' bestand ',' maxSize '=>' 100000 '], [' afbeelding ',' afbeelding ' , 'extensions' => 'png, jpg, gif', 'minWidth' => 100, 'maxWidth' => 400, 'minHeight' => 100, 'maxHeight' => 400,], 

De FileValidators zorgen ervoor dat de afbeelding eindigt met een juiste beelduitbreiding en minder dan 100.000 bytes is. 

De ImageValidator verifieert ook het extensietype, evenals de breedte- en hoogtebereiken voor de afbeelding.

Hier is een voorbeeld van fouten die zijn gegenereerd door het uploaden van een afbeelding waarvan de afmetingen groter zijn dan 400 x 400 pixels:

Dat is mijn assistent hierboven, die mijn tutorials graag kopieerde.

Het bereik in Validator

Er is ook de RangeValidator die ervoor zorgt dat een waarde binnen een lijst van toegestane items valt. 

Laten we voor ons voorbeeld het veld voor censuur opnieuw toevoegen aan het formulier:

errorSummary ($ model); ?> field ($ model, 'thought') -> textInput (['maxlength' => 255])?> veld ($ model, 'email') -> textInput () -> label (Yii :: t ('app', 'Uw e-mailadres'))?> field ($ model, 'url') -> textInput () -> label (Yii :: t ('app', 'Uw website'))?> field ($ model, 'censorship') -> textInput ()?> field ($ model, 'rank') -> textInput ()?> field ($ model, 'captcha') -> widget (\ yii \ captcha \ Captcha :: classname (), [// configureer hier extra widget eigenschappen])?>

Vervolgens voegen we een RangeValidator toe om het antwoord aan a te koppelen Ja of Nee draad:

 public function rules () return [['thought'], 'string', 'max' => 255], ['thought', 'match', 'pattern' => '/ ^ [az] [A- Za-z,; \ "\\ s] + [!?.] $ / I ',' message '=> Yii :: t (' app ',' Je gedachten moeten een complete zin van alfabetische tekens vormen. ') ], [['email'], 'email'], [['email'], 'exist', 'targetClass' => '\ app \ modellen \ Gebruiker', 'bericht' => Yii :: t (' app ',' Sorry, die persoon heeft nog niet geregistreerd ')], [[' url '],' url '], [' censuur ',' in ',' bereik '=> [' yes ',' nee ',' Ja ',' Nee '],' bericht '=> Yii :: t (' app ',' De censoren eisen een ja of nee antwoord ')],

Hier is een voorbeeld van de RangeValidator in actie:

De Validator voor reguliere expressie

Laten we vervolgens kijken naar de RegularExpressionValidator, die validatie uitvoert tegen een voorwaarde die wordt gedefinieerd door een reguliere expressie. 

In ons voorbeeld gebruik ik de volgende regex om volledige zinnen te combineren met alfabetische tekens. Dit betekent dat ze moeten eindigen met (!,? Of.) En geen numerieke tekens hebben.

 public function rules () return [['thought'], 'string', 'max' => 255], ['thought', 'match', 'pattern' => '/ ^ [az] [A- Za-z,; \ "\\ s] + [!?.] $ / I ',' message '=> Yii :: t (' app ',' Je gedachten moeten een complete zin van alfabetische tekens vormen. ') ], 

Hier is een voorbeeld van gebruikersinvoer dat de test niet doorstaat vanwege de aantallen en het ontbreken van een slepend leesteken:

Hier is een geldige zin:

Mogelijk bent u ook geïnteresseerd in Eight Regular Expressions You Should Know (Tuts +) als referentie voor algemene regex-patronen.

De unieke validator

Laten we tot slot eens kijken naar de UniqueValidator, die ervoor zorgt dat een waarde uniek is binnen een tabel, zoals een e-mailadres of een slak.

Ik heb Sluggable Behavior eerder in deze serie besproken, die zijn eigen ingebouwde uniciteitsondersteuning biedt. Laten we echter nog een paar voorbeelden bekijken van de Building Your Startup With PHP-serie. 

In de codebase voor Meeting Planner (uit de meer recente tutorial-afleveringen) in het plaatsmodel (\ Frontend \ modellen \ Place.php), gebruiken we de unieke validator op verschillende manieren:

public function rules () return [['naam', 'slug'], 'required'], [['place_type', 'status', 'created_by', 'created_at', 'updated_at'], 'integer' ], [['naam', 'google_place_id', 'slug', 'website', 'full_address', 'vicinity'], 'string', 'max' => 255], [['' website '],' url '], [[' slug '],' uniek '], [[' zoekvak '],' uniek ',' targetAttribute '=>' google_place_id '], [[' naam ',' volledig_adres '],' uniek ' , 'targetAttribute' => ['name', 'full_address']],]; 

Ten eerste gebruiken we de unieke regel met de slug om Sluggable Behavior te verbeteren, wat overbodig is; maar u kunt het validatieformaat zien.

Ten tweede controleren we of de resultaten van het zoekvak Google Places Autocomplete resulteren in het verborgen veld voor google_place_id uniek zijn omdat het nog niet bestaat binnen de Places-tabel. We voorkomen in feite dubbele Google Places-ID's. 

Het belangrijke stuk hiervan is dat Yii2's unieke validator ons in staat stelt uniciteit op het zichtbare veld af te dwingen (zoekbox) Terwijl het wordt gevalideerd op de secundaire kolom die wordt geretourneerd via AJAX van Google (google_place_id).

Ten derde zorgen we ervoor naam en volledig adres zijn uniek samen. Met andere woorden, namen van dubbele plaatsen zijn in orde. Er kan een bazillion Starbucks zijn. We willen echter niet dat iemand tweemaal dezelfde Starbucks-locatie betreedt.

Notitie: Starbucks-koffie is geen effectieve stimulans voor softwareontwikkelaars. Ik moedig je aan om regelmatig onafhankelijke koffiehuizen te bezoeken.

Hier is een voorbeeld van in actie:

Wat is het volgende?

Ik hoop dat je het erover eens bent hoe eenvoudig en nuttig Yii2 validators zijn voor webontwikkeling. Ik kan me gewoon niet voorstellen ooit terug te keren naar de ontwikkeling van vanille PHP zonder de hulp van een raamwerk.

Kijk uit naar komende tutorials in mijn Programming With Yii2-serie terwijl ik verder duik in verschillende aspecten van het framework. In de volgende aflevering ga ik de geavanceerde validatiefuncties van Yii2 bekijken, zoals:

  • Voorwaardelijke validatie om alleen een validatieregel uit te voeren als een specifieke gebeurtenis waar is
  • Aangepaste validators om essentiële validaties te creëren die verder gaan dan wat Yii out of the box biedt
  • Validatie van clientzijde om gebruik te maken van de ingebouwde ActiveForm JavaScript-validatie van Yii zonder dat een vernieuwing van de pagina vereist is
  • AJAX-validatie voor het implementeren van AJAX-validaties aan de serverkant om de JavaScript-pagina validatiemogelijkheden aan de clientzijde van Yii uit te breiden.
  • Validatiegebeurtenissen om validatie op te heffen of specifieke functionaliteit uit te voeren vóór en / of na validatie
  • Scenario's definiëren om selectief regels voor bepaalde situaties toe te passen
  • Ad-hocvalidatie om validatieregels te gebruiken onafhankelijk van formulierinzending

Ik verwelkom aanvragen voor functies en onderwerpen. Je kunt ze plaatsen in de reacties hieronder, neem contact met me op @reifman op Twitter of mail me op Lookahead Consulting.

Als je wilt weten wanneer de volgende Yii2-tutorial arriveert, kun je ook mijn Tuts + -instructorpagina bekijken. Het bevat altijd links naar mijn artikelen onmiddellijk nadat ze zijn gepubliceerd.

Gerelateerde Links

  • Yii2 Gids voor validatie van gebruikersinvoer
  • Yii2 Guide to Core Validators
  • Yii2 Validators (documentatie)
  • Yii2 Developer Exchange, mijn eigen Yii2-bronsite