SlideShare une entreprise Scribd logo
1  sur  97
Télécharger pour lire hors ligne
Symfony2: 30 astuces et bonnes
         pratiques
Noel GUILBERT

                • Développeur Symfony depuis 2005

                • Consultant et formateur à SensioLabs

                • http://www.noelguilbert.com

                • http://twitter.com/noelguilbert
Avant propos

   • La version actuelle est en cours de développement

   • Une version stable est prévue pour bientôt

   • Les éléments présenté durant cette session peuvent changer
Rappel
Les bonnes pratiques que vous avez appris avec symfony 1 sont bien
évidemment toujours d'actualité:

  • Pas de logique métier dans les templates, ni dans les contrôleurs
    : uniquement dans les classes métier

  • Gérer la présentation dans les vues : pas dans les contrôleurs ni
    les classes métier

  • Ne dupliquez pas de code

  • Ne modifiez pas directement les classes du framework

  • ...
Here we Go !
30 astuces et bonnes pratiques à propos de Symfony2
 • Par où commencer ?

 • Comment organiser votre code ?

 • Quel moteur de templates choisir ?

 • Configuration

 • Gestion des erreurs

 • Templating

 • Comment utiliser l'injecteur de dépendances ?

 • Profiling

 • Debugging

 • Sécurité

 • Performances
1) Par où commencer?
Par où commencer ?
 • Documentation: http://docs.symfony-reloaded.org/master/

     ◦ Quick Tour: 1h pour prendre en main le framework

     ◦ Flat PHP application to Symfony2: un autre tutorial pour prendre en main le framework

     ◦ Guides: http://docs.symfony-reloaded.org/master/guides

     ◦ Cookbook: http://docs.symfony-reloaded.org/master/cookbook

 • Sandbox: version prépackagée d'une application Symfony2

     ◦ Pour le moment, c'est la seule méthode recommandée pour démarrer un projet
2) Organisez vos projets!
Organisation des projets
Projets

  • Avec Symfony2, aucune structure n'est imposée

  • La sandbox est une structure possible, respectant les bonnes
    pratiques

  • Si vous voulez que vos projets soit facilement repris en main par
    différents développeurs, gardez le modèle de la sandbox
Organisation des applications
Les applications

  • Avec Symfony2, vous aurez généralement besoin que d'une
    seule application:

       ◦ Le système de sécurité permet de cloisonner efficacement
         chaque fonctionnalité (backend/frontend)

       ◦ Les classes et services sont chargés uniquement si vous les
         utilisez: pas d'impact sur les performances
Multi applications
 • Vous pouvez avoir besoin de plusieurs applications:

     ◦ Projet avec beaucoup de fonctionnalités, et avec un besoin
       cloisonnement

     ◦ Séparation importante entre les différentes fonctionnalités

 • Généralement, vous avez surtout besoin de créer un nouveau
   projet
Organisation en multi-applications
Exemple de projet avec plusieurs applications
  /application1/
      Application1Kernel.php
      ...
  /application2/
      Application2Kernel.php
      ...
  /web/
      application1.php
      application2.php
      ...
Organisation des bundles
Les bundles
 • Organisez vos bundles en briques logicielles: chaque bundle est responsable d'une
   fonctionnalité:

     ◦ ForumBundle

     ◦ BlogBundle

     ◦ UserBundle

     ◦ ShopBundle

  src/Sensio/
     Bundle/
         UserBundle/
              Controller/
                  UserController.php
         ShopBundle/
              Controller/
                  OrderController.php
3. Isolez vos classes métiers
Isolez vos classes métiers
Problématique
 • Souvent, vous avez des classes qui sont réutilisées dans plusieurs bundles

 • Ces classes peuvent même être utilisées dans des projets n'utilisant pas Symfony2

Solution
 • Les bundles sont uniquement des liens entre votre code métier et le framework

 • Vous pouvez donc avoir des classes en dehors de vos bundles

 • C'est le choix d'architecture qui a été fait pour le framework: Bundles vs Components
Séparez vos classes métiers des
bundles
Exemple de structure avec une séparation des classes métiers et des
bundles
  src/Sensio/
      Bundle/
         UserBundle/
         OrderBundle/
      Business/         <--------- Classes metiers
         Form/
              User.php
         Validator/
              Order.php
     Entity/            <--------- Entites Doctrine2
         User.php
Séparez vos classes métiers des
bundles
Grâce à l'autoloading, vous pouvez très simplement charger des classes qui ne sont pas dans un bundle.

   <?php

   use SymfonyComponentClassLoaderUniversalClassLoader;

   $loader = new UniversalClassLoader();
   $loader->registerNamespaces(array(
       'Sensio'    => __DIR__.'/../src',
   ));

   $loader->register();

   # in your application
   new SensioBusinessFormUser();
Spécificité pour les entités
Doctrine2
Déclarez les mappings
Il faut indiquer à Doctrine2 où sont les entités, lorsqu'elles ne sont pas dans un bundle:

   # app/config/config.yml
   orm:
        auto_generate_proxy_classes: %kernel.debug%
        mappings:
            Sensio:
                  type: annotation
                  prefix: Sensio
                  dir: %kernel.root_dir%/../src/Sensio/Entity
4: Utilisez votre namespace
Utilisez votre propre namespace
 Gérez votre propre namespace:
 Vos projets doivent avoir leurs propre namespaces:

  • n'utilisez pas le namespace Sensio de la sandbox!

       ◦ Sensio

       ◦ YourCompany

       ◦ MyProject

    <?php

        namespace Sensio;

        class Product
        {
            /* ... */
        }
5: Bibliothèque externes
Bibliothèques externes
 • Par défaut, la sandbox est fournie avec toutes les bibliothèques externe qu'elle supporte:

     ◦ Symfony2

     ◦ Twig

     ◦ Doctrine

     ◦ SwiftMailer

     ◦ Assetic

 • Retirez les bibliothèques que vous n'utilisez pas:

     ◦ Supprimez les répertoires correspondants

     ◦ Retirez les de la configuration de l'autoloader

     ◦ Désactivez les bundles associés
6: Ne divulgez plus vos mots de passes
Ne divulgez plus vos mots de passes
 Utilisez des variables d'environnement
  • Vous pouvez définir des variables d'environnement spécifiques pour vos projets Symfony2:

      ◦ Les variables doivent être préfixées par SYMFONY_ _

      ◦ Vous pouvez ensuite utiliser ces paramètres naturellement dans vos fichiers de
        configuration
Ne divulgez plus vos mots de passes
 Configuration des variables d'environnement depuis un VirtualHost
   # VirtualHost configuration
   <VirtualHost *:80>
       Servername www.domain.tld

       # ...

       SetEnv SYMFONY__DATABASE_USERNAME "sflive"
       SetEnv SYMFONY__DATABASE_PASSWORD "s3cr3t"
   </VirtualHost>

   # Application configuration: app/config/config.yml

   doctrine:
       dbal:
           username: %database_username%
           password: %database_password%
7: Configuration: le format INI
Le format INI
Généralement, n'utilisez pas le format INI pour vos projets:

  • La syntaxe est limité

  • Pas de validation
Le format INI
 Le format INI peut être utile dans certains cas
 Si vous souhaitez fournir une application paramétrable à des profils peu techniques, vous pouvez
 utiliser le format INI.

    ; blog.ini
    [parameters]
    blog.admin.email = noelguilbert@gmail.com
    blog.admin.name = Noël

 Importez ce fichier dans la configuration de votre bundle:

    <container>
        <imports>
            <import resource="blog.ini" />
        </imports>

        <services id="blog.notification.email"
                  class="SensioBlogBundleNotificationEmail">
            <argument key="admin_email">%blog.admin.email%</argument>
            <argument key="admin_name">%blog.admin.name%</argument>
        </services>
    </container>
8: Utilisez Twig
Utilisez Twig
 • Deux moteurs de templates sont disponibles par défaut avec Symfony2:

     ◦ PHP

     ◦ Twig

 • Twig est le moteur de template recommandé :

     ◦ Protection XSS

     ◦ Mode sandbox

     ◦ Limite la logique métier dans les templates

     ◦ Utilisable très facilement par les intégrateurs HTML
9: Surchargez les pages d'erreurs
Surcharge des pages d'erreurs
Plusieurs solutions sont à votre disposition:

  • Surcharger uniquement les templates

  • Surcharger les contrôleurs

  • Créer un service pour surcharger le comportement du framework
Surcharge des pages d'erreurs
 • Surchargez les templates:

     ◦ app/view/FrameworkBundle/error.html.twig

     ◦ app/view/FrameworkBundle/error.xml.twig

     ◦ app/view/FrameworkBundle/error.json.twig

  <!-- app/view/FrameworkBundle/error.html.twig -->
  <!DOCTYPE html>
  <html>
      <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      </head>
      <body>
          <h1>Oops! An Error Occurred</h1>
          <h2>The server returned a "{{ status_code }} {{ status_text }}".</h2>

          <div>
              Something is broken. Please e-mail us at [email] and let us know
              what you were doing when this error occurred. We will fix it as soon
              as possible. Sorry for any inconvenience caused.
          </div>
      </body>
  </html>
Surcharge des pages d'erreurs
 • Par défaut, les exceptions sont récupérées par un controller.

 • Vous pouvez utiliser un autre contrôleur

      # app/config/config.yml

      framework:
          exception_controller: SensioHelloBundleControllerErrorController


 • Votre contrôleur doit implémenter une méthode showAction

  <?php

  namespace SensioHelloBundleController;

  class ErrorController extends ContainerAware
  {

       public function showAction(FlattenException $exception)
       {
           // do whatever you want here

            return new Response(/* ... */);
       }
  }
Surcharge des pages d'erreurs
 • Si vous voulez complètement surcharger le mécanisme
   d'exception de symfony, vous pouvez utiliser un service

 • Ce service doit écouter l'évènement core.exception
Surcharge des pages d'erreurs
Déclaration du service
  <service id="sensio.error_handle" class="SensioErrorExceptionHandler">
      <tag name="kernel.listener"
           event="core.exception"
           method="handleException"
           priority="-128"
      />
  </service>


 Implémentation du service
    <?php

    namespace SensioError;

    class ExceptionHandler
    {
        public function handleException(EventInterface $event)
        {
            $exception = $event->get('exception');
            // do whatever you want here

            return new Response(/* ... */);
        }
    }
10) Contrôleurs
Contrôleurs
 Les contrôleurs ne doivent pas hériter de la classe Controller du
 FrameworkBundle.
   <?php

   namespace HelloBundleController;

   use SymfonyBundleFrameworkBundleControllerController;

   class BadController extends Controller
   {
       // your code here
   }
Contrôleurs
Pourquoi ce n'est pas conseillé:

  • Les méthodes fournies par cette classe ne sont que des
    raccourcis

  • Surtout utile pour débuter avec le framework

  • Cette dépendance n'est pas obligatoire

  • L'overhead ajouté n'apporte aucun bénéfice
Contrôleurs
 Ce contrôleur est correct:
   <?php
   # Sensio/HelloBundle/Controller/Controller.php
   namespace SensioHelloBundle;

   class SimplestController
   {
       /**
         * @extra:Route("/hello")
         */
       public function hello()
       {
            return new Response('Hello World');
       }
   }
Contrôleurs
 Oui, les contrôleurs peuvent être de simples objets PHP
 Avantages:                      Inconvénients:

  • Aucune dépendance             • Aucun moyen d'accéder aux différentes
                                    fonctionnalités du framework: request,
  • Pas d'overhead                  entity_manager, etc.

  • Très facile à comprendre
Contrôleurs
 Solution 1: Hériter de ContainerAware
   <?php

   namespace HelloBundleController;

   use SymfonyComponentDependencyInjectionContainerAware

   class GoodController extends ContainerAware
   {
       public function indexAction()
       {
           $em = $this->container->get('doctrine.orm.entity_manager');
       }
   }




 Avantages:
  • Plus de dépendances vers Controller

  • Les mêmes fonctionnalités sont disponibles

  • Pas d'overhead
Contrôleurs
 Solution 2: utiliser des services en tant que controlleurs

 Avantages:
  • Vous contrôlez vos dépendances via l'injecteur de dépendances

  • Vous pouvez tester unitairement vos contrôleurs
Contrôleurs
 Définition d'un contrôleur via l'injecteur de dépendances
  • Définition du service

   <!-- HelloBundle/Resources/controllers.xml -->
   <service id="better_controller" class="HelloBundleControllerServiceController" />

  • Configuration du routing

   my_route:
       defaults: { _controller: better_controller:index }

  • Votre contrôleur est toujours un objet PHP classique

   <?php
   namespace HelloBundleController;

   class ServiceController
   {
       public function indexAction()
       {
       }
   }
Contrôleurs
 Exemple: un contrôleur ayant accès aux services suivant:
  • Le service de templating

  • L'entity manager



 Configuration du service:
   # HelloBundle/Resources/controllers.xml
   <service id="product_controller" class="HelloBundleControllerProductController">
       <argument type="service" id="templating" />
       <argument type="doctrine.orm.entity_manager" />
   </service>
Contrôleurs
 Implémentation du contrôleur:
   <?php

   namespace HelloBundleController;

   class ProductController
   {
       public function __construct(EngineInterface $templating, EntityManager $em)
       {
           $this->templating = $templating;
           $this->em         = $em;
       }

       public function indexAction()
       {
           $products = $this->em->getRepository('HelloBundle:Product')->findAll();

           return $this->templating->renderResponse(
               'HelloBundle:Product:list.html.twig',
               array('products' => $products)
           );
       }
   }
