Σχήμα: Επικύρωση δεδομένων
Μια πρακτική βιβλιοθήκη για την επικύρωση και την κανονικοποίηση δομών δεδομένων έναντι ενός δεδομένου σχήματος με ένα έξυπνο και κατανοητό API.
Εγκατάσταση:
Βασική χρήση
Στη μεταβλητή $schema
έχουμε ένα σχήμα επικύρωσης (τι ακριβώς
σημαίνει αυτό και πώς να το δημιουργήσουμε θα πούμε αργότερα) και στη
μεταβλητή $data
έχουμε μια δομή δεδομένων που θέλουμε να
επικυρώσουμε και να κανονικοποιήσουμε. Αυτό μπορεί να είναι, για
παράδειγμα, δεδομένα που αποστέλλονται από τον χρήστη μέσω ενός API,
ενός αρχείου ρυθμίσεων κ.λπ.
Το έργο αναλαμβάνει η κλάση Nette\Schema\Processor, η οποία επεξεργάζεται την είσοδο και είτε επιστρέφει κανονικοποιημένα δεδομένα είτε πετάει μια εξαίρεση Nette\Schema\ValidationException σε περίπτωση σφάλματος.
Η μέθοδος $e->getMessages()
επιστρέφει πίνακα όλων των
συμβολοσειρών μηνυμάτων και η $e->getMessageObjects()
επιστρέφει όλα τα
μηνύματα ως αντικείμενα Nette\Schema\Message.
Ορισμός σχήματος
Και τώρα ας δημιουργήσουμε ένα σχήμα. Η κλάση Nette\Schema\Expect χρησιμοποιείται για
τον ορισμό του, ουσιαστικά ορίζουμε τις προσδοκίες για το πώς θα πρέπει
να μοιάζουν τα δεδομένα. Ας πούμε ότι τα δεδομένα εισόδου πρέπει να
είναι μια δομή (π.χ. ένας πίνακας) που περιέχει στοιχεία processRefund
τύπου bool και refundAmount
τύπου int.
Πιστεύουμε ότι ο ορισμός του σχήματος φαίνεται σαφής, ακόμη και αν τον βλέπετε για πρώτη φορά.
Ας στείλουμε τα ακόλουθα δεδομένα για επικύρωση:
Η έξοδος, δηλαδή η τιμή $normalized
, είναι το αντικείμενο
stdClass
. Εάν θέλουμε η έξοδος να είναι ένας πίνακας, προσθέτουμε
ένα cast στο schema Expect::structure([...])->castTo('array')
.
Όλα τα στοιχεία της δομής είναι προαιρετικά και έχουν προεπιλεγμένη
τιμή null
. Παράδειγμα:
Το γεγονός ότι η προεπιλεγμένη τιμή είναι null
δεν σημαίνει ότι
θα γινόταν δεκτή στα δεδομένα εισόδου 'processRefund' => null
. Όχι, η
είσοδος πρέπει να είναι boolean, δηλαδή μόνο true
ή false
. Θα
πρέπει να επιτρέψουμε ρητά το null
μέσω του
Expect::bool()->nullable()
.
Ένα στοιχείο μπορεί να καταστεί υποχρεωτικό χρησιμοποιώντας το
Expect::bool()->required()
. Αλλάζουμε την προεπιλεγμένη τιμή σε false
χρησιμοποιώντας το Expect::bool()->default(false)
ή σύντομα
χρησιμοποιώντας το Expect::bool(false)
.
Και τι θα γινόταν αν θέλαμε να δεχτούμε το 1
and 0
εκτός
από booleans; Τότε απαριθμούμε τις επιτρεπόμενες τιμές, τις οποίες επίσης
θα κανονικοποιήσουμε σε boolean:
Τώρα γνωρίζετε τα βασικά για το πώς ορίζεται το σχήμα και πώς συμπεριφέρονται τα επιμέρους στοιχεία της δομής. Τώρα θα δείξουμε ποια είναι όλα τα άλλα στοιχεία που μπορούν να χρησιμοποιηθούν στον ορισμό ενός σχήματος.
Τύποι δεδομένων: type()
Όλοι οι τυποποιημένοι τύποι δεδομένων PHP μπορούν να αναφερθούν στο σχήμα:
Και στη συνέχεια όλοι οι τύποι που υποστηρίζονται από τους
επικυρωτές μέσω του Expect::type('scalar')
ή της συντομογραφίας
Expect::scalar()
. Επίσης, γίνονται δεκτά ονόματα κλάσεων ή διεπαφών, π.χ.
Expect::type('AddressEntity')
.
Μπορείτε επίσης να χρησιμοποιήσετε τον συμβολισμό της ένωσης:
Η προεπιλεγμένη τιμή είναι πάντα null
εκτός από τις περιπτώσεις
array
και list
, όπου είναι ένας άδειος πίνακας. (Μια λίστα
είναι ένας πίνακας με ευρετηρίαση σε αύξουσα σειρά αριθμητικών
κλειδιών από το μηδέν, δηλαδή ένας μη συσχετιστικός πίνακας).
Πίνακας τιμών: arrayOf() listOf()
Ο πίνακας είναι πολύ γενική δομή, είναι πιο χρήσιμο να καθορίσετε ακριβώς ποια στοιχεία μπορεί να περιέχει. Για παράδειγμα, ένας πίνακας του οποίου τα στοιχεία μπορούν να είναι μόνο συμβολοσειρές:
Η δεύτερη παράμετρος μπορεί να χρησιμοποιηθεί για τον προσδιορισμό των κλειδιών (από την έκδοση 1.2):
Η λίστα είναι ένας δεικτοδοτημένος πίνακας:
Η παράμετρος μπορεί επίσης να είναι ένα σχήμα, οπότε μπορούμε να γράψουμε:
Η προεπιλεγμένη τιμή είναι ένας άδειος πίνακας. Εάν καθορίσετε την
προεπιλεγμένη τιμή, θα συγχωνευτεί με τα δεδομένα που έχουν περάσει.
Αυτό μπορεί να απενεργοποιηθεί χρησιμοποιώντας το mergeDefaults(false)
(από την έκδοση 1.1).
Απαρίθμηση: anyOf()
anyOf()
είναι ένα σύνολο τιμών ή σχημάτων που μπορεί να είναι μια
τιμή. Εδώ είναι πώς να γράψετε έναν πίνακα στοιχείων που μπορεί να
είναι είτε 'a'
, true
, είτε null
:
Τα στοιχεία της απαρίθμησης μπορούν επίσης να είναι σχήματα:
Η μέθοδος anyOf()
δέχεται παραλλαγές ως μεμονωμένες παραμέτρους,
όχι ως πίνακα. Για να της παραδώσετε έναν πίνακα τιμών, χρησιμοποιήστε
τον τελεστή αποσυμπίεσης anyOf(...$variants)
.
Η προεπιλεγμένη τιμή είναι null
. Χρησιμοποιήστε τη μέθοδο
firstIsDefault()
για να κάνετε το πρώτο στοιχείο προεπιλεγμένο:
Δομές
Οι δομές είναι αντικείμενα με καθορισμένα κλειδιά. Κάθε ένα από αυτά τα ζεύγη κλειδί ⇒ τιμή αναφέρεται ως „ιδιότητα“:
Οι δομές δέχονται πίνακες και αντικείμενα και επιστρέφουν
αντικείμενα stdClass
.
Από προεπιλογή, όλες οι ιδιότητες είναι προαιρετικές και έχουν
προεπιλεγμένη τιμή null
. Μπορείτε να ορίσετε υποχρεωτικές
ιδιότητες χρησιμοποιώντας το required()
:
Εάν δεν θέλετε να εξάγετε ιδιότητες με μόνο μια προεπιλεγμένη τιμή,
χρησιμοποιήστε το skipDefaults()
:
Παρόλο που το null
είναι η προεπιλεγμένη τιμή της ιδιότητας
optional
, δεν επιτρέπεται στα δεδομένα εισόδου (η τιμή πρέπει να
είναι συμβολοσειρά). Οι ιδιότητες που δέχονται το null
ορίζονται
χρησιμοποιώντας το nullable()
:
Ο πίνακας όλων των ιδιοτήτων της δομής επιστρέφεται από τη μέθοδο
getShape()
.
Από προεπιλογή, δεν μπορούν να υπάρχουν επιπλέον στοιχεία στα δεδομένα εισόδου:
Το οποίο μπορούμε να αλλάξουμε με το otherItems()
. Ως παράμετρος, θα
καθορίσουμε το σχήμα για κάθε επιπλέον στοιχείο:
Μπορείτε να δημιουργήσετε μια νέα δομή παράγοντας από μια άλλη
χρησιμοποιώντας το extend()
:
Συστοιχία
Ένας πίνακας με καθορισμένα κλειδιά. Ισχύουν οι ίδιοι κανόνες όπως και για τις δομές.
Μπορείτε επίσης να ορίσετε έναν δεικτοδοτούμενο πίνακα, γνωστό ως πλειάδα:
Αποσβέσεις
Μπορείτε να καταργήσετε μια ιδιότητα χρησιμοποιώντας την εντολή
deprecated([string $message])
μέθοδο. Οι ειδοποιήσεις κατάργησης
επιστρέφονται από το $processor->getWarnings()
:
Εύρος: min() max()
Χρησιμοποιήστε τα min()
και max()
για να περιορίσετε τον
αριθμό των στοιχείων των πινάκων:
Για συμβολοσειρές, περιορίστε το μήκος τους:
Για αριθμούς, περιορίστε την τιμή τους:
Φυσικά, είναι δυνατόν να αναφέρετε μόνο το min()
ή μόνο το
max()
:
Κανονικές εκφράσεις: pattern()
Χρησιμοποιώντας το pattern()
, μπορείτε να καθορίσετε μια κανονική
έκφραση με την οποία πρέπει να ταιριάζει όλη η συμβολοσειρά
εισόδου (δηλαδή σαν να ήταν τυλιγμένη σε χαρακτήρες ^
a
$
):
assert()
Μπορείτε να προσθέσετε οποιουσδήποτε άλλους περιορισμούς
χρησιμοποιώντας το assert(callable $fn)
.
Ή
Μπορείτε να προσθέσετε τη δική σας περιγραφή για κάθε ισχυρισμό. Θα είναι μέρος του μηνύματος σφάλματος.
Η μέθοδος μπορεί να κληθεί επανειλημμένα για την προσθήκη πολλαπλών
περιορισμών. Μπορεί να αναμειχθεί με κλήσεις στις transform()
και
castTo()
.
Μετασχηματισμός: transform()
Τα επιτυχώς επικυρωμένα δεδομένα μπορούν να τροποποιηθούν χρησιμοποιώντας μια προσαρμοσμένη συνάρτηση:
Η μέθοδος μπορεί να κληθεί επανειλημμένα για την προσθήκη πολλαπλών
μετασχηματισμών. Μπορεί να αναμειχθεί με κλήσεις στις assert()
και
castTo()
. Οι λειτουργίες θα εκτελούνται με τη σειρά με την οποία
δηλώνονται:
Η μέθοδος transform()
μπορεί να μετασχηματίσει και να επικυρώσει
την τιμή ταυτόχρονα. Αυτό είναι συχνά απλούστερο και λιγότερο περιττό
από την αλυσιδωτή εκτέλεση των transform()
και assert()
. Για το
σκοπό αυτό, η συνάρτηση λαμβάνει ένα αντικείμενο Context με μια μέθοδο addError()
, η
οποία μπορεί να χρησιμοποιηθεί για την προσθήκη πληροφοριών σχετικά
με τα θέματα επικύρωσης:
Casting: castTo()
Τα επιτυχώς επικυρωμένα δεδομένα μπορούν να μεταφερθούν:
Εκτός από τους εγγενείς τύπους της PHP, μπορείτε επίσης να κάνετε cast σε κλάσεις. Διακρίνεται αν πρόκειται για μια απλή κλάση χωρίς κατασκευαστή ή για μια κλάση με κατασκευαστή. Αν η κλάση δεν έχει κατασκευαστή, δημιουργείται μια παρουσία της και όλα τα στοιχεία της δομής γράφονται στις ιδιότητές της:
Εάν η κλάση διαθέτει κατασκευαστή, τα στοιχεία της δομής μεταβιβάζονται ως ονομαστικές παράμετροι στον κατασκευαστή:
Η χύτευση σε συνδυασμό με μια κλιμακωτή παράμετρο δημιουργεί ένα αντικείμενο και μεταβιβάζει την τιμή ως μοναδική παράμετρο στον κατασκευαστή:
Κανονικοποίηση: before()
Πριν από την ίδια την επικύρωση, τα δεδομένα μπορούν να
κανονικοποιηθούν χρησιμοποιώντας τη μέθοδο before()
. Ως
παράδειγμα, ας έχουμε ένα στοιχείο που πρέπει να είναι ένας πίνακας
συμβολοσειρών (π.χ. ['a', 'b', 'c']
), αλλά δέχεται είσοδο με τη μορφή
συμβολοσειράς a b c
:
Αντιστοίχιση σε αντικείμενα: from()
Μπορείτε να δημιουργήσετε σχήμα δομής από την κλάση. Παράδειγμα:
Υποστηρίζονται επίσης ανώνυμες κλάσεις:
Μπορείτε να προσθέσετε ένα προσαρμοσμένο σχήμα για τα στοιχεία με τη δεύτερη παράμετρο: