Schema: Validierung von Daten
Eine praktische Bibliothek zur Validierung und Normalisierung von Datenstrukturen anhand eines vorgegebenen Schemas mit einer intelligenten und leicht verständlichen API.
Installation:
Grundlegende Verwendung
In der Variablen $schema
haben wir ein Validierungsschema (was genau das bedeutet und wie man es erstellt, wird
später erklärt) und in der Variablen $data
haben wir eine Datenstruktur, die wir validieren und normalisieren
wollen. Dies können z. B. Daten sein, die vom Benutzer über eine API, eine Konfigurationsdatei usw. gesendet werden.
Die Aufgabe wird von der Klasse Nette\Schema\Processor übernommen, die die Eingabe verarbeitet und entweder normalisierte Daten zurückgibt oder im Fehlerfall eine Nette\Schema\ValidationException Exception wirft.
Die Methode $e->getMessages()
liefert ein Array mit allen Nachrichtenstrings und
$e->getMessageObjects()
liefert alle Nachrichten als „Nette\Schema\Message“-Objekte:https://api.nette.org/…Message.html zurück.
Schema definieren
Und nun erstellen wir ein Schema. Die Klasse Nette\Schema\Expect wird dazu verwendet, um es zu definieren,
d.h. wir definieren Erwartungen, wie die Daten aussehen sollen. Sagen wir, dass die Eingabedaten eine Struktur (z. B. ein Array)
sein müssen, die Elemente processRefund
vom Typ bool und refundAmount
vom Typ int enthält.
Wir glauben, dass die Schemadefinition klar aussieht, auch wenn Sie sie zum ersten Mal sehen.
Lassen Sie uns die folgenden Daten zur Validierung senden:
Die Ausgabe, d. h. der Wert $normalized
, ist das Objekt stdClass
. Wenn wir wollen, dass die Ausgabe
ein Array ist, fügen wir einen Cast zu schema Expect::structure([...])->castTo('array')
.
Alle Elemente der Struktur sind optional und haben einen Standardwert null
. Beispiel:
Die Tatsache, dass der Standardwert null
ist, bedeutet nicht, dass er in den Eingabedaten
'processRefund' => null
akzeptiert würde. Nein, die Eingabe muss boolesch sein, d. h. nur true
oder
false
. Wir müssten null
über Expect::bool()->nullable()
ausdrücklich zulassen.
Ein Element kann mit Expect::bool()->required()
obligatorisch gemacht werden. Wir ändern den Standardwert auf
false
mit Expect::bool()->default(false)
oder kurz mit Expect::bool(false)
.
Und was, wenn wir neben Booleschen Werten auch 1
and 0
akzeptieren wollen? Dann listen wir die
zulässigen Werte auf, die wir ebenfalls zu booleschen Werten normalisieren werden:
Jetzt kennen Sie die Grundlagen, wie das Schema definiert ist und wie sich die einzelnen Elemente der Struktur verhalten. Wir werden nun zeigen, was alle anderen Elemente bei der Definition eines Schemas verwendet werden können.
Datentypen: type()
Alle Standard-PHP-Datentypen können im Schema aufgeführt werden:
Und dann alle Typen , die von den Validatoren über
Expect::type('scalar')
oder abgekürzt Expect::scalar()
unterstützt werden. Auch Klassen- oder Schnittstellennamen
werden akzeptiert, z.B. Expect::type('AddressEntity')
.
Sie können auch die Union-Notation verwenden:
Der Standardwert ist immer null
, außer bei array
und list
, wo es sich um ein leeres
Array handelt. (Eine Liste ist ein Array, das in aufsteigender Reihenfolge der numerischen Schlüssel von Null an indiziert ist,
also ein nicht-assoziatives Array).
Array von Werten: arrayOf() listOf()
Das Array ist eine zu allgemeine Struktur, es ist sinnvoller, genau anzugeben, welche Elemente es enthalten kann. Zum Beispiel, ein Array, dessen Elemente nur Strings sein können:
Der zweite Parameter kann zur Angabe von Schlüsseln verwendet werden (seit Version 1.2):
Die Liste ist ein indiziertes Array:
Der Parameter kann auch ein Schema sein, so dass wir schreiben können:
Der Standardwert ist ein leeres Array. Wenn Sie einen Standardwert angeben, wird dieser mit den übergebenen Daten
zusammengeführt. Dies kann mit mergeDefaults(false)
deaktiviert werden (seit Version 1.1).
Aufzählung: anyOf()
anyOf()
ist eine Menge von Werten oder Schemata, die ein Wert sein kann. So schreiben Sie ein Array von Elementen,
die entweder 'a'
, true
oder null
sein können:
Die Aufzählungselemente können auch Schemata sein:
Die Methode anyOf()
akzeptiert Varianten als einzelne Parameter, nicht als Array. Um ihr ein Array von Werten zu
übergeben, verwenden Sie den Entpackungsoperator anyOf(...$variants)
.
Der Standardwert ist null
. Verwenden Sie die Methode firstIsDefault()
, um das erste Element zum
Standardwert zu machen:
Strukturen
Strukturen sind Objekte mit definierten Schlüsseln. Jedes dieser Schlüssel ⇒ Wert-Paare wird als „Eigenschaft“ bezeichnet:
Strukturen akzeptieren Arrays und Objekte und geben Objekte zurück stdClass
.
Standardmäßig sind alle Eigenschaften optional und haben einen Standardwert von null
. Obligatorische
Eigenschaften können Sie mit required()
definieren:
Wenn Sie keine Eigenschaften mit nur einem Standardwert ausgeben wollen, verwenden Sie skipDefaults()
:
Obwohl null
der Standardwert der Eigenschaft optional
ist, ist er in den Eingabedaten nicht erlaubt
(der Wert muss ein String sein). Eigenschaften, die null
akzeptieren, werden mit nullable()
definiert:
Das Array mit allen Struktureigenschaften wird von der Methode getShape()
zurückgegeben.
Standardmäßig können keine zusätzlichen Elemente in den Eingabedaten enthalten sein:
Das können wir mit otherItems()
ändern. Als Parameter wird das Schema für jedes zusätzliche Element
angegeben:
Sie können eine neue Struktur erstellen, indem Sie mit extend()
von einer anderen ableiten:
Array
Ein Array mit definierten Schlüsseln. Es gelten die gleichen Regeln wie für Strukturen.
Sie können auch ein indiziertes Array, ein sogenanntes Tupel, definieren:
Verwerfungen
Sie können eine Eigenschaft mit der deprecated([string $message])
Methode. Verwerfungshinweise werden von
$processor->getWarnings()
zurückgegeben:
Bereiche: min() max()
Verwenden Sie min()
und max()
, um die Anzahl der Elemente für Arrays zu begrenzen:
Bei Zeichenketten begrenzen Sie deren Länge:
Bei Zahlen begrenzen Sie ihren Wert:
Es ist natürlich möglich, nur min()
oder nur max()
zu nennen:
Reguläre Ausdrücke: pattern()
Mit pattern()
können Sie einen regulären Ausdruck angeben, mit dem die gesamte Eingabezeichenkette
übereinstimmen muss (d.h. als ob sie in Zeichen eingeschlossen wäre ^
a $
):
Benutzerdefinierte Assertions: assert()
Sie können weitere Einschränkungen mit assert(callable $fn)
hinzufügen.
Oder
Sie können Ihre eigene Beschreibung für jede Assertion hinzufügen. Sie wird Teil der Fehlermeldung sein.
Die Methode kann wiederholt aufgerufen werden, um mehrere Beschränkungen hinzuzufügen. Sie kann mit Aufrufen von
transform()
und castTo()
vermischt werden.
Umwandlung: transform()
Erfolgreich überprüfte Daten können mit einer benutzerdefinierten Funktion geändert werden:
Die Methode kann wiederholt aufgerufen werden, um mehrere Transformationen hinzuzufügen. Sie kann mit Aufrufen von
assert()
und castTo()
vermischt werden. Die Operationen werden in der Reihenfolge ausgeführt, in der
sie deklariert sind:
Die Methode transform()
kann den Wert gleichzeitig transformieren und validieren. Dies ist oft einfacher und
weniger redundant als die Verkettung von transform()
und assert()
. Zu diesem Zweck erhält die Funktion
ein Context-Objekt mit einer addError()
-Methode, die dazu verwendet werden kann, Informationen über Validierungsprobleme hinzuzufügen:
Gießen: castTo()
Erfolgreich überprüfte Daten können gecastet werden:
Zusätzlich zu den nativen PHP-Typen können Sie auch auf Klassen casten. Es wird unterschieden, ob es sich um eine einfache Klasse ohne Konstruktor oder um eine Klasse mit Konstruktor handelt. Wenn die Klasse keinen Konstruktor hat, wird eine Instanz der Klasse erstellt und alle Elemente der Struktur werden in ihre Eigenschaften geschrieben:
Wenn die Klasse einen Konstruktor hat, werden die Elemente der Struktur als benannte Parameter an den Konstruktor übergeben:
Casting in Verbindung mit einem skalaren Parameter erzeugt ein Objekt und übergibt den Wert als einzigen Parameter an den Konstruktor:
Normalisierung: before()
Vor der eigentlichen Validierung können die Daten mit der Methode before()
normalisiert werden. Als Beispiel
nehmen wir ein Element an, das ein Array von Strings sein muss (z.B. ['a', 'b', 'c']
), aber eine Eingabe in Form
einer Zeichenkette erhält a b c
:
Zuordnung zu Objekten: from()
Sie können aus der Klasse ein Strukturschema erzeugen. Beispiel:
Anonyme Klassen werden ebenfalls unterstützt:
Da die aus der Klassendefinition gewonnenen Informationen möglicherweise nicht ausreichen, können Sie mit dem zweiten Parameter ein benutzerdefiniertes Schema für die Elemente hinzufügen: