dataclass vous permet de changer rapidement votre array
simple en classe PHP à indication de type avec dénormalisation automatique des objets et collections intégrés, ce qui nécessite normalement beaucoup de travail si vous utilisez des normaliseurs et des dénormaliseurs. La bibliothèque est inspirée du module pydantic Python. Il utilise la puissance d'indication de type disponible depuis PHP 7.4.
L'objectif principal de ce package est de fournir un moyen rapide d'avoir des classes strictement typées pour une utilisation ultérieure, par exemple pour mapper la charge utile de la requête à une classe strictement typée afin que vous puissiez l'utiliser à la place d'un tableau qui peut ou non correspondre à vos besoins. Cela ne remplacera pas la validation de vos données, mais vous assurera que la charge utile JSON reçue par fx correspond aux types que vos opérations backend s'attendent à recevoir. C'est quelque chose comme l'interface pydantic BaseModel
ou TypeScript mentionné ci-dessus.
Tout ce dont vous avez besoin est de créer une ou deux classes :
declare (strict_types= 1 );
class MyEmbededClass
{
public float $ number ;
}
class MyClass
{
public int $ number ;
public ? string $ optionalText = null ;
public MyEmbededClass $ embeded ;
}
À l'étape suivante, transmettez le nom de la classe principale et les données reçues, par exemple du JSON reçu à la méthode transform
:
$ data = ' {
"number": 1,
"embeded": {
"number": 1.23
}
} ' ;
$ object = transform (MyClass::class, json_decode ( $ data , true ));
Pour mapper rapidement les données reçues à dataclass entièrement fonctionnelle :
var_dump ( $ object )
object (MyClass) {
[ " number " ]=> int( 1 )
[ " optionalText " ]=> NULL
[ " embeded " ]=>
object(MyEmbededClass) {
[ " number " ]=>
float( 1.23 )
}
}
Vous n'avez pas à vous soucier de transmettre null
depuis json_decode
, cela lancera TransformException
pour le champ root
s'il est détecté.
Vous n'avez pas à vous soucier des champs manquants et des types invalides, car la bibliothèque détecte toutes les exigences liées au type et renvoie TransformException
avec des erreurs (prêtes à être servies comme réponse) pointant vers des champs exacts avec un message de raison simple, par exemple :
echo json_encode ( $ transformException , JSON_PRETTY_PRINT )
{
"errors" : [
{
"field" : " optionalText " ,
"reason" : " Field must have value "
},
{
"field" : " embeded " ,
"reason" : " Field must have value "
}
]
}
Vous pouvez également utiliser la méthode Transform::to
qui est en fait appelée par la fonction d'assistance transform
. La fonction d'assistance utilisera toujours les paramètres optimaux pour les objets Transform
(dès qu'ils apparaissent).
$ data = ' {
"number": 1,
"embeded": {
"number": 1.23
}
} ' ;
$ transformer = new Transform ();
$ object = $ transformer -> to (MyClass::class, json_decode ( $ data , true ));
Si vous devez utiliser un constructeur avec des arguments de type, vous pouvez le faire, mais de manière limitée. La bibliothèque prend uniquement en charge le remplissage des arguments du constructeur avec les valeurs de la charge utile. Cela signifie que le constructeur doit utiliser les mêmes types et noms de variables que les propriétés de classe. Par exemple:
class MyClass
{
public float $ number ;
public ? int $ numberTwo = null ;
public function __construct ( float $ number )
{
$ this -> number = $ number ;
}
}
L'utilisation d'un nom ou d'un type différent pour l'argument du constructeur ne fonctionnera pas. L'objectif est d'aider le développeur à remplir les propriétés.
Tout constructeur contenant un autre paramètre que les propriétés lancera UnsupportedException
. Les paramètres doivent avoir le même type que les propriétés. L'ordre n'a aucune importance. Si cela est nécessaire, seul un sous-ensemble de propriétés peut exister dans le constructeur.
Veuillez consulter le répertoire docs/ pour plus d'exemples.
Aussi simple que
composer install rutek/ dataclass
Attention : soyez conscient de l'utilisation des astuces de type array
. Ils ne peuvent pas être utilisés (lanceront UnsupportedException
s'ils sont détectés) car PHP ne permet pas de taper des éléments d'un tableau. Veuillez consulter la section Collections ci-dessous pour plus d'informations.
Les quatre scalaires PHP sont pris en charge.
La nullité des indications de type est prise en charge. Vous pouvez utiliser en toute sécurité par exemple ?string
pour accepter à la fois string
et null
. Veuillez noter que l'utilisation uniquement ?string $field
ne signifie pas que le tableau transformé ne peut pas contenir ce champ. Cela signifie seulement que cette valeur accepte null
.
Si vous devez accepter la transformation de données qui ne contiennent pas certains champs, vous pouvez utiliser les valeurs par défaut, par exemple : ?string $field = null
. La bibliothèque dataclass détectera que cette propriété n'existe pas dans la charge utile et utilisera à la place la valeur par défaut.
PHP ne prend pas en charge les champs array
indication de type si vous devez intégrer une collection d'objets ou de scalaires, vous devez utiliser la classe Collection
. Vous devez l'étendre avec un constructeur avec une déconstruction d'arguments typés, par exemple :
class Tags extends Collection
{
public function __construct ( string ... $ names )
{
$ this -> items = $ names ;
}
}
Les tableaux à indication de type comme string[]
ont été rejetés dans la RFC, donc ce comportement ne changera probablement pas de sitôt.
La bibliothèque vérifiera si les valeurs fournies correspondent aux indications de type du constructeur.
Il n'est pas possible de vérifier les éléments minimum et maximum, mais une telle fonctionnalité pourrait être disponible dans les prochaines versions.
Veuillez noter que vous pouvez également utiliser Collection comme classe de base que vous souhaitez transformer, par exemple :
$ tags = transform (Tags::class, [ ' tag1 ' , ' tag2 ' ]);
TransformException
- les données ne correspondent pas à votre schéma Il s’agit d’une exception de base à laquelle vous pouvez vous attendre. Chaque fois que vos données (charge utile) transmises à la fonction transform(string $class, $data)
ou Transform::to
ne correspondront pas à vos classes à indication de type, vous recevrez TransformException
avec la méthode getErrors(): FieldError[]
qui décrit ce qui est réellement arrivé.
Chaque FieldError
contient à la fois un field
décrivant le champ qui a échoué à la vérification de type et reason
décrivant en termes simples pourquoi il a été rejeté. S'il y a des objets imbriqués, vous pouvez vous attendre à recevoir des valeurs field
telles que parentProperty.childrenProperty
(niveaux séparés par un point).
La classe prend en charge la sérialisation JSON et renverra toujours quelque chose comme :
{
"errors" : [
{
"field" : " optionalText " ,
"reason" : " Field must have value "
},
{
"field" : " embeded " ,
"reason" : " Field must have value "
}
]
}
Veuillez noter que le champ code
pourrait être ajouté à l'avenir.
UnsupportedException
- uniquement si vos indications de type ne sont pas prises en charge La bibliothèque ne couvre pas tous les scénarios car vous pouvez définir des astuces de type qui n'auraient pas de contexte strict. Par exemple, si vous utilisez une propriété object
, il ne sera pas possible de la valider car n'importe quel objet correspondra à votre schéma. Dans de tels cas, vous pouvez vous attendre à UnsupportedException
.
Les types d'union PHP 8.0 et les types d'intersection PHP 8.1 ne sont pas pris en charge pour le moment.
Les énumérations natives PHP 8.1 ne sont pas prises en charge pour le moment.
Tous les champs indiqués doivent être publics pour le moment. La mise en œuvre d'une telle fonctionnalité est discutable car vous devrez créer des getters pour de telles propriétés, ce qui constitue une surcharge indésirable. La bibliothèque est destinée à créer la possibilité de définir des schémas internes pour les données reçues des systèmes distants (API, files d'attente/messages de bus, navigateurs).
Toutes les vérifications de réflexion sont effectuées à chaque fois que la fonction transform
ou Transform::to
est appelée. Vous pouvez bientôt vous attendre à une fonctionnalité de mise en cache pour de meilleures performances.
N'oubliez pas que l'objectif de ce package n'est pas de valider entièrement les données que vous recevez, mais de créer des classes simples qui rendent vos charges utiles entièrement indiquées, même lorsqu'elles ont une structure compliquée. Vous n'aurez pas besoin d'encoder vos classes en JSON avec des champs class
, car vos indications de type indiqueront à votre code quel objet ou tableau doit être créé à la place de certaines valeurs intégrées.
Si vous créez une API et que vous avez besoin d'une validation de schéma OpenAPI de niveau entreprise, vous devez vérifier hkarlstrom/openapi-validation-middleware et vous pourrez ensuite mapper la charge utile reçue aux classes à indication de type à l'aide de cette bibliothèque ! :)