97
Symfony2: 30 astuces et bonnes pratiques

Symfony2: 30 astuces et bonnes pratiques

Embed Size (px)

DESCRIPTION

Avec cette nouvelle version de votre framework préféré, de nouvelles fonctionnalités et de nouveaux usages sont apparus. Vous vous demandez comment structurer vos bundles? Comment organiser votre code source? Comment utiliser correctement l'injecteur de dépendance? Venez découvrir au cours de cette session les bonnes pratiques, et quelques astuces, qui vous aiderons dans la réalisation de vos projets avec Symfony2.

Citation preview

Page 1: Symfony2: 30 astuces et bonnes pratiques

Symfony2: 30 astuces et bonnespratiques

www.princexml.com
Prince - Non-commercial License
This document was created with Prince, a great way of getting web content onto paper.
Page 2: 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

Page 3: Symfony2: 30 astuces et bonnes pratiques

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

Page 4: Symfony2: 30 astuces et bonnes pratiques

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 niles classes métier

• Ne dupliquez pas de code

• Ne modifiez pas directement les classes du framework

• ...

Page 5: Symfony2: 30 astuces et bonnes pratiques

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

Page 6: Symfony2: 30 astuces et bonnes pratiques

1) Par où commencer?

Page 7: Symfony2: 30 astuces et bonnes pratiques

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

Page 8: Symfony2: 30 astuces et bonnes pratiques

2) Organisez vos projets!

Page 9: Symfony2: 30 astuces et bonnes pratiques

Organisation des projetsProjets

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

• La sandbox est une structure possible, respectant les bonnespratiques

• Si vous voulez que vos projets soit facilement repris en main pardifférents développeurs, gardez le modèle de la sandbox

Page 10: Symfony2: 30 astuces et bonnes pratiques

Organisation des applicationsLes applications

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

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

◦ Les classes et services sont chargés uniquement si vous lesutilisez: pas d'impact sur les performances

Page 11: Symfony2: 30 astuces et bonnes pratiques

Multi applications

• Vous pouvez avoir besoin de plusieurs applications:

◦ Projet avec beaucoup de fonctionnalités, et avec un besoincloisonnement

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

• Généralement, vous avez surtout besoin de créer un nouveauprojet

Page 12: Symfony2: 30 astuces et bonnes pratiques

Organisation en multi-applicationsExemple de projet avec plusieurs applications

/application1/Application1Kernel.php...

/application2/Application2Kernel.php...

/web/application1.phpapplication2.php...

Page 13: Symfony2: 30 astuces et bonnes pratiques

Organisation des bundlesLes bundles

• Organisez vos bundles en briques logicielles: chaque bundle est responsable d'unefonctionnalité:

◦ ForumBundle

◦ BlogBundle

◦ UserBundle

◦ ShopBundle

src/Sensio/Bundle/

UserBundle/Controller/

UserController.phpShopBundle/

Controller/OrderController.php

Page 14: Symfony2: 30 astuces et bonnes pratiques

3. Isolez vos classes métiers

Page 15: Symfony2: 30 astuces et bonnes pratiques

Isolez vos classes métiersProblé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

Page 16: Symfony2: 30 astuces et bonnes pratiques

Séparez vos classes métiers desbundles

Exemple de structure avec une séparation des classes métiers et desbundles

src/Sensio/Bundle/

UserBundle/OrderBundle/

Business/ <--------- Classes metiersForm/

User.phpValidator/

Order.phpEntity/ <--------- Entites Doctrine2

User.php

Page 17: Symfony2: 30 astuces et bonnes pratiques

Séparez vos classes métiers desbundles

Grâce à l'autoloading, vous pouvez très simplement charger des classes qui ne sont pas dans un bundle.

<?php

use Symfony\Component\ClassLoader\UniversalClassLoader;

$loader = new UniversalClassLoader();$loader->registerNamespaces(array(

'Sensio' => __DIR__.'/../src',));

$loader->register();

# in your applicationnew Sensio\Business\Form\User();

Page 18: Symfony2: 30 astuces et bonnes pratiques

Spécificité pour les entitésDoctrine2

Déclarez les mappings

Il faut indiquer à Doctrine2 où sont les entités, lorsqu'elles ne sont pas dans un bundle:

# app/config/config.ymlorm:

auto_generate_proxy_classes: %kernel.debug%mappings:

Sensio:type: annotationprefix: Sensiodir: %kernel.root_dir%/../src/Sensio/Entity

Page 19: Symfony2: 30 astuces et bonnes pratiques

