Modifications de données
Mise à jour et suppression de données avec Doctrine dans Symfony 7
Notions théoriques
Dans Symfony 7, pour mettre à jour ou supprimer une entité, il est recommandé d'utiliser l'injection de dépendance avec le Repository.
Voici les principales étapes :
- Injecter le Repository dans votre contrôleur.
- Utiliser le Repository pour trouver l'entité.
- Effectuer les modifications ou la suppression.
- Utiliser les méthodes du Repository pour persister les changements.
Une mise à jour
Voici comment réaliser une mise à jour de données dans la base de données :
use App\Entity\Player;
use App\Repository\PlayerRepository;
class GameController extends AbstractController
{
public function __construct(private PlayerRepository $playerRepository)
{
}
public function updatePlayer(int $id): Response
{
$player = $this->playerRepository->find($id);
if (!$player) {
throw $this->createNotFoundException('No player found for id '.$id);
}
$player->setName('New Name');
$this->playerRepository->save($player, true);
return new Response('Player updated!');
}
}
Une suppression
Voici comment réaliser une suppression de données dans la base de données :
public function deletePlayer(int $id): Response
{
$player = $this->playerRepository->find($id);
if (!$player) {
throw $this->createNotFoundException('No player found for id '.$id);
}
$this->playerRepository->remove($player, true);
return new Response('Player deleted!');
}
Exemple pratique
Ajoutons deux actions à notre GameController
pour mettre à jour et supprimer un joueur dans Symfony 7 :
use App\Entity\Player;
use App\Repository\PlayerRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class GameController extends AbstractController
{
public function __construct(private PlayerRepository $playerRepository)
{
}
#[Route('/game/update_player/{id}', name: 'update_player')]
public function updatePlayer(int $id): Response
{
$player = $this->playerRepository->find($id);
if (!$player) {
throw $this->createNotFoundException('No player found for id '.$id);
}
$player->setName('Updated Player');
$this->playerRepository->save($player, true);
return new Response('Player updated!');
}
#[Route('/game/delete_player/{id}', name: 'delete_player')]
public function deletePlayer(int $id): Response
{
$player = $this->playerRepository->find($id);
if (!$player) {
throw $this->createNotFoundException('No player found for id '.$id);
}
$this->playerRepository->remove($player, true);
return new Response('Player deleted!');
}
}
La promotion de propriété de constructeur
Pourquoi private PlayerRepository $playerRepository
dans les paramètres du constructeur ?
Voici une explication du constructeur de l'exemple pratique et une alternative plus explicite (plus classique).
Explication du constructeur de l'exemple
class GameController extends AbstractController
{
public function __construct(private PlayerRepository $playerRepository)
{
}
// ... reste du code ...
}
Dans ce constructeur :
-
Le mot-clé
private
avant le paramètre$playerRepository
est une fonctionnalité de PHP 8 appelée "promotion de propriété de constructeur" (constructor property promotion). -
Cette syntaxe combine la déclaration du paramètre du constructeur et la déclaration de la propriété de classe en une seule ligne.
-
Elle crée automatiquement une propriété privée
$playerRepository
dans la classe et lui assigne la valeur passée au constructeur. -
Le corps de la méthode est vide car toute la logique nécessaire (création de la propriété et assignation) est gérée par la promotion de propriété.
Cette syntaxe est concise mais peut être moins évidente pour les développeurs non familiers avec les dernières fonctionnalités de PHP.
Alternative plus explicite
Voici une version plus explicite et potentiellement plus facile à comprendre pour certains développeurs :
class GameController extends AbstractController
{
private PlayerRepository $playerRepository;
public function __construct(PlayerRepository $playerRepository)
{
$this->playerRepository = $playerRepository;
}
// ... reste du code ...
}
Dans cette version :
-
La propriété
$playerRepository
est explicitement déclarée dans la classe. -
Le constructeur reçoit le
PlayerRepository
comme paramètre. -
Dans le corps du constructeur, nous assignons explicitement le paramètre à la propriété de la classe.
Cette approche est plus verbeuse mais peut être plus claire pour les développeurs habitués à un style plus traditionnel de PHP ou pour ceux qui apprennent le langage.
Les deux approches sont fonctionnellement équivalentes. Le choix entre elles dépend souvent des préférences de l'équipe de développement et des conventions du projet.
La version avec promotion de propriété est plus concise et devient de plus en plus courante dans les projets PHP modernes, tandis que la version explicite peut être préférée pour sa clarté dans certains contextes, notamment pédagogiques.
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Votre défi pour aujourd'hui consiste à créer 2 nouvelles actions dans votre
GameController
pour permettre de mettre à jour et de supprimer un joueur.
- La 1ère méthode
updatePlayerTwo
doit mettre à jour le nom du joueur avec l'ID 2. - La 2ème méthode
deletePlayerThree
doit supprimer le joueur avec l'ID 3.
Une solution
Vous devez être connecté pour voir le contenu.