• 30 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 5/13/19

Utilisons la console pour créer un bundle

Log in or subscribe for free to enjoy all this course has to offer!

Dans ce chapitre, nous allons créer notre premier bundle, juste histoire d'avoir la structure de base de notre code futur. Mais nous ne le ferons pas n'importe comment : nous allons générer le bundle en utilisant une commande Symfony en console ! L'objectif est de découvrir la console utilement.

Utilisation de la console

Tout d'abord, vous devez savoir une chose : Symfony intègre des commandes disponibles non pas via le navigateur, mais via l'invite de commandes (sous Windows) ou le terminal (sous Linux). Il existe pas mal de commandes qui vont nous servir assez souvent lors du développement, apprenons donc dès maintenant à utiliser cette console !

Les outils disponibles en ligne de commande ont pour objectif de nous faciliter la vie. Ce n'est pas un obscur programme pour les geeks amoureux de la console ! Vous pourrez à partir de là générer une base de code source pour certains fichiers récurrents, vider le cache, ajouter des utilisateurs par la suite, etc. N'ayez pas peur de cette console.

Sous Windows

Lancez l'invite de commandes :Menu Démarrer > Programmes > Accessoires > Invite de commandes.

Puis placez-vous dans le répertoire où vous avez mis Symfony, en utilisant la commande Windowscd(je vous laisse adapter la commande) :