4: Utilisez votre namespace

Page 20: Symfony2: 30 astuces et bonnes pratiques

Utilisez votre propre namespaceGé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{

/* ... */}

Page 21: Symfony2: 30 astuces et bonnes pratiques

5: Bibliothèque externes

Page 22: Symfony2: 30 astuces et bonnes pratiques

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

Page 23: Symfony2: 30 astuces et bonnes pratiques

6: Ne divulgez plus vos mots de passes

Page 24: Symfony2: 30 astuces et bonnes pratiques

Ne divulgez plus vos mots de passesUtilisez 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 deconfiguration

Page 25: Symfony2: 30 astuces et bonnes pratiques

Ne divulgez plus vos mots de passesConfiguration 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%

Page 26: Symfony2: 30 astuces et bonnes pratiques

7: Configuration: le format INI

Page 27: Symfony2: 30 astuces et bonnes pratiques

Le format INI

Généralement, n'utilisez pas le format INI pour vos projets:

• La syntaxe est limité

• Pas de validation

Page 28: Symfony2: 30 astuces et bonnes pratiques

Le format INILe format INI peut être utile dans certains cas

Si vous souhaitez fournir une application paramétrable à des profils peu techniques, vous pouvezutiliser le format INI.

; blog.ini[parameters]blog.admin.email = [email protected] = Noël

Importez ce fichier dans la configuration de votre bundle:

<container><imports>

<import resource="blog.ini" /></imports><services id="blog.notification.email"

class="Sensio\BlogBundle\Notification\Email"><argument key="admin_email">%blog.admin.email%</argument><argument key="admin_name">%blog.admin.name%</argument>

</services></container>

Page 29: Symfony2: 30 astuces et bonnes pratiques

8: Utilisez Twig

Page 30: Symfony2: 30 astuces et bonnes pratiques

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

Page 31: Symfony2: 30 astuces et bonnes pratiques

9: Surchargez les pages d'erreurs

Page 32: Symfony2: 30 astuces et bonnes pratiques

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

Page 33: Symfony2: 30 astuces et bonnes pratiques

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 knowwhat you were doing when this error occurred. We will fix it as soonas possible. Sorry for any inconvenience caused.

</div></body>

</html>

Page 34: Symfony2: 30 astuces et bonnes pratiques

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: Sensio\HelloBundle\Controller\ErrorController

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

<?php

namespace Sensio\HelloBundle\Controller;

class ErrorController extends ContainerAware{

public function showAction(FlattenException $exception){

// do whatever you want here

return new Response(/* ... */);}

}

Page 35: Symfony2: 30 astuces et bonnes pratiques

Surcharge des pages d'erreurs

• Si vous voulez complètement surcharger le mécanismed'exception de symfony, vous pouvez utiliser un service

• Ce service doit écouter l'évènement core.exception

Page 36: Symfony2: 30 astuces et bonnes pratiques

Surcharge des pages d'erreursDéclaration du service

<service id="sensio.error_handle" class="Sensio\Error\ExceptionHandler"><tag name="kernel.listener"

event="core.exception"method="handleException"priority="-128"

/></service>

Implémentation du service

<?php

namespace Sensio\Error;

class ExceptionHandler{

public function handleException(EventInterface $event){

$exception = $event->get('exception');// do whatever you want here

return new Response(/* ... */);}

}

Page 37: Symfony2: 30 astuces et bonnes pratiques

10) Contrôleurs

Page 38: Symfony2: 30 astuces et bonnes pratiques

ContrôleursLes contrôleurs ne doivent pas hériter de la classe Controller duFrameworkBundle.

<?php

