Schema: Validarea datelor
O bibliotecă practică pentru validarea și normalizarea structurilor de date în raport cu o schemă dată, cu o API inteligentă și ușor de înțeles.
Instalare:
Utilizare de bază
În variabila $schema
avem o schemă de validare (ce înseamnă exact acest lucru și cum să o creăm vom spune
mai târziu) și în variabila $data
avem o structură de date pe care dorim să o validăm și să o normalizăm.
Aceasta poate fi, de exemplu, date trimise de utilizator prin intermediul unui API, fișier de configurare etc.
Sarcina este gestionată de clasa Nette\Schema\Processor, care procesează datele de intrare și fie returnează datele normalizate, fie aruncă o excepție Nette\Schema\ValidationException în caz de eroare.
Metoda $e->getMessages()
returnează o matrice cu toate șirurile de mesaje, iar
$e->getMessageObjects()
returnează toate mesajele ca obiecte Nette\Schema\Message.
Definirea schemei
Și acum să creăm o schemă. Clasa Nette\Schema\Expect este utilizată pentru a o defini,
definim de fapt așteptările cu privire la modul în care ar trebui să arate datele. Să spunem că datele de intrare trebuie
să fie o structură (de exemplu, o matrice) care conține elementele processRefund
de tip bool și
refundAmount
de tip int.
Credem că definiția schemei pare clară, chiar dacă o vedeți pentru prima dată.
Să trimitem următoarele date pentru validare:
Rezultatul, adică valoarea $normalized
, este obiectul stdClass
. Dacă dorim ca ieșirea să fie
o matrice, adăugăm un cast la schema Expect::structure([...])->castTo('array')
.
Toate elementele structurii sunt opționale și au o valoare implicită null
. Exemplu:
Faptul că valoarea implicită este null
nu înseamnă că aceasta ar fi acceptată în datele de intrare
'processRefund' => null
. Nu, datele de intrare trebuie să fie booleene, adică numai true
sau
false
. Ar trebui să permitem în mod explicit null
prin Expect::bool()->nullable()
.
Un element poate fi făcut obligatoriu folosind Expect::bool()->required()
. Schimbăm valoarea implicită la
false
folosind Expect::bool()->default(false)
sau la scurt timp folosind
Expect::bool(false)
.
Și dacă am dori să acceptăm 1
and 0
în afară de booleeni? Atunci enumerăm valorile permise, pe
care le vom normaliza, de asemenea, la boolean:
Acum cunoașteți elementele de bază ale modului în care este definită schema și cum se comportă elementele individuale ale structurii. Vom arăta acum ce alte elemente pot fi utilizate în definirea unei scheme.
Tipuri de date: type()
Toate tipurile de date PHP standard pot fi enumerate în schemă:
Și apoi toate tipurile acceptate de validatoare prin
Expect::type('scalar')
sau prin abrevierea Expect::scalar()
. De asemenea, sunt acceptate și nume de
clase sau interfețe, de exemplu Expect::type('AddressEntity')
.
De asemenea, puteți utiliza notația de uniune:
Valoarea implicită este întotdeauna null
, cu excepția array
și list
, unde este
o matrice goală. (O listă este o matrice indexată în ordine crescătoare a cheilor numerice de la zero, adică o matrice
neasociativă).
Array de valori: arrayOf() listOf()
Matricea este o structură prea generală, fiind mai util să se specifice exact ce elemente poate conține. De exemplu, un array ale cărui elemente pot fi doar șiruri de caractere:
Al doilea parametru poate fi utilizat pentru a specifica cheile (începând cu versiunea 1.2):
Lista este o matrice indexată:
Parametrul poate fi, de asemenea, o schemă, astfel încât putem scrie:
Valoarea implicită este o matrice goală. Dacă specificați valoarea implicită, aceasta va fi îmbinată cu datele
transmise. Acest lucru poate fi dezactivat utilizând mergeDefaults(false)
(începând cu versiunea 1.1).
Enumerare: anyOf()
anyOf()
este un set de valori sau de scheme care pot reprezenta o valoare. Iată cum se scrie o matrice de
elemente care pot fi fie 'a'
, true
, fie null
:
Elementele enumerării pot fi, de asemenea, scheme:
Metoda anyOf()
acceptă variantele ca parametri individuali, nu ca matrice. Pentru a-i transmite o matrice de
valori, utilizați operatorul de despachetare anyOf(...$variants)
.
Valoarea implicită este null
. Utilizați metoda firstIsDefault()
pentru a face din primul element
valoarea implicită:
Structuri
Structurile sunt obiecte cu chei definite. Fiecare dintre aceste perechi cheie ⇒ valoare este denumită „proprietate“:
Structurile acceptă matrici și obiecte și returnează obiecte stdClass
.
În mod implicit, toate proprietățile sunt opționale și au o valoare implicită de null
. Puteți defini
proprietățile obligatorii utilizând required()
:
Dacă nu doriți să afișați proprietăți care au doar o valoare implicită, utilizați skipDefaults()
:
Deși null
este valoarea implicită a proprietății optional
, nu este permisă în datele de intrare
(valoarea trebuie să fie un șir de caractere). Proprietățile care acceptă null
sunt definite utilizând
nullable()
:
Matricea tuturor proprietăților structurii este returnată de metoda getShape()
.
În mod implicit, nu pot exista elemente suplimentare în datele de intrare:
Ceea ce se poate schimba cu otherItems()
. Ca parametru, vom specifica schema pentru fiecare element
suplimentar:
Puteți crea o structură nouă derivând din alta folosind extend()
:
Array
Un array cu chei definite. Se aplică aceleași reguli ca pentru structuri.
De asemenea, puteți defini un array indexat, cunoscut sub numele de tuple:
Deprecieri
Puteți deprecia o proprietate folosind opțiunea deprecated([string $message])
metoda . Notificările de
depreciere sunt returnate de $processor->getWarnings()
:
Domenii: min() max()
Utilizați min()
și max()
pentru a limita numărul de elemente pentru array-uri:
Pentru șirurile de caractere, limitați lungimea acestora:
Pentru numere, limitați valoarea acestora:
Desigur, este posibil să se menționeze doar min()
, sau doar max()
:
Expresii regulate: pattern()
Cu ajutorul pattern()
, puteți specifica o expresie regulată cu care trebuie să se potrivească
întregul șir de intrare (adică ca și cum ar fi înfășurat în caractere ^
a $
):
Aserțiuni personalizate: assert()
Puteți adăuga orice alte restricții folosind assert(callable $fn)
.
Sau
Puteți adăuga propria descriere pentru fiecare afirmație. Aceasta va face parte din mesajul de eroare.
Metoda poate fi apelată în mod repetat pentru a adăuga mai multe constrângeri. Ea poate fi amestecată cu apelurile la
transform()
și castTo()
.
Transformare: transform()
Datele validate cu succes pot fi modificate cu ajutorul unei funcții personalizate:
Metoda poate fi apelată în mod repetat pentru a adăuga mai multe transformări. Ea poate fi amestecată cu apeluri la
assert()
și castTo()
. Operațiile vor fi executate în ordinea în care sunt declarate:
Metoda transform()
poate transforma și valida valoarea simultan. Acest lucru este adesea mai simplu și mai
puțin redundant decât înlănțuirea transform()
și assert()
. În acest scop, funcția primește un
obiect Context cu o metodă addError()
,
care poate fi utilizată pentru a adăuga informații despre problemele de validare:
Casting: castTo()
Datele validate cu succes pot fi turnate:
În plus față de tipurile native PHP, puteți, de asemenea, să faceți cast la clase. Se distinge dacă este vorba de o clasă simplă fără constructor sau de o clasă cu constructor. În cazul în care clasa nu are constructor, se creează o instanță a acesteia și toate elementele structurii sunt scrise în proprietățile sale:
În cazul în care clasa are un constructor, elementele structurii sunt transmise constructorului ca parametri numiți:
Castingul combinat cu un parametru scalar creează un obiect și transmite valoarea acestuia ca unic parametru către constructor:
Normalizare: before()
Înainte de validarea propriu-zisă, datele pot fi normalizate cu ajutorul metodei before()
. Ca exemplu, să avem
un element care trebuie să fie o matrice de șiruri de caractere (de exemplu ['a', 'b', 'c']
), dar care primește
datele de intrare sub forma unui șir de caractere a b c
:
Maparea în obiecte: from()
Puteți genera o schemă de structură din clasă. Exemplu:
Sunt acceptate și clasele anonime:
Deoarece este posibil ca informațiile obținute din definiția clasei să nu fie suficiente, puteți adăuga o schemă personalizată pentru elemente cu ajutorul celui de-al doilea parametru: