• 30 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

Ce cours existe en livre papier.

course.header.alt.is_certifying

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 04/09/2017

Utilisons la console pour créer un bundle

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

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 Symfony2 en console ! L'objectif est de découvrir la console utilement.

Utilisation de la console

Tout d'abord, vous devez savoir une chose : Symfony2 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 Symfony2, en utilisant la commande Windows cd (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 fichier app/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 app/console. C'est parti :

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

Symfony version 2.7.0 - app/dev/debug

Usage:
  [options] command [arguments]

Options:
  --help           -h Display this help message.
  --quiet          -q Do not output any message.
  --verbose        -v Increase verbosity of messages.
  --version        -V Display this application version.
  --ansi              Force ANSI output.
  --no-ansi           Disable ANSI output.
  --no-interaction -n Do not ask any interactive question.
  --shell          -s Launch the shell.
  --process-isolation    Launch commands from shell as a separate processes.
  --env            -e The Environment name.
  --no-debug          Switches off debug mode.

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 Symfony2, probablement /var/www pour Linux ou /user/sites pour Mac. Le fichier que nous allons exécuter est app/console, il faut donc lancer la commande php app/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 Symfony2, 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é Symfony2, tout est toujours écrit en PHP, il n'y a rien d'autre. Pour en être sûrs, ouvrez le fichier app/console :

<?php

set_time_limit(0);

require_once __DIR__.'/bootstrap.php.cache';
require_once __DIR__.'/AppKernel.php';

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

$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 frontal app.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'articulerons 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 Symfony2, 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 commande php app/console generate:bundle.

1. Choisir le namespace

Symfony2 vous demande le namespace de votre bundle :

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


  Welcome to the Symfony2 bundle generator



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 console OC/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.

2. Choisir le nom

Symfony2 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 Symfony2 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.

3. Choisir la destination

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

The bundle can be generated anywhere. The suggested default directory uses
the standard conventions.

Target directory [C:/wamp/www/Symfony/src]:_

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

4. Choisir le format de configuration

Symfony2 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 [C:/wamp/www/Symfony/src]:

Determine the format to use for the generated configuration.

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

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 donc yml.

5. Choisir quelle structure générer

Symfony2 vous demande si vous voulez générer juste le minimum ou une structure plus complète pour le bundle :

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

To help you get started faster, the command can generate some
code snippets for you.

Do you want to generate the whole directory structure [no]?

Nous n'avons pas besoin de tout générer ici, appuyez donc sur Entrée pour dire non.

6. Confirmez, et c'est joué !

Pour toutes les questions suivantes, confirmez en appuyant sur Entrée à chaque fois. Et voilà, votre bundle est généré :

Do you want to generate the whole directory structure [no]? 


  Summary before generation


You are going to generate a "OC\PlatformBundle\OCPlatformBundle" bundle
in "C:/wamp/www/Symfony/src/" using the "yml" format.

Do you confirm generation [yes]?


  Bundle generation


Generating the bundle code: OK
Checking that the bundle is autoloaded: OK
Confirm automatic update of your Kernel [yes]?
Enabling the bundle inside the Kernel: OK
Confirm automatic update of the Routing [yes]?
Importing the bundle routing resource: OK


  You can now start using the generated code!



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 Symfony2 à 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 Symfony2 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 fichier src/OC/PlatformBundle/Resources/views/Default/index.html.twig, c'est la vue utilisée pour cette page. L'extension .twig signifie 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 {{ name }}!
  </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, Symfony2 a fait pas mal de choses, revoyons tout cela à notre rythme.

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

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

À savoir : le seul fichier obligatoire pour un bundle est en fait la classe OCPlatformBundle.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.

Symfony2 a enregistré notre bundle auprès du Kernel

Le bundle est créé, mais il faut dire à Symfony2 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 fichier app/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 Symfony\Bundle\AsseticBundle\AsseticBundle(),
            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'))) {
            $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;
    }

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
    }
}

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 à 22 définissent les bundles à charger pour l'environnement de production. Les lignes 26 à 29 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 22. 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 Symfony2. En fait, quand on parle de Symfony2, on parle à la fois de ses composants (Kernel, Routeur, etc.) et de ses bundles.

Symfony2 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 fichier src/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:     /hello/{name}
    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 fichier app/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é dans src/Application/Bundle, et dont le seul fichier obligatoire est la classe à la racine OCPlatformBundle.php ;

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

  • Enregistrer les routes (si le bundle en contient) dans le Routeur pour qu'elles soient chargées, en modifiant le fichier app/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 Symfony2 disponibles en ligne de commande ont pour objectif de nous faciliter la vie en automatisant certaines tâches.

  • Les commandes sont faites, comme tout Symfony2, 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 est php app/console generate:bundle.

Exemple de certificat de réussite
Exemple de certificat de réussite