namespace HelloBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BadController extends Controller{

// your code here}

Page 39: Symfony2: 30 astuces et bonnes pratiques

ContrôleursPourquoi ce n'est pas conseillé:

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

• Surtout utile pour débuter avec le framework

• Cette dépendance n'est pas obligatoire

• L'overhead ajouté n'apporte aucun bénéfice

Page 40: Symfony2: 30 astuces et bonnes pratiques

ContrôleursCe contrôleur est correct:

<?php# Sensio/HelloBundle/Controller/Controller.phpnamespace Sensio\HelloBundle;

class SimplestController{

/*** @extra:Route("/hello")*/public function hello(){

return new Response('Hello World');}

}

Page 41: Symfony2: 30 astuces et bonnes pratiques

ContrôleursOui, les contrôleurs peuvent être de simples objets PHP

Avantages:

• Aucune dépendance

• Pas d'overhead

• Très facile à comprendre

Inconvénients:

• Aucun moyen d'accéder aux différentesfonctionnalités du framework: request,entity_manager, etc.

Page 42: Symfony2: 30 astuces et bonnes pratiques

ContrôleursSolution 1: Hériter de ContainerAware

<?php

namespace HelloBundle\Controller;

use Symfony\Component\DependencyInjection\ContainerAware

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

Page 43: Symfony2: 30 astuces et bonnes pratiques

ContrôleursSolution 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

Page 44: Symfony2: 30 astuces et bonnes pratiques

ContrôleursDéfinition d'un contrôleur via l'injecteur de dépendances

• Définition du service

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

• Configuration du routing

my_route:defaults: { _controller: better_controller:index }

• Votre contrôleur est toujours un objet PHP classique

<?phpnamespace HelloBundle\Controller;

class ServiceController{

public function indexAction(){}

}

Page 45: Symfony2: 30 astuces et bonnes pratiques

ContrôleursExemple: 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="HelloBundle\Controller\ProductController">

<argument type="service" id="templating" /><argument type="doctrine.orm.entity_manager" />

</service>

Page 46: Symfony2: 30 astuces et bonnes pratiques

ContrôleursImplémentation du contrôleur:

<?php

namespace HelloBundle\Controller;

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)

);}

}

Page 47: Symfony2: 30 astuces et bonnes pratiques

11: Inclusion des assets

Page 48: Symfony2: 30 astuces et bonnes pratiques

Inclusions des assetsAssets 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>

Page 49: Symfony2: 30 astuces et bonnes pratiques

Inclusions des assetsChoisissez 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"></script>

{% endblock %}

Page 50: Symfony2: 30 astuces et bonnes pratiques

12: Utilisez les macros Twig

Page 51: Symfony2: 30 astuces et bonnes pratiques

Twig: Utilisez les macrosCas 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>

Page 52: Symfony2: 30 astuces et bonnes pratiques

Twig: Utilisez les macrosRéalisez un macro permettant de réutiliser facilement ce codeHTML

{# 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!") }}

Page 53: Symfony2: 30 astuces et bonnes pratiques

13: Internationalisation

Page 54: Symfony2: 30 astuces et bonnes pratiques

InternationalisationInternationalisez 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

Page 55: Symfony2: 30 astuces et bonnes pratiques

Injection de dépendance

Page 56: Symfony2: 30 astuces et bonnes pratiques

14) Apprenez à l'utiliser

Page 57: Symfony2: 30 astuces et bonnes pratiques

L'injecteur de dépendance est à la base du framework.

Domptez-le, et vous aurez le pouvoir de Symfony2 entre vosmains!

Page 58: Symfony2: 30 astuces et bonnes pratiques

Apprenez à utiliser l'injecteur dedé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/

Page 59: Symfony2: 30 astuces et bonnes pratiques

15) Injection de dépendences: règles de

base

Page 60: Symfony2: 30 astuces et bonnes pratiques

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

Page 61: Symfony2: 30 astuces et bonnes pratiques

16) Utilisez le format XML

Page 62: Symfony2: 30 astuces et bonnes pratiques

Définir vos servicesUtilisez 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

Page 63: Symfony2: 30 astuces et bonnes pratiques

17) Injecteur de dépendances:

Page 64: Symfony2: 30 astuces et bonnes pratiques

Injecteur de dépendancesQuand l'utiliser?L'injecteur de dépendances doit être utilisés pour les objetsmétiers qui ont une portée globale:

• request

• http kernel

• entity manager

• caching driver (memcache, apc, ...)

Page 65: Symfony2: 30 astuces et bonnes pratiques

18) Quand NE PAS l'utiliser?

Page 66: Symfony2: 30 astuces et bonnes pratiques

Injecteur de dépendancesQuand ne pas l'utiliser ?L'injecteur de dépendances ne doit pas être utilisés dans lescas suivants:

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

• Pour un objet n'ayant pas une portée globle: un objet métiern'étant utilisés que dans un controleur, par exemple

Page 67: Symfony2: 30 astuces et bonnes pratiques

19) Ne pas injecter le container

Page 68: Symfony2: 30 astuces et bonnes pratiques

Ne pas injecter le containerIl 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 Sensio\Product

class Manager{

public function __construct($container){

$this->dbh = $container->get('doctrine.dbal.default_connection');}

}

Page 69: Symfony2: 30 astuces et bonnes pratiques

Injecteur de dépendancesInjecter directement le service concerné:

<?php

namespace Sensio\Product

class Manager{

public function __construct($dbh){

$this->dbh = $dbh;}

}

Page 70: Symfony2: 30 astuces et bonnes pratiques

21) Sécurité

Page 71: Symfony2: 30 astuces et bonnes pratiques

SécuritéLe module de sécurité est une part très spécifique de laconfiguration 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

Page 72: Symfony2: 30 astuces et bonnes pratiques

SécuritéExemple:

# app/config/security.ymlsecurity:

encoders:Symfony\Component\Security\Core\User\User: sha1

providers:main:

users:foo: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: ROLE_USER }

facebook: true

firewalls:main:

pattern: /.*http-basic: truelogout: true

access_control:- { path: /admin, role: ROLE_ADMIN }- { path: /public, role: ROLE_ANONYMOUS }- { path: /.*, role: ROLE_USER }

Page 73: Symfony2: 30 astuces et bonnes pratiques

22) Profiling

Page 74: Symfony2: 30 astuces et bonnes pratiques

Profiling:Surveillez vos performances:

• nombre de requêtes

• temps d'exécution

• mémoire utilisée

Page 75: Symfony2: 30 astuces et bonnes pratiques

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 permettred'analyser l'exécution

Page 76: Symfony2: 30 astuces et bonnes pratiques

23) Profiling en production

Page 77: Symfony2: 30 astuces et bonnes pratiques

Profiling:

Il arrive parfois qu'un problème survienne en production sans quevous soyez capable de comprendre le problème.

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

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

Activer le profiling en production:

# app/config/config_prod.ymlframework:

profiler: { only_exceptions: true }

Page 78: Symfony2: 30 astuces et bonnes pratiques

Profiling:Importer un dump

Page 79: Symfony2: 30 astuces et bonnes pratiques

24) Utilisez les annotations

Page 80: Symfony2: 30 astuces et bonnes pratiques

Utilisez les annotationsLes 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 estdéfini

Page 81: Symfony2: 30 astuces et bonnes pratiques

25) FrameworkExtraBundle

Page 82: Symfony2: 30 astuces et bonnes pratiques

FrameworkExtraBundle

Le bundle FrameworkExtraBundle vous donne accès à d'avantagesd'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, parex.)

Page 83: Symfony2: 30 astuces et bonnes pratiques

FrameworkExtraBundleExemple 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(){

}}

Page 84: Symfony2: 30 astuces et bonnes pratiques

Performances

Optimisez vos performances grâce à Symfony2.

Page 85: Symfony2: 30 astuces et bonnes pratiques

26) Optimisez l'autoloading

Page 86: Symfony2: 30 astuces et bonnes pratiques

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 del'injecteur de dépendance.

<?php

namespace Sensio\UserBundle\DependencyInjection;

class UserExtension extends Extension{

public function load(array $config, ContainerBuilder $container){

/* ... */

$this->addClassesToCompile(array('Sensio\UserBundle\Model\User'

));}

}

Page 87: Symfony2: 30 astuces et bonnes pratiques

AutoloadingVos classes sont "compilées" dans un fichier unique:

<?php

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

namespace Sensio\UserBundle\Model {class User {

/* your code */}

}

Avantages:

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

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

• Ce fichier est mis en cache par les gestionnaire d'opcode (APC, EAccelerator, XCache)

Page 88: Symfony2: 30 astuces et bonnes pratiques

Autoloading

L'arme secrète de Symfony2 est à votre portée!

• Attention : cette fonctionnalité peut avoir l'effet inverse si elleest trop utilisée

Page 89: Symfony2: 30 astuces et bonnes pratiques

27) Cache Warmer

Page 90: Symfony2: 30 astuces et bonnes pratiques

Cache WarmerLa 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

Page 91: Symfony2: 30 astuces et bonnes pratiques

28) Doctrine: vérifier laconfiguration

Page 92: Symfony2: 30 astuces et bonnes pratiques

Doctrine: vérifier la configuration

Une commande dédiée vous permet de vérifier la bonneconfiguration de Doctrine2 dans Symfony2:

$> php app/console doctrine:ensure-production-settings

Page 93: Symfony2: 30 astuces et bonnes pratiques

29) Routing

Page 94: Symfony2: 30 astuces et bonnes pratiques

Routing: Utilisez le router ApacheConfigurez 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

Page 95: Symfony2: 30 astuces et bonnes pratiques

30) Assets

Page 96: Symfony2: 30 astuces et bonnes pratiques

AssetsUtilisez 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 %}

Page 97: Symfony2: 30 astuces et bonnes pratiques

Questions ?Merci de votre attention!