Formulare utilizate independent
Nette Forms facilitează enorm crearea și procesarea formularelor web. Le puteți utiliza în aplicațiile dvs. complet independent de restul framework-ului, așa cum vom demonstra în acest capitol.
Dacă însă utilizați Nette Application și presentere, ghidul pentru utilizarea în presentere este destinat dvs.
Primul formular
Vom încerca să scriem un formular simplu de înregistrare. Codul său va fi următorul (codul complet):
Îl putem randa foarte ușor:
și în browser se va afișa astfel:

Formularul este un obiect al clasei Nette\Forms\Form
(clasa Nette\Application\UI\Form
se utilizează
în presentere). Am adăugat în el așa-numitele elemente nume, parolă și buton de trimitere.
Acum vom anima formularul. Prin interogarea $form->isSuccess()
vom afla dacă formularul a fost trimis și
dacă a fost completat valid. Dacă da, vom afișa datele. După definiția formularului, vom adăuga:
Metoda getValues()
returnează datele trimise sub forma unui obiect ArrayHash. Cum să schimbăm acest lucru vom arăta mai târziu. Obiectul $data
conține cheile name
și
password
cu datele completate de utilizator.
De obicei, trimitem datele direct pentru procesare ulterioară, cum ar fi inserarea într-o bază de date. Însă, în timpul
procesării poate apărea o eroare, de exemplu, numele de utilizator este deja ocupat. În acest caz, transmitem eroarea înapoi
formularului folosind addError()
și îl lăsăm să se randeze din nou, inclusiv cu mesajul de eroare.
După procesarea formularului, redirecționăm către pagina următoare. Acest lucru previne retrimiterea nedorită a formularului prin butonul reîmprospătare, înapoi sau prin navigarea în istoricul browserului.
Formularul se trimite standard prin metoda POST și către aceeași pagină. Ambele pot fi modificate:
Și cam asta e tot :-) Avem un formular funcțional și perfect securizat.
Încercați să adăugați și alte elemente de formular.
Accesul la elemente
Formularul și elementele sale individuale le numim componente. Ele formează un arbore de componente, unde rădăcina este chiar formularul. Putem accesa elementele individuale ale formularului în acest mod:
Elementele se elimină folosind unset:
Reguli de validare
Am menționat cuvântul valid, dar formularul nu are încă nicio regulă de validare. Să remediem acest lucru.
Numele va fi obligatoriu, așa că îl vom marca cu metoda setRequired()
, al cărei argument este textul mesajului
de eroare care se va afișa dacă utilizatorul nu completează numele. Dacă nu specificăm argumentul, se va utiliza mesajul de
eroare implicit.
Încercați să trimiteți formularul fără a completa numele și veți vedea că se afișează un mesaj de eroare, iar browserul sau serverul îl va respinge până când nu completați câmpul.
În același timp, nu puteți păcăli sistemul scriind, de exemplu, doar spații în câmp. Nici vorbă. Nette elimină automat spațiile de la începutul și sfârșitul șirului. Încercați. Este un lucru pe care ar trebui să-l faceți întotdeauna cu fiecare input de o singură linie, dar adesea se uită. Nette o face automat. (Puteți încerca să păcăliți formularul și să trimiteți un șir multilinie ca nume. Nici aici Nette nu se lasă păcălit și transformă sfârșiturile de linie în spații.)
Formularul se validează întotdeauna pe partea de server, dar se generează și o validare JavaScript, care se execută
instantaneu, iar utilizatorul află despre eroare imediat, fără a fi nevoie să trimită formularul la server. Acest lucru este
gestionat de scriptul netteForms.js
. Inserați-l în pagină:
Dacă vă uitați la codul sursă al paginii cu formularul, puteți observa că Nette inserează elementele obligatorii în
elemente cu clasa CSS required
. Încercați să adăugați următorul stil în șablon și eticheta „Nume” va fi
roșie. Astfel, marcăm elegant elementele obligatorii pentru utilizatori:
Alte reguli de validare le adăugăm cu metoda addRule()
. Primul parametru este regula, al doilea este din nou
textul mesajului de eroare și poate urma un argument al regulii de validare. Ce înseamnă asta?
Vom extinde formularul cu un nou câmp opțional „vârstă”, care trebuie să fie un număr întreg
(addInteger()
) și, în plus, într-un interval permis ($form::Range
). Și aici vom folosi al treilea
parametru al metodei addRule()
, prin care transmitem validatorului intervalul dorit ca pereche
[de la, până la]
:
Dacă utilizatorul nu completează câmpul, regulile de validare nu vor fi verificate, deoarece elementul este opțional.
Aici apare spațiu pentru o mică refactorizare. În mesajul de eroare și în al treilea parametru, numerele sunt menționate
duplicat, ceea ce nu este ideal. Dacă am crea formulare multilingve și mesajul care
conține numere ar fi tradus în mai multe limbi, o eventuală modificare a valorilor ar fi dificilă. Din acest motiv, este
posibil să folosim substituenții %d
, iar Nette va completa valorile:
Să revenim la elementul password
, pe care îl vom face, de asemenea, obligatoriu și vom verifica lungimea
minimă a parolei ($form::MinLength
), folosind din nou substituentul:
Vom adăuga în formular și câmpul passwordVerify
, unde utilizatorul introduce parola încă o dată, pentru
verificare. Folosind regulile de validare, vom verifica dacă ambele parole sunt identice ($form::Equal
). Și ca
parametru vom da o referință la prima parolă folosind paranteze drepte:
Folosind setOmitted()
, am marcat elementul a cărui valoare nu ne interesează de fapt și care există doar în
scopul validării. Valoarea nu se va transmite în $data
.
Astfel, avem un formular complet funcțional cu validare în PHP și JavaScript. Capacitățile de validare ale Nette sunt mult mai extinse, se pot crea condiții, se pot afișa și ascunde părți ale paginii în funcție de acestea etc. Veți afla totul în capitolul despre validarea formularelor.
Valori implicite
Elementelor formularului le setăm în mod obișnuit valori implicite:
Adesea este util să setăm valori implicite pentru toate elementele simultan. De exemplu, când formularul servește la editarea înregistrărilor. Citim înregistrarea din baza de date și setăm valorile implicite:
Apelați setDefaults()
după definirea elementelor.
Randarea formularului
Standard, formularul se randează ca un tabel. Elementele individuale respectă regula de bază a accesibilității – toate
etichetele sunt scrise ca <label>
și legate de elementul de formular corespunzător. La clic pe etichetă,
cursorul apare automat în câmpul formularului.
Fiecărui element îi putem seta atribute HTML arbitrare. De exemplu, adăugăm un placeholder:
Există într-adevăr o mare varietate de moduri de a randa un formular, așa că acestui subiect i se dedică un capitol separat despre randare.
Maparea pe clase
Să revenim la procesarea datelor formularului. Metoda getValues()
ne returna datele trimise ca obiect
ArrayHash
. Deoarece este o clasă generică, ceva de genul stdClass
, ne va lipsi un anumit confort în
lucrul cu ea, cum ar fi sugestiile de proprietăți în editori sau analiza statică a codului. Acest lucru ar putea fi rezolvat
având o clasă specifică pentru fiecare formular, ale cărei proprietăți reprezintă elementele individuale. De ex.:
Alternativ, puteți utiliza constructorul:
Proprietățile clasei de date pot fi, de asemenea, enumuri și vor fi mapate automat.
Cum să spunem Nette să ne returneze datele ca obiecte ale acestei clase? Mai ușor decât credeți. Este suficient să specificați numele clasei sau obiectul de hidratat ca parametru:
Ca parametru se poate specifica și 'array'
, iar datele vor fi returnate ca array.
Dacă formularele formează o structură multinivel compusă din containere, creați o clasă separată pentru fiecare:
Maparea va recunoaște apoi din tipul proprietății $person
că trebuie să mapeze containerul la clasa
PersonFormData
. Dacă proprietatea ar conține un array de containere, specificați tipul array
și
transmiteți clasa pentru mapare direct containerului:
Puteți genera schița clasei de date a formularului folosind metoda
Nette\Forms\Blueprint::dataClass($form)
, care o va afișa în pagina browserului. Apoi, este suficient să
selectați codul cu un clic și să îl copiați în proiect.
Mai multe butoane
Dacă formularul are mai mult de un buton, de obicei trebuie să distingem care dintre ele a fost apăsat. Această informație
ne este returnată de metoda isSubmittedBy()
a butonului:
Nu omiteți interogarea $form->isSuccess()
, aceasta verifică validitatea datelor.
Când formularul este trimis cu tasta Enter, se consideră ca și cum ar fi fost trimis cu primul buton.
Protecția împotriva vulnerabilităților
Nette Framework acordă o mare importanță securității și, prin urmare, are grijă deosebită de securizarea formularelor.
Pe lângă protejarea formularelor împotriva atacurilor Cross Site Scripting (XSS) și Cross-Site Request Forgery (CSRF), realizează o mulțime de mici măsuri de securitate la care nu mai trebuie să vă gândiți.
De exemplu, filtrează toate caracterele de control din intrări și verifică validitatea codificării UTF-8, astfel încât datele din formular vor fi întotdeauna curate. Pentru casetele de selecție și listele radio, verifică dacă elementele selectate au fost într-adevăr dintre cele oferite și nu a avut loc o falsificare. Am menționat deja că pentru intrările de text de o singură linie elimină caracterele de sfârșit de linie pe care un atacator le-ar fi putut trimite. Pentru intrările multilinie, normalizează caracterele de sfârșit de linie. Și așa mai departe.
Nette rezolvă pentru dvs. riscurile de securitate despre care mulți programatori nici nu știu că există.
Atacul CSRF menționat constă în faptul că atacatorul atrage victima pe o pagină care execută discret în browserul victimei o cerere către serverul pe care victima este autentificată, iar serverul crede că cererea a fost executată de victimă din proprie inițiativă. De aceea, Nette previne trimiterea formularelor POST de pe un alt domeniu. Dacă, din anumite motive, doriți să dezactivați protecția și să permiteți trimiterea formularului de pe un alt domeniu, utilizați:
Această protecție utilizează un cookie SameSite numit _nss
. Prin urmare, creați obiectul formularului înainte
de a trimite prima ieșire, pentru a putea trimite cookie-ul.
Protecția prin cookie SameSite poate să nu fie 100% fiabilă, de aceea este recomandat să activați și protecția prin token:
Recomandăm protejarea în acest mod a formularelor din partea de administrare a site-ului, care modifică date sensibile în
aplicație. Framework-ul se apără împotriva atacului CSRF prin generarea și verificarea unui token de autorizare, care este
stocat în sesiune. Prin urmare, este necesar să aveți sesiunea deschisă înainte de afișarea formularului. În partea de
administrare a site-ului, sesiunea este de obicei deja pornită datorită autentificării utilizatorului. Altfel, porniți
sesiunea cu metoda Nette\Http\Session::start()
.
Așadar, am parcurs o introducere rapidă în formularele Nette. Încercați să consultați și directorul examples din distribuție, unde veți găsi mai multă inspirație.