Microsoft Windows [version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Tous droits réservés.

C:\Users\winzou>cd ../../wamp/www/Symfony

C:\wamp\www\Symfony>_

On va exécuter des fichiers PHP depuis cette invite de commandes. En l'occurrence, c'est le fichierbin/console(ouvrez-le, c'est bien du PHP) que nous allons exécuter. Pour cela, il faut lancer la commande PHP avec le nom du fichier en argument :php bin/console. C'est parti :

C:\wamp\www\Symfony>php bin/console

Symfony version 3.0.0 - app/dev/debug

Usage:
  [options] command [arguments]

Options:
 -h, --help           Display this help message
 -q, --quiet          Do not output any message
 -V, --version        Display this application version
 --ansi               Force ANSI output
 --no-ansi            Disable ANSI output
 -n, --no-interaction Do not ask any interactive question
 -e, --env=ENV        The Environment name. [default: "dev"]
 --no-debug           Switches off debug mode.
 -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Et voila, vous venez d'exécuter une commande Symfony ! Celle-ci ne fait pas grand-chose, c'était juste un entraînement.

Sous Linux et Mac

Ouvrez le terminal. Placez-vous dans le répertoire où vous avez mis Symfony, probablement/var/wwwpour Linux ou/user/sitespour Mac. Le fichier que nous allons exécuter estbin/console, il faut donc lancer la commandephp bin/console. Je ne vous fais pas de capture d'écran, j'imagine que vous savez le faire !

À quoi ça sert ?

Une très bonne question, qu'il faut toujours se poser. La réponse est très simple : à nous simplifier la vie !

Depuis cette console, on pourra par exemple créer une base de données, vider le cache, ajouter ou modifier des utilisateurs (sans passer par phpMyAdmin !), etc. Mais ce qui nous intéresse dans ce chapitre, c'est la génération de code.

En effet, pour créer un bundle, un modèle ou un formulaire, le code de départ est toujours le même. C'est ce code-là que le générateur va écrire pour nous. Du temps de gagné !

Comment ça marche ?

Comment Symfony, un framework pourtant écrit en PHP, peut-il avoir des commandes en console ?

Vous devez savoir que PHP peut s'exécuter depuis le navigateur, mais également depuis la console. En fait, côté Symfony, tout est toujours écrit en PHP, il n'y a rien d'autre. Pour en être sûrs, ouvrez le fichierbin/console:

#!/usr/bin/env php
<?php

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;

set_time_limit(0);

$loader = require __DIR__.'/../app/autoload.php';

$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';

if ($debug) {
    Debug::enable();
}

$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);

Vous ne remarquez rien ? Il ressemble beaucoup au contrôleur frontalapp.php! En fait, il fait presque la même chose, il inclut les mêmes fichiers, et charge également le Kernel. Mais il définit la requête comme venant de la console, ce qui exécute du code différent par la suite. On pourra nous aussi écrire du code qui sera exécuté non pas depuis le navigateur (comme les contrôleurs habituels), mais depuis la console. Rien ne change pour le code, si ce n'est que l'affichage ne peut pas être en HTML bien évidemment.

Le fil rouge de notre cours : une plateforme d'échange

Dans ce cours, je vous propose de monter de toute pièce une plateforme d'échange. Notre site proposera de poster des annonces de missions pour développeurs, designers, etc. On pourra consulter ces annonces, les commenter, les chercher. Tous les codes que vous trouverez dans ce cours s'articuleront donc autour de ce concept de plateforme d'échange, pensez-y pour avoir une vision globale de ce qu'on construit ! 

Créons notre bundle

Tout est bundle

Rappelez-vous : dans Symfony, chaque partie de votre site est un bundle. Pour créer notre première page, il faut donc d'abord créer notre premier bundle. Rassurez-vous, créer un bundle est extrêmement simple avec le générateur. Démonstration !

Exécuter la bonne commande

Comme on vient de l'apprendre, exécutez la commandephp bin/console generate:bundle.

1. Réutilisation du bundle

Symfony vous demande si vous comptez réutiliser ce bundle, pour l'exemple nous disons oui ici, cela nous permettra d'avoir un bundle plus complet :

C:\wamp\www\Symfony>php bin/console generate:bundle


 Welcome to the Symfony bundle generator!


Are you planning on sharing this bundle across multiple applications? [no]:_

Répondez paryes .

2. Choisir le namespace

Symfony vous demande ensuite le namespace de votre bundle :

Are you planning on sharing this bundle across multiple applications? [no]: yes

Your application code must be written in bundles. This command helps
you generate them easily.

Each bundle is hosted under a namespace (like Acme/Bundle/BlogBundle).
The namespace should begin with a "vendor" name like your company name, your
project name, or your client name, followed by one or more optional category
sub-namespaces, and it should end with the bundle name itself
(which must have Bundle as a suffix).

See http://symfony.com/doc/current/cookbook/bundles/best_practices.html#index-1
for more
details on bundle naming conventions.

Use / instead of \ for the namespace delimiter to avoid any problem.

Bundle namespace:_

Vous pouvez nommer votre namespace comme bon vous semble, il faut juste qu'il se termine par le suffixe « Bundle ». Par convention, on le compose de trois parties. Nous allons nommer notre namespace « OC\PlatformBundle ». Explications :

  1. « OC » est le namespace racine : il vous représente vous ou votre entreprise. Vous pouvez mettre votre pseudo, le nom de votre site, celui de votre entreprise, etc. C'est un nom arbitraire. J'utiliserai OC pour OpenClassrooms ;

  2. « Platform » est le nom du bundle en lui-même : il définit ce que fait le bundle. Ici, nous créons une plateforme d'échange, nous l'avons donc simplement appelé « Platform » ;

  3. « Bundle » est le suffixe obligatoire.

Entrez donc dans la consoleOC/PlatformBundle, avec des slashes (ou des barres obliques en français) juste pour cette fois pour les besoins de la console, mais un namespace comprend bien des anti-slashes.

3. Choisir le nom

Symfony vous demande le nom de votre bundle :

Bundle namespace: OC/PlatformBundle

In your code, a bundle is often referenced by its name. It can be the
concatenation of all namespace parts but it's really up to you to come
up with a unique name (a good practice is to start with the vendor name).
Based on the namespace, we suggest OCPlatformBundle.

Bundle name [OCPlatformBundle]:_

Par convention, on nomme le bundle de la même manière que le namespace, sans les shashes. On a donc : OCPlatformBundle. C'est ce que Symfony vous propose par défaut (la valeur entre les crochets), appuyez donc simplement sur Entrée. Retenez ce nom : par la suite, quand on parlera du nom du bundle, cela voudra dire ce nom-là : OCPlatformBundle.

Si votre bundle ne fonctionne pas, c'est peut-être à cause du fichier composer.json ! Consultez cette page sur le GitHub de Symfony pour en savoir plus.

4. Choisir la destination

Symfony vous demande l'endroit où vous voulez que les fichiers du bundle soient générés :

Bundle name [OCPlatformBundle]:

Bundles are usually generated into the src/ directory. Unless you're
doing something custom, hit enter to keep this default!

Target Directory [src/]:_

Par convention, comme on l'a vu, on place nos bundles dans le répertoire/src. C'est ce que Symfony vous propose, appuyez donc sur Entrée.

5. Choisir le format de configuration

Symfony vous demande sous quelle forme vous voulez configurer votre bundle. Il s'agit simplement du format de la configuration, que nous ferons plus tard. Il existe plusieurs moyens comme vous pouvez le voir : YAML, XML, PHP ou Annotations.

Target Directory [src/]:

What format do you want to use for your generated configuration?

Configuration format (annotation, yml, xml, php) [xml]:_

Chacun a ses avantages et inconvénients. Nous allons utiliser le YAML (yml) ici, car il est bien adapté pour un bundle. Mais sachez que nous utiliserons les annotations pour nos futurs modèles par exemple. Entrez doncyml.

6. Le tour est joué !

Avec toutes vos réponses, Symfony est capable de générer la structure du bundle que nous voulons :

Configuration format (annotation, yml, xml, php) [xml]: yml


 Bundle generation


> Generating a sample bundle skeleton into src/OC/PlatformBundle OK!
> Checking that the bundle is autoloaded: OK
> Enabling the bundle inside C:\wamp\www\Symfony\app\AppKernel.php: OK
> Importing the bundle's routes from the C:\wamp\www\Symfony\app\config\routing.yml file: OK


 Everything is OK! Now get to work :).

C:\wamp\www\Symfony>_

Mais pourquoi n'y a-t-il plus la toolbar en bas de la page ?

C'est normal, c'est juste une petite astuce à savoir pour éviter de s'arracher les cheveux inutilement. La toolbar (barre de débogage en français) est un petit bout de code HTML que rajoute Symfony à chaque page… contenant la balise</body>. Or sur cette page, vous pouvez afficher la source depuis votre navigateur, il n'y a aucune balise HTML, donc Symfony n'ajoute pas la toolbar.

Pour l'activer, rien de plus simple, il nous faut rajouter une toute petite structure HTML. Pour cela, ouvrez le fichiersrc/OC/PlatformBundle/Resources/views/Default/index.html.twig, c'est la vue utilisée pour cette page. L'extension.twigsignifie qu'on utilise le moteur de templates Twig pour gérer nos vues, on en reparlera bien sûr. Le fichier est plutôt simple, et je vous propose de le changer ainsi :

{# src/OC/PlatformBundle/Resources/views/Default/index.html.twig #}

<html>
  <body>
    Hello World!
  </body>
</html>

Actualisez la page, et voici une magnifique toolbar semblable à la figure suivante qui apparaît en bas de la page ! Seule la balise</body>suffisait, mais quitte à changer autant avoir une structure HTML valide. 

La toolbar apparaît
La toolbar apparaît

Que s'est-il passé ?

Dans les coulisses, Symfony a fait pas mal de choses, revoyons tout cela à notre rythme.

Symfony a généré la structure du bundle

Allez dans le répertoiresrc/OC/PlatformBundle, vous pouvez voir tout ce que Symfony a généré pour nous. Rappelez-vous la structure d'un bundle que nous avons vu au chapitre précédent : Symfony en a généré la plus grande partie !

À savoir : le seul fichier obligatoire pour un bundle est en fait la classeOCPlatformBundle.phpà la racine du répertoire. Vous pouvez l'ouvrir et voir ce qu'il contient : pas très intéressant en soi ; heureusement que Symfony l'a généré tout seul. Sachez-le dès maintenant : nous ne modifierons presque jamais ce fichier, vous pouvez passer votre chemin.

Symfony a enregistré notre bundle auprès du Kernel

Le bundle est créé, mais il faut dire à Symfony de le charger. Pour cela il faut configurer le noyau (le Kernel) pour qu'il le charge. Rappelez-vous, la configuration de l'application se trouve dans le répertoire/app. En l'occurrence, la configuration du noyau se fait dans le fichierapp/AppKernel.php:

<?php
// app/AppKernel.php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),
            new Symfony\Bundle\MonologBundle\MonologBundle(),
            new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
            new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
            new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
            new AppBundle\AppBundle(),
            // Le générateur a généré la ligne suivante :
            new OC\PlatformBundle\OCPlatformBundle(),
        );

        if (in_array($this->getEnvironment(), array('dev', 'test'), true)) {
            $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
            $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
            $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
            $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
        }

        return $bundles;
    }
    
    // ...
}

