PRÉSENTATION DU COURS

Utilisez Doctrine dans votre Symfony

Créez et manipulez vos données de la base de données grâce à Doctrine

Enregister et manipuler des données

Doctrine est un système complexe et assez lourd, vos premiers contact avec lui seront certainement assez compliqués ! Mais perseverez, vous verrez que cet outil facilite beaucoup la gestion d'une base de données.

Enregistrer les données

Dans un premier temps, concentrons nous sur ce qui est probablement la chose la plus simple avec Doctrine : Enregistrer des données.

Dans un premier temps, créez un nouveau controller pour gérer la table singe que l'on vient de créer !

Vous pouvez utiliser le maker pour faire un controller, je vous laisse voir comment ça se passe dans la documentation !

Dans ce controller créez une nouvelle route, nommez la create.

Nous allons ensuite créer un nouveau singe manuellement dans ce controller.

D'abord créez une nouvelle entité (ici on va prendre Monkey comme exemple d'entité)

use App/Entity/Monkey;

/// ... code

public function new () {
    $monkey = new Monkey();
    $monkey->setNom('Alban')
        ->setSexe('M')
        ->setFamille('Babouin')
        ->setAge(18)
        ->setAlimentation('Végétarien')
        ->setEntreeAuParc(new \DateTime());

    return new Response('This is currently unavailable !');
}

Vous pouvez enchainer les méthode de cette manière avec les entités, vous pouvez aussi le faire dans votre propre code en renvoyant $this au retour d'une fonction, mais attention à ne pas en abuser !

Utilisez un dump pour voir les données que contient cet entité !

Par contre petit problème, on a pas d'enregistrement qui se fait dans la base de données !

Rien de bizzare ne vous en faites pas, définir des éléments comme ça n'enregistre pas automatiquement les modifications, on va devoir utiliser, encore une fois, comme vous pouvez vous dire en ce moment, face à cette phrase beaucoup trop longue, un service 😏.

Modifiez le controller de cette façon :

use App/Entity/Monkey;

/// ... code

public function new (EntityManagerInterface $em) {
    $monkey = new Monkey();
    $monkey->setNom('Alban')
        ->setSexe('M')
        ->setFamille('Babouin')
        ->setAge(18)
        ->setAlimentation('Végétarien')
        ->setEntreeAuParc(new \DateTime());

    $em->persist($monkey);
    $em->flush();

    return new Response(sprintf(
            'Welcome to our new resident : %s !',
            $monkey->getNom() // on récupère le nom du simple pour un retour un peu plus sympa
        ));
}

Pour enregistrer des données, modifier ou quoi que ce soit, ça se passera toujours avec les méthode persist et flush d'EntityManagerInterface.

À quoi servent-elles ?

  • persist : Enregistre l'objet pour être persisté plus tard dans la base de données
  • flush : Enregistre tous les objet en presistance dans la base de données

Et là vous allez me dire Mais pourquoi ne pas faire une seule méthode ?

Tout simplement pour la performance, imaginez enregistrer 10000 singes d'un coup en 10000 requêtes différentes... ça risque de faire péter la base ou tout simplement timeout donc pas top !

Avoir flush séparé, ça nous permet de faire ces 10000 ajouts en une seule requête à la base, donc beaucoup plus efficace !

Nous n'avons pas mis d'id normal ? Oui, Doctrine s'en occupe lui même, et génère une clée unique pour cet élément

Si vous voulez lancer des petites commandes sql sans aller voir en base vous pouvez utiliser cette commande : php bin/console doctrine:query:sql "SELECT * FROM monkey". Le plus simple reste quand même d'aller sur PHPmyAdmin

Normalement à ce niveau là, on devrait avoir un enregistrement dans notre base ! Horray !

Requêter sa base

Empiler les informations c'est cool, mais pas très utile si vous ne pouvez pas les lire / modifier / supprimer, nous allons voir dans cette question comment faire ça !

Dans un premier temps, créez un nouvelle route dans le controller nommée list.

Ici nous allons récupérer tous les singes dans la base de données, avec notre nouvel ami EntityManagerInterface.

use App/Entity/Monkey;

/// ... code

public function list (EntityManagerInterface $em) {
    $repository = $em->getRepository(Monkey::class);
    
    $monkeys = $repository->findAll();

    return new JsonResponse($monkeys); // on retourne en json par simplicité !
}

Désormais si vous allez sur ces routes, vous avez tous les enregistrement de singe dans la base de données, cool !

Mais à quoi ça correspond

Comme nous l'avons vu tout à l'heure doctrine crée un Repostiory pour notre entité, et ce repository vient avec tout un tas de fonctions déjà présentes !

Du type :

  • findAll
  • findOneBy
  • ...etc

Vous pouvez aller voir plusieurs des fonctions et leur utilisations dans la documentation symfony

Que se passe t'il lorsque l'on trouve pas de résultat ?

Dans un premier temps, vous pouvez voir que rien n'existe en checkant pour une réponse null du findAll (ou tout autre fonction) ou un tableau vide en fonction des cas.

Pour ce qui est de créer l'erreur 404, Symfony à une petite méthode sympa appelée createNotFoundException

Vous pourriez donc gérer le cas de cette façon là :

use App/Entity/Monkey;

/// ... code

public function list (EntityManagerInterface $em) {
    $repository = $em->getRepository(Monkey::class);
    
    $monkeys = $repository->findAll();

    if(!$monkeys) {
        throw $this->createNotFoundException('Sorry, no monkey came for the banana this time');
    }

    return $this->render('votrenomdetemplate.html.twig', ['monkeys' => $monkeys]); // Et maintenant c'est à vous de vous débtrouiller pour afficher ça avec twig 😉 (hésitez pas à regarder juste en dessous pour un peu d'aide)
}

Envoyer les données à twig

Pour envoyer les données à twig, envoyez simplement $monkeys dans les paramètres du thème.

Attention à bien utiliser les getters ({{monkey.gerName()}}) pour récupérer les élément de chaque monkey, sinon vous allez avoir des erreurs !

Conclusion

Vous avez désormais les bases pour requêter et créer dans votre base de données ! Vous allez un peu vous débrouiller par vous même avec le petit exercice suivant !

Envie de discuter du contenu ?

logo twitter @GarnierKristen