11: Inclusion des assets
Inclusions des assets
 Assets avec Symfony2
  • Avec Symfony2, il n'y a plus de gestionnaire d'assets permettant d'ajouter les styles css à
    utiliser

  • Utilisez plutôt les blocs twig pour gérer vos assets.



 Dans votre layout de base:
   {# app/views/base.html.twig #}
   <html>
       <head>
           {%block stylesheets %}{% endblock %}
       </head>
       <body>
           {# ... #}
           {%block javascripts %}{% endblock %}
       </body>
   </html>
Inclusions des assets
 Choisissez les assets à utiliser directement dans vos templates:
   {# HelloBundle/Resources/views/Default/index.html.twig #}
   {% block stylesheets %}
       <link href="{{ assets("bundles/hello/css/styles.css") }}" rel="stylesheet" />
   {% endblock %}

   {% block javascripts %}
       <script src="{{ assets("bundles/hello/js/script.js") }}" type="text/javascript"></scr
   {% endblock %}
12: Utilisez les macros Twig
Twig: Utilisez les macros
 Cas d'utilisation classique: des boutons html personnalisés




 Le code HTML correspondant pourrait être le suivant:
   <a href="#" class="button">
     <span>
        <span>
          <span>
            Nice Button
          </span>
        </span>
     </span>
   </a>
Twig: Utilisez les macros
 Réalisez un macro permettant de réutiliser facilement ce code
 HTML
   {# HelloBundle/Resources/views/macro.html.twig #}
   {% macro button(url, text) %}
       <a href="{{ url }}" class="button">
         <span>
            <span>
              <span>
                {{ text }}
              </span>
            </span>
         </span>
       </a>
   {% endmacro %}




 Réutilisez cette macro dans vos templates:
   {# HelloBundle/Resources/views/Default/index.html.twig #}

   {% from "HelloBundle::macro.html.twig" import button %}

   {{ button("Nice Button!") }}
13: Internationalisation
Internationalisation
 Internationalisez vos projets
  • Parce que vous ne savez pas comment votre projet va évoluer

  • Parce que l'impact en terme de performances est négligeable

  • Parce que implémenter l'internationalisation après coup vous prendra beaucoup de temps
Injection de dépendance
14) Apprenez à l'utiliser
L'injecteur de dépendance est à la base du framework.

Domptez-le, et vous aurez le pouvoir de Symfony2 entre vos
mains!
Apprenez à utiliser l'injecteur de
dépendances
Ressources sur ce sujet:

  • http://www.slideshare.net/fabpot

  • http://fabien.potencier.org/article/13/introduction-to-the-symfony-service-container

  • http://components.symfony-project.org/dependency-injection/
15) Injection de dépendences: règles de
                 base
Règles générales:

   • Les classes doivent être utilisables sans le conteneur

   • Seul le conteneur connait les dépendances, et pas l'inverse

   • Ce n'est pas LA solution à tous vos problèmes
16) Utilisez le format XML
Définir vos services
 Utilisez le format xml pour décrire vos services:

   • Un peu plus verbeux

   • Mais beaucoup plus simple à appréhender et à comprendre

   • Autocomplétion dans les éditeurs XML qui le supporte
17) Injecteur de dépendances:
Injecteur de dépendances
 Quand l'utiliser?
 L'injecteur de dépendances doit être utilisés pour les objets
 métiers qui ont une portée globale:

   • request

   • http kernel

   • entity manager

   • caching driver (memcache, apc, ...)
18) Quand NE PAS l'utiliser?
Injecteur de dépendances
 Quand ne pas l'utiliser ?
 L'injecteur de dépendances ne doit pas être utilisés dans les
 cas suivants:

   • Retrouver une instance d'un objet métier (i.e. un produit
     dans une base de données)

   • Pour un objet n'ayant pas une portée globle: un objet métier
     n'étant utilisés que dans un controleur, par exemple
19) Ne pas injecter le container
Ne pas injecter le container
 Il ne faut pas injecter le container dans les objets:
  • Cela crée une dépendance forte avec le conteneur alors que vous avez rarement la nécessité

  • Vous ne pourrez plus utiliser vos classes sans le conteneur

   <?php

   namespace SensioProduct

   class Manager
   {
       public function __construct($container)
       {
           $this->dbh = $container->get('doctrine.dbal.default_connection');
       }
   }
Injecteur de dépendances
 Injecter directement le service concerné:
   <?php

   namespace SensioProduct

   class Manager
   {
       public function __construct($dbh)
       {
           $this->dbh = $dbh;
       }
   }
21) Sécurité
Sécurité
 Le module de sécurité est une part très spécifique de la
 configuration de votre projet
 Vous y définissez:

   • Comment retrouver vos utilisateurs

   • A quelles ressources il peuvent accéder

   • Comment il peuvent accéder à ces resources

 La bonne pratique est de définir ces informations dans un fichier spécifique
Sécurité
Exemple:

   # app/config/security.yml
   security:
       encoders:
           SymfonyComponentSecurityCoreUserUser: sha1

       providers:
           main:
               users:
                   foo: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: ROLE_USER

           facebook: true


       firewalls:
           main:
               pattern:    /.*
               http-basic: true
               logout:     true

       access_control:
           - { path: /admin, role: ROLE_ADMIN }
           - { path: /public, role: ROLE_ANONYMOUS }
           - { path: /.*, role: ROLE_USER }
22) Profiling
Profiling:
Surveillez vos performances:

  • nombre de requêtes

  • temps d'exécution

  • mémoire utilisée
Profiling:
Surveillez également vos redirections:

 • Les actions réalisant des redirections font très souvent des dizaines de requêtes

 • En environnement de développement, Symfony2 intercepte ces redirections pour vous permettre
   d'analyser l'exécution
23) Profiling en production
Profiling:
Il arrive parfois qu'un problème survienne en production sans que
vous soyez capable de comprendre le problème.

  • Avec symfony 1, une des solutions est d'activer le debug le
    temps de comprendre ce qu'il se passe.

  • Avec Symfony2, vous pouvez activer le profiler en production
    sans activer l'affichage des erreurs.

 Activer le profiling en production:

    # app/config/config_prod.yml
    framework:
        profiler: { only_exceptions: true }
Profiling:
Importer un dump
24) Utilisez les annotations
Utilisez les annotations
Les annotations permettent de définir des comportements, des éléments de configuration, etc...

   <?php

   /**
    * @orm:Entity
    */
    class User
    {

    }

Ce format de configuration est très pratique:

  • Il permet de définir des comportements directement dans les classes concernés

  • Tout est centralisé: vous n'avez plus à vous rappeler dans quel fichier tel ou tel comportement est
    défini
25) FrameworkExtraBundle
FrameworkExtraBundle
Le bundle FrameworkExtraBundle vous donne accès à d'avantages
d'annotations pour configurer:

  • Le routing

  • La ou les méthodes HTTP possible pour une règle de routing
    (GET, POST, ...)

  • les templates à utiliser

  • Le cache HTTP

  • Convertir des paramètres de requêtes (en entité Doctrine, par
    ex.)
FrameworkExtraBundle
 Exemple de contrôleur:
   <?php

   class AwesomeController extends ContainerAware
   {
       /**
         * @extra:Route("/awesome/controller")
         * @extra:Method("GET")
         * @extra:Template("SensioHelloBundle:Default:index.html.twig")
         * @extra:Cache(maxage=600)
         */
       public function indexAction()
       {

       }
   }
Performances
Optimisez vos performances grâce à Symfony2.
26) Optimisez l'autoloading
Autoloading
 • L'un des goulot d'étranglement classique en PHP est l'autoloading.

 • Les performances exceptionnelles de Symfony2 s'expliquent en partie par des solutions visant à
   optimiser le chargement des classes du framework

 • Vous pouvez également profiter de ces améliorations pour vos projets, grâce aux extensions de
   l'injecteur de dépendance.

  <?php

  namespace SensioUserBundleDependencyInjection;

  class UserExtension extends Extension
  {
      public function load(array $config, ContainerBuilder $container)
      {
          /* ... */

            $this->addClassesToCompile(array(
                'SensioUserBundleModelUser'
            ));
       }
  }
Autoloading
Vos classes sont "compilées" dans un fichier unique:

   <?php

   # app/cache/prod/classes.php
   /* ... */

   namespace SensioUserBundleModel {
       class User {
           /* your code */
       }
   }



  Avantages:
    • Plus besoin de passer par l'autoloader: vos classes sont forcéments chargées à chaque requête
      HTTP

    • Moins d'accès disque pour charger les classes

    • Ce fichier est mis en cache par les gestionnaire d'opcode (APC, EAccelerator, XCache)
Autoloading
L'arme secrète de Symfony2 est à votre portée!

  • Attention : cette fonctionnalité peut avoir l'effet inverse si elle
    est trop utilisée
27) Cache Warmer
Cache Warmer
La commande cache:warmup permet de pré-compiler tous les fichiers nécessaire en cache:

 • Templates

 • Injecteur de dépendance

 • Routing

 • Autoloading

   $> php symfony cache:warmup
28) Doctrine: vérifier la
     configuration
Doctrine: vérifier la configuration
Une commande dédiée vous permet de vérifier la bonne
configuration de Doctrine2 dans Symfony2:

  $>   php app/console doctrine:ensure-production-settings
29) Routing
Routing: Utilisez le router Apache
 Configurez Symfony pour utiliser le matcher Apache:
   # app/config/config.yml

   framework:
       router: { matcher: apache }




 Exportez vos règles de routing en RewriteRules:
   $> php app/console router:dump > rewrite.conf
30) Assets
Assets
Utilisez assetic pour de meilleures performances:

   {# HelloBundle/Resources/views/Default/index.html.twig #}
   {% block stylesheets %}
       {% stylesheet filter="yui_css", output="/css/main.css",
           "@HelloBundle/Resources/public/css/reset.css"
           "@HelloBundle/Resources/public/css/styles.css"
       %}
       <link href="{{ asset_url }}" rel="stylesheet" />
       {% endstylesheet %}
   {% endblock %}

   {% block javascripts %}
       {% javascript filter="closure", output="/js/script.js",
           "@HelloBundle/Resources/public/js/jquery.js"
           "@HelloBundle/Resources/public/js/hello.js"
       %}
       <script src="{{ asset_url }}" type="text/javascript"></script>
       {% endjavascript %}
   {% endblock %}
Questions ?
 Merci de votre attention!

Contenu connexe

Tendances

Presentation Symfony2
Presentation Symfony2Presentation Symfony2
Presentation Symfony2
Ahmed ABATAL
 
Présentation de symfony - Human talks aux docks le 8 juillet 2014
Présentation de symfony - Human talks aux docks le 8 juillet 2014Présentation de symfony - Human talks aux docks le 8 juillet 2014
Présentation de symfony - Human talks aux docks le 8 juillet 2014
Tony Galmiche
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs Symfony
Vincent Composieux
 
Exposer des services web SOAP et REST avec symfony 1.4 et Zend Framework
Exposer des services web SOAP et REST avec symfony 1.4 et Zend FrameworkExposer des services web SOAP et REST avec symfony 1.4 et Zend Framework
Exposer des services web SOAP et REST avec symfony 1.4 et Zend Framework
Hugo Hamon
 
symfony : Un Framework Open-Source pour les Professionnels
symfony : Un Framework Open-Source pour les Professionnelssymfony : Un Framework Open-Source pour les Professionnels
symfony : Un Framework Open-Source pour les Professionnels
Fabien Potencier
 
Utiliser le Zend Framework avec Symfony
Utiliser le Zend Framework avec SymfonyUtiliser le Zend Framework avec Symfony
Utiliser le Zend Framework avec Symfony
Xavier Gorse
 

Tendances (20)

Atelier Symfony2- Introduction
Atelier Symfony2- IntroductionAtelier Symfony2- Introduction
Atelier Symfony2- Introduction
 
Presentation Symfony2
Presentation Symfony2Presentation Symfony2
Presentation Symfony2
 
Symfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulairesSymfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulaires
 
Presentation Symfony
Presentation SymfonyPresentation Symfony
Presentation Symfony
 
Presentation du framework symfony
Presentation du framework symfonyPresentation du framework symfony
Presentation du framework symfony
 
Présentation de symfony - Human talks aux docks le 8 juillet 2014
Présentation de symfony - Human talks aux docks le 8 juillet 2014Présentation de symfony - Human talks aux docks le 8 juillet 2014
Présentation de symfony - Human talks aux docks le 8 juillet 2014
 
Une application en deux heure - PHP Québec Janvier 2009
Une application en deux heure - PHP Québec Janvier 2009Une application en deux heure - PHP Québec Janvier 2009
Une application en deux heure - PHP Québec Janvier 2009
 
Symfony 2 et le Web
Symfony 2 et le WebSymfony 2 et le Web
Symfony 2 et le Web
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs Symfony
 
Symfony3 overview
Symfony3 overviewSymfony3 overview
Symfony3 overview
 
Exposer des services web SOAP et REST avec symfony 1.4 et Zend Framework
Exposer des services web SOAP et REST avec symfony 1.4 et Zend FrameworkExposer des services web SOAP et REST avec symfony 1.4 et Zend Framework
Exposer des services web SOAP et REST avec symfony 1.4 et Zend Framework
 
symfony : Un Framework Open-Source pour les Professionnels
symfony : Un Framework Open-Source pour les Professionnelssymfony : Un Framework Open-Source pour les Professionnels
symfony : Un Framework Open-Source pour les Professionnels
 
Symfony2 Presentation
Symfony2 PresentationSymfony2 Presentation
Symfony2 Presentation
 
PHP5 et Zend Framework
PHP5 et Zend FrameworkPHP5 et Zend Framework
PHP5 et Zend Framework
 
wallabag, comment on a migré vers symfony3
wallabag, comment on a migré vers symfony3wallabag, comment on a migré vers symfony3
wallabag, comment on a migré vers symfony3
 
Utiliser le Zend Framework avec Symfony
Utiliser le Zend Framework avec SymfonyUtiliser le Zend Framework avec Symfony
Utiliser le Zend Framework avec Symfony
 
Symfony
SymfonySymfony
Symfony
 
Symfony with angular.pptx
Symfony with angular.pptxSymfony with angular.pptx
Symfony with angular.pptx
 
PHP Composer : Pourquoi ? Comment ? Et plus ...
PHP Composer : Pourquoi ? Comment ? Et plus ...PHP Composer : Pourquoi ? Comment ? Et plus ...
PHP Composer : Pourquoi ? Comment ? Et plus ...
 
Atelier symfony n 1
Atelier symfony n 1Atelier symfony n 1
Atelier symfony n 1
 

En vedette

Alphorm.com Support de la Formation Symfony 3 , les fondamentaux-ss
Alphorm.com Support de la Formation Symfony 3 , les fondamentaux-ssAlphorm.com Support de la Formation Symfony 3 , les fondamentaux-ss
Alphorm.com Support de la Formation Symfony 3 , les fondamentaux-ss
Alphorm
 
Boostez vos-developpements-symfony-avec-phpedit
Boostez vos-developpements-symfony-avec-phpeditBoostez vos-developpements-symfony-avec-phpedit
Boostez vos-developpements-symfony-avec-phpedit
auto entrepreneur
 
Very lastroom symfony1 vers symfony2 en douceur
Very lastroom   symfony1 vers symfony2 en douceurVery lastroom   symfony1 vers symfony2 en douceur
Very lastroom symfony1 vers symfony2 en douceur
Sébastien Houzé
 
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
Fabien Potencier
 

En vedette (19)

Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec Symfony
 
Design pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentesDesign pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentes
 
30 Symfony Best Practices
30 Symfony Best Practices30 Symfony Best Practices
30 Symfony Best Practices
 
Alphorm.com Support de la Formation Symfony 3 , les fondamentaux-ss
Alphorm.com Support de la Formation Symfony 3 , les fondamentaux-ssAlphorm.com Support de la Formation Symfony 3 , les fondamentaux-ss
Alphorm.com Support de la Formation Symfony 3 , les fondamentaux-ss
 
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
 
Drupal 8 + Symfony 2 = une équipe gagnante
Drupal 8 + Symfony 2 = une équipe gagnanteDrupal 8 + Symfony 2 = une équipe gagnante
Drupal 8 + Symfony 2 = une équipe gagnante
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Comment construire un environnement e-commerce complet avec Symfony 2 ?
Comment construire un environnement e-commerce complet avec Symfony 2 ? Comment construire un environnement e-commerce complet avec Symfony 2 ?
Comment construire un environnement e-commerce complet avec Symfony 2 ?
 
Symfony Debug & VarDumper
Symfony Debug & VarDumperSymfony Debug & VarDumper
Symfony Debug & VarDumper
 
Boostez vos-developpements-symfony-avec-phpedit
Boostez vos-developpements-symfony-avec-phpeditBoostez vos-developpements-symfony-avec-phpedit
Boostez vos-developpements-symfony-avec-phpedit
 
Very lastroom symfony1 vers symfony2 en douceur
Very lastroom   symfony1 vers symfony2 en douceurVery lastroom   symfony1 vers symfony2 en douceur
Very lastroom symfony1 vers symfony2 en douceur
 
La Console Symfony
La Console Symfony La Console Symfony
La Console Symfony
 
Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)
 
Conference drupal 8 au Forum PHP 2013 à Paris
Conference drupal 8 au Forum PHP 2013 à ParisConference drupal 8 au Forum PHP 2013 à Paris
Conference drupal 8 au Forum PHP 2013 à Paris
 
Drupal 8
Drupal 8Drupal 8
Drupal 8
 
Symfony 2 : Performances et Optimisations
Symfony 2 : Performances et OptimisationsSymfony 2 : Performances et Optimisations
Symfony 2 : Performances et Optimisations
 
Symfony live Paris 2014 - Symfony2 sur Azure
Symfony live Paris 2014 - Symfony2 sur AzureSymfony live Paris 2014 - Symfony2 sur Azure
Symfony live Paris 2014 - Symfony2 sur Azure
 
Symfonytn
SymfonytnSymfonytn
Symfonytn
 
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
 

Similaire à Symfony2: 30 astuces et bonnes pratiques

#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
Atsé François-Xavier KOBON
 
Introduction à Zend Framework 2
Introduction à Zend Framework 2Introduction à Zend Framework 2
Introduction à Zend Framework 2
Mickael Perraud
 
DEVASC_Module_7 - Infrastructure & automatisation.pptx
DEVASC_Module_7 - Infrastructure & automatisation.pptxDEVASC_Module_7 - Infrastructure & automatisation.pptx
DEVASC_Module_7 - Infrastructure & automatisation.pptx
TasnimBenAmmar
 

Similaire à Symfony2: 30 astuces et bonnes pratiques (20)

Spring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'tsSpring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'ts
 
Atelier symfony n 2
Atelier symfony n 2Atelier symfony n 2
Atelier symfony n 2
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
 
Zend Framework 2.0 - Le gestionnaire de modules
Zend Framework 2.0 - Le gestionnaire de modulesZend Framework 2.0 - Le gestionnaire de modules
Zend Framework 2.0 - Le gestionnaire de modules
 
Etude des Frameworks PHP
Etude des Frameworks PHPEtude des Frameworks PHP
Etude des Frameworks PHP
 
Drupal7 - Bonnes Pratiques (Partie 1)
Drupal7 - Bonnes Pratiques (Partie 1)Drupal7 - Bonnes Pratiques (Partie 1)
Drupal7 - Bonnes Pratiques (Partie 1)
 
20081008 - Tours Jug - Apache Maven
20081008  - Tours Jug - Apache Maven20081008  - Tours Jug - Apache Maven
20081008 - Tours Jug - Apache Maven
 
Introduction à Zend Framework 2
Introduction à Zend Framework 2Introduction à Zend Framework 2
Introduction à Zend Framework 2
 
DEVASC_Module_7 - Infrastructure & automatisation.pptx
DEVASC_Module_7 - Infrastructure & automatisation.pptxDEVASC_Module_7 - Infrastructure & automatisation.pptx
DEVASC_Module_7 - Infrastructure & automatisation.pptx
 
Présentation1
Présentation1Présentation1
Présentation1
 
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et JenkinsBuild automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
 
20081023 - Paris Vi Master STL TA - Initiation Maven
20081023 - Paris Vi Master STL TA - Initiation Maven20081023 - Paris Vi Master STL TA - Initiation Maven
20081023 - Paris Vi Master STL TA - Initiation Maven
 
Comment réussir son projet en Angular 1.5 ?
Comment réussir son projet en Angular 1.5 ?Comment réussir son projet en Angular 1.5 ?
Comment réussir son projet en Angular 1.5 ?
 
Accroître la sécurité de son site internet et de Joomla! plus spécifiquement
Accroître la sécurité de son site internet et de Joomla! plus spécifiquementAccroître la sécurité de son site internet et de Joomla! plus spécifiquement
Accroître la sécurité de son site internet et de Joomla! plus spécifiquement
 
20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven
 
20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache Maven20081113 - Nantes Jug - Apache Maven
20081113 - Nantes Jug - Apache Maven
 
Introduction à Symfony
Introduction à SymfonyIntroduction à Symfony
Introduction à Symfony
 
Industrialisation des développements logiciels
Industrialisation des développements logicielsIndustrialisation des développements logiciels
Industrialisation des développements logiciels
 
Les générateurs de code, pour se simplifier la vie au quotidien
Les générateurs de code, pour se simplifier la vie au quotidienLes générateurs de code, pour se simplifier la vie au quotidien
Les générateurs de code, pour se simplifier la vie au quotidien
 
tp-spring.pdf
tp-spring.pdftp-spring.pdf
tp-spring.pdf
 

Symfony2: 30 astuces et bonnes pratiques

  • 1. Symfony2: 30 astuces et bonnes pratiques
  • 2. Noel GUILBERT • Développeur Symfony depuis 2005 • Consultant et formateur à SensioLabs • http://www.noelguilbert.com • http://twitter.com/noelguilbert
  • 3. Avant propos • La version actuelle est en cours de développement • Une version stable est prévue pour bientôt • Les éléments présenté durant cette session peuvent changer
  • 4. Rappel Les bonnes pratiques que vous avez appris avec symfony 1 sont bien évidemment toujours d'actualité: • Pas de logique métier dans les templates, ni dans les contrôleurs : uniquement dans les classes métier • Gérer la présentation dans les vues : pas dans les contrôleurs ni les classes métier • Ne dupliquez pas de code • Ne modifiez pas directement les classes du framework • ...
  • 5. Here we Go ! 30 astuces et bonnes pratiques à propos de Symfony2 • Par où commencer ? • Comment organiser votre code ? • Quel moteur de templates choisir ? • Configuration • Gestion des erreurs • Templating • Comment utiliser l'injecteur de dépendances ? • Profiling • Debugging • Sécurité • Performances
  • 6. 1) Par où commencer?
  • 7. Par où commencer ? • Documentation: http://docs.symfony-reloaded.org/master/ ◦ Quick Tour: 1h pour prendre en main le framework ◦ Flat PHP application to Symfony2: un autre tutorial pour prendre en main le framework ◦ Guides: http://docs.symfony-reloaded.org/master/guides ◦ Cookbook: http://docs.symfony-reloaded.org/master/cookbook • Sandbox: version prépackagée d'une application Symfony2 ◦ Pour le moment, c'est la seule méthode recommandée pour démarrer un projet
  • 8. 2) Organisez vos projets!
  • 9. Organisation des projets Projets • Avec Symfony2, aucune structure n'est imposée • La sandbox est une structure possible, respectant les bonnes pratiques • Si vous voulez que vos projets soit facilement repris en main par différents développeurs, gardez le modèle de la sandbox
  • 10. Organisation des applications Les applications • Avec Symfony2, vous aurez généralement besoin que d'une seule application: ◦ Le système de sécurité permet de cloisonner efficacement chaque fonctionnalité (backend/frontend) ◦ Les classes et services sont chargés uniquement si vous les utilisez: pas d'impact sur les performances
  • 11. Multi applications • Vous pouvez avoir besoin de plusieurs applications: ◦ Projet avec beaucoup de fonctionnalités, et avec un besoin cloisonnement ◦ Séparation importante entre les différentes fonctionnalités • Généralement, vous avez surtout besoin de créer un nouveau projet
  • 12. Organisation en multi-applications Exemple de projet avec plusieurs applications /application1/ Application1Kernel.php ... /application2/ Application2Kernel.php ... /web/ application1.php application2.php ...
  • 13. Organisation des bundles Les bundles • Organisez vos bundles en briques logicielles: chaque bundle est responsable d'une fonctionnalité: ◦ ForumBundle ◦ BlogBundle ◦ UserBundle ◦ ShopBundle src/Sensio/ Bundle/ UserBundle/ Controller/ UserController.php ShopBundle/ Controller/ OrderController.php
  • 14. 3. Isolez vos classes métiers
  • 15. Isolez vos classes métiers Problématique • Souvent, vous avez des classes qui sont réutilisées dans plusieurs bundles • Ces classes peuvent même être utilisées dans des projets n'utilisant pas Symfony2 Solution • Les bundles sont uniquement des liens entre votre code métier et le framework • Vous pouvez donc avoir des classes en dehors de vos bundles • C'est le choix d'architecture qui a été fait pour le framework: Bundles vs Components
  • 16. Séparez vos classes métiers des bundles Exemple de structure avec une séparation des classes métiers et des bundles src/Sensio/ Bundle/ UserBundle/ OrderBundle/ Business/ <--------- Classes metiers Form/ User.php Validator/ Order.php Entity/ <--------- Entites Doctrine2 User.php
  • 17. Séparez vos classes métiers des bundles Grâce à l'autoloading, vous pouvez très simplement charger des classes qui ne sont pas dans un bundle. <?php use SymfonyComponentClassLoaderUniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespaces(array( 'Sensio' => __DIR__.'/../src', )); $loader->register(); # in your application new SensioBusinessFormUser();
  • 18. Spécificité pour les entités Doctrine2 Déclarez les mappings Il faut indiquer à Doctrine2 où sont les entités, lorsqu'elles ne sont pas dans un bundle: # app/config/config.yml orm: auto_generate_proxy_classes: %kernel.debug% mappings: Sensio: type: annotation prefix: Sensio dir: %kernel.root_dir%/../src/Sensio/Entity
  • 19. 4: Utilisez votre namespace
  • 20. Utilisez votre propre namespace Gérez votre propre namespace: Vos projets doivent avoir leurs propre namespaces: • n'utilisez pas le namespace Sensio de la sandbox! ◦ Sensio ◦ YourCompany ◦ MyProject <?php namespace Sensio; class Product { /* ... */ }
  • 22. Bibliothèques externes • Par défaut, la sandbox est fournie avec toutes les bibliothèques externe qu'elle supporte: ◦ Symfony2 ◦ Twig ◦ Doctrine ◦ SwiftMailer ◦ Assetic • Retirez les bibliothèques que vous n'utilisez pas: ◦ Supprimez les répertoires correspondants ◦ Retirez les de la configuration de l'autoloader ◦ Désactivez les bundles associés
  • 23. 6: Ne divulgez plus vos mots de passes
  • 24. Ne divulgez plus vos mots de passes Utilisez des variables d'environnement • Vous pouvez définir des variables d'environnement spécifiques pour vos projets Symfony2: ◦ Les variables doivent être préfixées par SYMFONY_ _ ◦ Vous pouvez ensuite utiliser ces paramètres naturellement dans vos fichiers de configuration
  • 25. Ne divulgez plus vos mots de passes Configuration des variables d'environnement depuis un VirtualHost # VirtualHost configuration <VirtualHost *:80> Servername www.domain.tld # ... SetEnv SYMFONY__DATABASE_USERNAME "sflive" SetEnv SYMFONY__DATABASE_PASSWORD "s3cr3t" </VirtualHost> # Application configuration: app/config/config.yml doctrine: dbal: username: %database_username% password: %database_password%
  • 26. 7: Configuration: le format INI
  • 27. Le format INI Généralement, n'utilisez pas le format INI pour vos projets: • La syntaxe est limité • Pas de validation
  • 28. Le format INI Le format INI peut être utile dans certains cas Si vous souhaitez fournir une application paramétrable à des profils peu techniques, vous pouvez utiliser le format INI. ; blog.ini [parameters] blog.admin.email = noelguilbert@gmail.com blog.admin.name = Noël Importez ce fichier dans la configuration de votre bundle: <container> <imports> <import resource="blog.ini" /> </imports> <services id="blog.notification.email" class="SensioBlogBundleNotificationEmail"> <argument key="admin_email">%blog.admin.email%</argument> <argument key="admin_name">%blog.admin.name%</argument> </services> </container>
  • 30. Utilisez Twig • Deux moteurs de templates sont disponibles par défaut avec Symfony2: ◦ PHP ◦ Twig • Twig est le moteur de template recommandé : ◦ Protection XSS ◦ Mode sandbox ◦ Limite la logique métier dans les templates ◦ Utilisable très facilement par les intégrateurs HTML
  • 31. 9: Surchargez les pages d'erreurs
  • 32. Surcharge des pages d'erreurs Plusieurs solutions sont à votre disposition: • Surcharger uniquement les templates • Surcharger les contrôleurs • Créer un service pour surcharger le comportement du framework
  • 33. Surcharge des pages d'erreurs • Surchargez les templates: ◦ app/view/FrameworkBundle/error.html.twig ◦ app/view/FrameworkBundle/error.xml.twig ◦ app/view/FrameworkBundle/error.json.twig <!-- app/view/FrameworkBundle/error.html.twig --> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h1>Oops! An Error Occurred</h1> <h2>The server returned a "{{ status_code }} {{ status_text }}".</h2> <div> Something is broken. Please e-mail us at [email] and let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused. </div> </body> </html>
  • 34. Surcharge des pages d'erreurs • Par défaut, les exceptions sont récupérées par un controller. • Vous pouvez utiliser un autre contrôleur # app/config/config.yml framework: exception_controller: SensioHelloBundleControllerErrorController • Votre contrôleur doit implémenter une méthode showAction <?php namespace SensioHelloBundleController; class ErrorController extends ContainerAware { public function showAction(FlattenException $exception) { // do whatever you want here return new Response(/* ... */); } }
  • 35. Surcharge des pages d'erreurs • Si vous voulez complètement surcharger le mécanisme d'exception de symfony, vous pouvez utiliser un service • Ce service doit écouter l'évènement core.exception
  • 36. Surcharge des pages d'erreurs Déclaration du service <service id="sensio.error_handle" class="SensioErrorExceptionHandler"> <tag name="kernel.listener" event="core.exception" method="handleException" priority="-128" /> </service> Implémentation du service <?php namespace SensioError; class ExceptionHandler { public function handleException(EventInterface $event) { $exception = $event->get('exception'); // do whatever you want here return new Response(/* ... */); } }
  • 38. Contrôleurs Les contrôleurs ne doivent pas hériter de la classe Controller du FrameworkBundle. <?php namespace HelloBundleController; use SymfonyBundleFrameworkBundleControllerController; class BadController extends Controller { // your code here }
  • 39. Contrôleurs Pourquoi ce n'est pas conseillé: • Les méthodes fournies par cette classe ne sont que des raccourcis • Surtout utile pour débuter avec le framework • Cette dépendance n'est pas obligatoire • L'overhead ajouté n'apporte aucun bénéfice
  • 40. Contrôleurs Ce contrôleur est correct: <?php # Sensio/HelloBundle/Controller/Controller.php namespace SensioHelloBundle; class SimplestController { /** * @extra:Route("/hello") */ public function hello() { return new Response('Hello World'); } }
  • 41. Contrôleurs Oui, les contrôleurs peuvent être de simples objets PHP Avantages: Inconvénients: • Aucune dépendance • Aucun moyen d'accéder aux différentes fonctionnalités du framework: request, • Pas d'overhead entity_manager, etc. • Très facile à comprendre
  • 42. Contrôleurs Solution 1: Hériter de ContainerAware <?php namespace HelloBundleController; use SymfonyComponentDependencyInjectionContainerAware class GoodController extends ContainerAware { public function indexAction() { $em = $this->container->get('doctrine.orm.entity_manager'); } } Avantages: • Plus de dépendances vers Controller • Les mêmes fonctionnalités sont disponibles • Pas d'overhead
  • 43. Contrôleurs Solution 2: utiliser des services en tant que controlleurs Avantages: • Vous contrôlez vos dépendances via l'injecteur de dépendances • Vous pouvez tester unitairement vos contrôleurs
  • 44. Contrôleurs Définition d'un contrôleur via l'injecteur de dépendances • Définition du service <!-- HelloBundle/Resources/controllers.xml --> <service id="better_controller" class="HelloBundleControllerServiceController" /> • Configuration du routing my_route: defaults: { _controller: better_controller:index } • Votre contrôleur est toujours un objet PHP classique <?php namespace HelloBundleController; class ServiceController { public function indexAction() { } }
  • 45. Contrôleurs Exemple: un contrôleur ayant accès aux services suivant: • Le service de templating • L'entity manager Configuration du service: # HelloBundle/Resources/controllers.xml <service id="product_controller" class="HelloBundleControllerProductController"> <argument type="service" id="templating" /> <argument type="doctrine.orm.entity_manager" /> </service>
  • 46. Contrôleurs Implémentation du contrôleur: <?php namespace HelloBundleController; class ProductController { public function __construct(EngineInterface $templating, EntityManager $em) { $this->templating = $templating; $this->em = $em; } public function indexAction() { $products = $this->em->getRepository('HelloBundle:Product')->findAll(); return $this->templating->renderResponse( 'HelloBundle:Product:list.html.twig', array('products' => $products) ); } }
  • 48. Inclusions des assets Assets avec Symfony2 • Avec Symfony2, il n'y a plus de gestionnaire d'assets permettant d'ajouter les styles css à utiliser • Utilisez plutôt les blocs twig pour gérer vos assets. Dans votre layout de base: {# app/views/base.html.twig #} <html> <head> {%block stylesheets %}{% endblock %} </head> <body> {# ... #} {%block javascripts %}{% endblock %} </body> </html>
  • 49. Inclusions des assets Choisissez les assets à utiliser directement dans vos templates: {# HelloBundle/Resources/views/Default/index.html.twig #} {% block stylesheets %} <link href="{{ assets("bundles/hello/css/styles.css") }}" rel="stylesheet" /> {% endblock %} {% block javascripts %} <script src="{{ assets("bundles/hello/js/script.js") }}" type="text/javascript"></scr {% endblock %}
  • 50. 12: Utilisez les macros Twig
  • 51. Twig: Utilisez les macros Cas d'utilisation classique: des boutons html personnalisés Le code HTML correspondant pourrait être le suivant: <a href="#" class="button"> <span> <span> <span> Nice Button </span> </span> </span> </a>
  • 52. Twig: Utilisez les macros Réalisez un macro permettant de réutiliser facilement ce code HTML {# HelloBundle/Resources/views/macro.html.twig #} {% macro button(url, text) %} <a href="{{ url }}" class="button"> <span> <span> <span> {{ text }} </span> </span> </span> </a> {% endmacro %} Réutilisez cette macro dans vos templates: {# HelloBundle/Resources/views/Default/index.html.twig #} {% from "HelloBundle::macro.html.twig" import button %} {{ button("Nice Button!") }}
  • 54. Internationalisation Internationalisez vos projets • Parce que vous ne savez pas comment votre projet va évoluer • Parce que l'impact en terme de performances est négligeable • Parce que implémenter l'internationalisation après coup vous prendra beaucoup de temps
  • 56. 14) Apprenez à l'utiliser
  • 57. L'injecteur de dépendance est à la base du framework. Domptez-le, et vous aurez le pouvoir de Symfony2 entre vos mains!
  • 58. Apprenez à utiliser l'injecteur de dépendances Ressources sur ce sujet: • http://www.slideshare.net/fabpot • http://fabien.potencier.org/article/13/introduction-to-the-symfony-service-container • http://components.symfony-project.org/dependency-injection/
  • 59. 15) Injection de dépendences: règles de base
  • 60. Règles générales: • Les classes doivent être utilisables sans le conteneur • Seul le conteneur connait les dépendances, et pas l'inverse • Ce n'est pas LA solution à tous vos problèmes
  • 61. 16) Utilisez le format XML
  • 62. Définir vos services Utilisez le format xml pour décrire vos services: • Un peu plus verbeux • Mais beaucoup plus simple à appréhender et à comprendre • Autocomplétion dans les éditeurs XML qui le supporte
  • 63. 17) Injecteur de dépendances:
  • 64. Injecteur de dépendances Quand l'utiliser? L'injecteur de dépendances doit être utilisés pour les objets métiers qui ont une portée globale: • request • http kernel • entity manager • caching driver (memcache, apc, ...)
  • 65. 18) Quand NE PAS l'utiliser?
  • 66. Injecteur de dépendances Quand ne pas l'utiliser ? L'injecteur de dépendances ne doit pas être utilisés dans les cas suivants: • Retrouver une instance d'un objet métier (i.e. un produit dans une base de données) • Pour un objet n'ayant pas une portée globle: un objet métier n'étant utilisés que dans un controleur, par exemple
  • 67. 19) Ne pas injecter le container
  • 68. Ne pas injecter le container Il ne faut pas injecter le container dans les objets: • Cela crée une dépendance forte avec le conteneur alors que vous avez rarement la nécessité • Vous ne pourrez plus utiliser vos classes sans le conteneur <?php namespace SensioProduct class Manager { public function __construct($container) { $this->dbh = $container->get('doctrine.dbal.default_connection'); } }
  • 69. Injecteur de dépendances Injecter directement le service concerné: <?php namespace SensioProduct class Manager { public function __construct($dbh) { $this->dbh = $dbh; } }
  • 71. Sécurité Le module de sécurité est une part très spécifique de la configuration de votre projet Vous y définissez: • Comment retrouver vos utilisateurs • A quelles ressources il peuvent accéder • Comment il peuvent accéder à ces resources La bonne pratique est de définir ces informations dans un fichier spécifique
  • 72. Sécurité Exemple: # app/config/security.yml security: encoders: SymfonyComponentSecurityCoreUserUser: sha1 providers: main: users: foo: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: ROLE_USER facebook: true firewalls: main: pattern: /.* http-basic: true logout: true access_control: - { path: /admin, role: ROLE_ADMIN } - { path: /public, role: ROLE_ANONYMOUS } - { path: /.*, role: ROLE_USER }
  • 74. Profiling: Surveillez vos performances: • nombre de requêtes • temps d'exécution • mémoire utilisée
  • 75. Profiling: Surveillez également vos redirections: • Les actions réalisant des redirections font très souvent des dizaines de requêtes • En environnement de développement, Symfony2 intercepte ces redirections pour vous permettre d'analyser l'exécution
  • 76. 23) Profiling en production
  • 77. Profiling: Il arrive parfois qu'un problème survienne en production sans que vous soyez capable de comprendre le problème. • Avec symfony 1, une des solutions est d'activer le debug le temps de comprendre ce qu'il se passe. • Avec Symfony2, vous pouvez activer le profiler en production sans activer l'affichage des erreurs. Activer le profiling en production: # app/config/config_prod.yml framework: profiler: { only_exceptions: true }
  • 79. 24) Utilisez les annotations
  • 80. Utilisez les annotations Les annotations permettent de définir des comportements, des éléments de configuration, etc... <?php /** * @orm:Entity */ class User { } Ce format de configuration est très pratique: • Il permet de définir des comportements directement dans les classes concernés • Tout est centralisé: vous n'avez plus à vous rappeler dans quel fichier tel ou tel comportement est défini
  • 82. FrameworkExtraBundle Le bundle FrameworkExtraBundle vous donne accès à d'avantages d'annotations pour configurer: • Le routing • La ou les méthodes HTTP possible pour une règle de routing (GET, POST, ...) • les templates à utiliser • Le cache HTTP • Convertir des paramètres de requêtes (en entité Doctrine, par ex.)
  • 83. FrameworkExtraBundle Exemple de contrôleur: <?php class AwesomeController extends ContainerAware { /** * @extra:Route("/awesome/controller") * @extra:Method("GET") * @extra:Template("SensioHelloBundle:Default:index.html.twig") * @extra:Cache(maxage=600) */ public function indexAction() { } }
  • 86. Autoloading • L'un des goulot d'étranglement classique en PHP est l'autoloading. • Les performances exceptionnelles de Symfony2 s'expliquent en partie par des solutions visant à optimiser le chargement des classes du framework • Vous pouvez également profiter de ces améliorations pour vos projets, grâce aux extensions de l'injecteur de dépendance. <?php namespace SensioUserBundleDependencyInjection; class UserExtension extends Extension { public function load(array $config, ContainerBuilder $container) { /* ... */ $this->addClassesToCompile(array( 'SensioUserBundleModelUser' )); } }
  • 87. Autoloading Vos classes sont "compilées" dans un fichier unique: <?php # app/cache/prod/classes.php /* ... */ namespace SensioUserBundleModel { class User { /* your code */ } } Avantages: • Plus besoin de passer par l'autoloader: vos classes sont forcéments chargées à chaque requête HTTP • Moins d'accès disque pour charger les classes • Ce fichier est mis en cache par les gestionnaire d'opcode (APC, EAccelerator, XCache)
  • 88. Autoloading L'arme secrète de Symfony2 est à votre portée! • Attention : cette fonctionnalité peut avoir l'effet inverse si elle est trop utilisée
  • 90. Cache Warmer La commande cache:warmup permet de pré-compiler tous les fichiers nécessaire en cache: • Templates • Injecteur de dépendance • Routing • Autoloading $> php symfony cache:warmup
  • 91. 28) Doctrine: vérifier la configuration
  • 92. Doctrine: vérifier la configuration Une commande dédiée vous permet de vérifier la bonne configuration de Doctrine2 dans Symfony2: $> php app/console doctrine:ensure-production-settings
  • 94. Routing: Utilisez le router Apache Configurez Symfony pour utiliser le matcher Apache: # app/config/config.yml framework: router: { matcher: apache } Exportez vos règles de routing en RewriteRules: $> php app/console router:dump > rewrite.conf
  • 96. Assets Utilisez assetic pour de meilleures performances: {# HelloBundle/Resources/views/Default/index.html.twig #} {% block stylesheets %} {% stylesheet filter="yui_css", output="/css/main.css", "@HelloBundle/Resources/public/css/reset.css" "@HelloBundle/Resources/public/css/styles.css" %} <link href="{{ asset_url }}" rel="stylesheet" /> {% endstylesheet %} {% endblock %} {% block javascripts %} {% javascript filter="closure", output="/js/script.js", "@HelloBundle/Resources/public/js/jquery.js" "@HelloBundle/Resources/public/js/hello.js" %} <script src="{{ asset_url }}" type="text/javascript"></script> {% endjavascript %} {% endblock %}
  • 97. Questions ? Merci de votre attention!