Garder les entités de doctrine honnêtes avec les DTO et ObjectMapper

DEV - 25/06
Publié à l'origine sur https://symfonycasts.com/blog/honest-entities Vos entités Doctrine sont...

Publié initialement sur https://symfonycasts.com/blog/honest-entities

Vos entités de Doctrine vous mentent !

Pendant des années, la manière standard de construire des entités Doctrine dans Symfony ressemblait à ceci (et c'est toujours ce que MakerBundle génère aujourd'hui) :

#[ORM\Entity] class ConferenceTalk { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[Assert\NotBlank] #[ORM\Column(length: 255)] private ?string $title = null; #[ORM\Column(type : Types :: TEXT, nullable : true)] private ?string $abstract = null; public function getId() : ?int { return $this->id; } public function getTitle() : ?string { return $this->title; } public function setTitle(?string $title): static { $this->title = $title; renvoie $this ; } fonction publique getAbstract() : ?string { return $this->abstract; } fonction publique setAbstract(?string $abstract): static { $this->abstract = $abstract; renvoie $this ; } }
Entrer en mode plein écran Quitter le mode plein écran

À première vue, cela semble tout à fait raisonnable.

Letitrele champ est obligatoire. Nous le savons parce qu'il a unPas videcontrainte et la colonne de la base de données n'est pas nullable.

Mais regardez de plus près.

privé ?string $titre = null ; fonction publique setTitle(?string $title) : fonction publique statique getTitle() : ?string
Entrer en mode plein écran Quitter le mode plein écran

Selon le système de typage PHP, le titre est facultatif. En fait, l'API publique de cette classe nous permet explicitement de la définir surnul.

Cela signifie que ceci est parfaitement valable :

$talk = nouveau ConferenceTalk();
Entrer en mode plein écran Quitter le mode plein écran

Et c'est aussi ça :

$talk = nouveau ConferenceTalk(); $talk->setTitle(null);
Entrer en mode plein écran Quitter le mode plein écran

Les deux objets représentent un discours de conférence qui ne pourra jamais être conservé avec succès.

Finalement, Doctrine détecte le problème :

$talk = nouveau ConferenceTalk(); $entityManager->persist($talk); $entityManager->flush(); // boum !
Entrer en mode plein écran Quitter le mode plein écran

SQLSTATE[23000] : violation de contrainte d'intégrité : 1048 La colonne « titre » ne peut pas être nulle

La base de données sait qu'une conférence doit avoir un titre.

Notre code PHP ne le fait pas.

Alors pourquoi construisons-nous des entités de cette façon ?

Historiquement, ce modèle a été optimisé pour plus de simplicité.

Un seul objet pourrait être utilisé partout :

  • Rendre un formulaire
  • Recevoir les données soumises
  • Valider ces données
  • Conservez-le dans la base de données

Pour les débutants, c'est fantastique. Il y a très peu de cérémonie, très peu de passe-partout et très peu de choses à apprendre avant de pouvoir construire des écrans CRUD fonctionnels.

Le compromis est que les entité...
[Courte citation de 8% de l'article original]

Loading...