Cette classe permet donc uniquement de définir quels bundles charger pour l'application. Vous pouvez le voir, ils sont instanciés dans un simple tableau. Les lignes 12 à 21 définissent les bundles à charger pour l'environnement de production. Les lignes 25 à 28 définissent les bundles à charger en plus pour l'environnement de développement.

Comme vous pouvez le voir, le générateur du bundle a modifié lui-même ce fichier pour y ajouter la ligne 21. C'est ce que l'on appelle « enregistrer le bundle dans l'application ».

Vous pouvez voir également que plein d'autres bundles sont déjà enregistrés, ce sont tous les bundles par défaut qui apportent des fonctionnalités de base au framework Symfony. En fait, quand on parle de Symfony, on parle à la fois de ses composants (Kernel, Routeur, etc.) et de ses bundles.

Symfony a enregistré nos routes auprès du Routeur

Les routes ? Le Routeur ?

Pas de panique, nous verrons tout cela en détails dans les prochains chapitres. Sachez juste pour l'instant que le rôle du Routeur, que nous avons brièvement vu sur le schéma du chapitre précédent, est de déterminer quel contrôleur exécuter en fonction de l'URL appelée. Pour cela, il utilise les routes.

Chaque bundle dispose de ses propres routes. Pour notre bundle fraîchement créé, vous pouvez les voir dans le fichiersrc/OC/PlatformBundle/Resources/config/routing.yml. En l'occurrence il n'y en a qu'une seule :

# src/OC/PlatformBundle/Resources/config/routing.yml

oc_platform_homepage:
    path:     /
    defaults: { _controller: OCPlatformBundle:Default:index }

Or ces routes ne sont pas chargées automatiquement, il faut dire au Routeur « Bonjour, mon bundle OCPlatformBundle contient des routes qu'il faut que tu viennes chercher. » Cela se fait, vous l'aurez deviné, dans la configuration de l'application. Cette configuration se trouve toujours dans le répertoire/app, en l'occurrence pour les routes il s'agit du fichierapp/config/routing.yml:

# app/config/routing.yml

oc_platform:
    resource: "@OCPlatformBundle/Resources/config/routing.yml"
    prefix:   /

# ...

Ce sont ces lignes qui importent le fichier de routes situé dans notre bundle. Ces lignes ont déjà été générées par le générateur de bundle, vraiment pratique !

À retenir

Ce qu'il faut retenir de tout cela, c'est que pour qu'un bundle soit opérationnel, il faut :

  • Son code source, situé danssrc/Application/Bundle, et dont le seul fichier obligatoire est la classe à la racineOCPlatformBundle.php;

  • Enregistrer le bundle dans le noyau pour qu'il soit chargé, en modifiant le fichierapp/AppKernel.php;

  • Enregistrer les routes (si le bundle en contient) dans le Routeur pour qu'elles soient chargées, en modifiant le fichierapp/config/routing.yml.

Ces trois points sont bien sûr effectués automatiquement lorsqu'on utilise le générateur. Mais vous pouvez tout à fait créer un bundle sans l'utiliser, et il faudra alors remplir cette petite checklist manuellement.

Par la suite, tout notre code source sera situé dans des bundles. Un moyen très propre de bien structurer son application.

En résumé

  • Les commandes Symfony disponibles en ligne de commande ont pour objectif de nous faciliter la vie en automatisant certaines tâches.

  • Les commandes sont faites, comme tout Symfony, en PHP uniquement. La console n'est qu'un moyen différent du navigateur pour exécuter du code PHP. 

  • La commande pour générer un nouveau bundle estphp bin/console generate:bundle.

  • Le code du cours tel qu'il doit être à ce stade est disponible sur la branche iteration-1 du dépot Github.

Example of certificate of achievement
Example of certificate of achievement