$30 off During Our Annual Pro Sale. View Details »

Symfony 2, un framework robuste et moderne

ubermuda
September 06, 2012

Symfony 2, un framework robuste et moderne

Présentation du framework PHP 5 Symfony 2

ubermuda

September 06, 2012
Tweet

More Decks by ubermuda

Other Decks in Technology

Transcript

  1. Un framework PHP robuste et moderne
    Geoffrey Bachelet – Pandanova
    mercredi 5 septembre 12

    View Slide

  2. HTTP
    MVC
    INJECTION DE DÉPENDANCE
    COMPOSANTS
    BUNDLES
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  3. HTTP
    mercredi 5 septembre 12

    View Slide

  4. HTTP
    Quel est le cycle de vie d’une page web ?
    mercredi 5 septembre 12

    View Slide

  5. Requête Réponse
    HTTP
    mercredi 5 septembre 12

    View Slide

  6. Requête Réponse
    Application
    HTTP
    mercredi 5 septembre 12

    View Slide

  7. Requête Réponse
    Application
    GET
    HTTP
    mercredi 5 septembre 12

    View Slide

  8. Requête Réponse
    Application
    GET
    POST
    HTTP
    mercredi 5 septembre 12

    View Slide

  9. Requête Réponse
    Application
    GET
    POST
    PUT
    HTTP
    mercredi 5 septembre 12

    View Slide

  10. Requête Réponse
    Application
    GET
    POST
    PUT
    DELETE
    HTTP
    mercredi 5 septembre 12

    View Slide

  11. Requête Réponse
    Application
    GET
    POST
    PUT
    DELETE
    ...
    HTTP
    mercredi 5 septembre 12

    View Slide

  12. Requête Réponse
    Application
    GET
    POST
    PUT
    DELETE
    ...
    HTML
    HTTP
    mercredi 5 septembre 12

    View Slide

  13. Requête Réponse
    Application
    GET
    POST
    PUT
    DELETE
    ...
    HTML
    XML
    HTTP
    mercredi 5 septembre 12

    View Slide

  14. Requête Réponse
    Application
    GET
    POST
    PUT
    DELETE
    ...
    HTML
    XML
    JSON
    HTTP
    mercredi 5 septembre 12

    View Slide

  15. Requête Réponse
    Application
    GET
    POST
    PUT
    DELETE
    ...
    HTML
    XML
    JSON
    ...
    HTTP
    mercredi 5 septembre 12

    View Slide

  16. Tirer parti du protocole HTTP
    HTTP
    mercredi 5 septembre 12

    View Slide

  17. Codes d’état (200, 404, ...)
    Tirer parti du protocole HTTP
    HTTP
    mercredi 5 septembre 12

    View Slide

  18. Codes d’état (200, 404, ...)
    Redirections
    Tirer parti du protocole HTTP
    HTTP
    mercredi 5 septembre 12

    View Slide

  19. Codes d’état (200, 404, ...)
    Redirections
    Verbes (GET, POST, ...)
    Tirer parti du protocole HTTP
    HTTP
    mercredi 5 septembre 12

    View Slide

  20. Codes d’état (200, 404, ...)
    Redirections
    Verbes (GET, POST, ...)
    Cache (etags, validation, ...)
    Tirer parti du protocole HTTP
    HTTP
    mercredi 5 septembre 12

    View Slide

  21. Codes d’état (200, 404, ...)
    Redirections
    Verbes (GET, POST, ...)
    Cache (etags, validation, ...)
    Négociation de contenu
    Tirer parti du protocole HTTP
    HTTP
    mercredi 5 septembre 12

    View Slide

  22. Codes d’état (200, 404, ...)
    Redirections
    Verbes (GET, POST, ...)
    Cache (etags, validation, ...)
    Négociation de contenu
    ...
    Tirer parti du protocole HTTP
    HTTP
    mercredi 5 septembre 12

    View Slide

  23. Documentation :
    http://symfony.com/doc/current/book/http_fundamentals.html
    Composant :
    http://symfony.com/doc/current/components/http_foundation/
    introduction.html
    HTTP
    mercredi 5 septembre 12

    View Slide

  24. MVC
    mercredi 5 septembre 12

    View Slide

  25. MVC
    mercredi 5 septembre 12

    View Slide

  26. La couche modèle
    MVC
    mercredi 5 septembre 12

    View Slide

  27. /** @Entity **/
    class Post
    {
    /** @Id @GeneratedValue @Column(type="integer") **/
    protected $id;
    /** @Column(type="string") **/
    protected $title;
    /** @Column(type="text") **/
    protected $body;
    public function getAbbrTitle()
    {
    return substr($this->title, 0, 15);
    }
    } http://doctrine-project.org/
    MVC
    mercredi 5 septembre 12

    View Slide

  28. /** @Entity **/
    class Post
    {
    /** @Id @GeneratedValue @Column(type="integer") **/
    protected $id;
    /** @Column(type="string") **/
    protected $title;
    /** @Column(type="text") **/
    protected $body;
    public function getAbbrTitle()
    {
    return substr($this->title, 0, 15);
    }
    } http://doctrine-project.org/
    MVC
    Données
    mercredi 5 septembre 12

    View Slide

  29. /** @Entity **/
    class Post
    {
    /** @Id @GeneratedValue @Column(type="integer") **/
    protected $id;
    /** @Column(type="string") **/
    protected $title;
    /** @Column(type="text") **/
    protected $body;
    public function getAbbrTitle()
    {
    return substr($this->title, 0, 15);
    }
    } http://doctrine-project.org/
    MVC
    Métier
    mercredi 5 septembre 12

    View Slide




  30. name="id"
    type="integer"
    required="true"
    primaryKey="true"
    autoIncrement="true"
    />




    http://propelorm.org/
    MVC
    mercredi 5 septembre 12

    View Slide




  31. name="id"
    type="integer"
    required="true"
    primaryKey="true"
    autoIncrement="true"
    />




    http://propelorm.org/
    MVC
    Données
    mercredi 5 septembre 12

    View Slide

  32. /**
    * Skeleton subclass for representing a row from the 'user' table.
    *
    * You should add additional methods to this class to meet the
    * application requirements. This class will only be generated as
    * long as it does not already exist in the output directory.
    */
    class Post extends BasePost
    {
    public function getAbbrTitle()
    {
    return substr($this->title, 0, 15);
    }
    }
    http://propelorm.org/
    MVC
    mercredi 5 septembre 12

    View Slide

  33. /**
    * Skeleton subclass for representing a row from the 'user' table.
    *
    * You should add additional methods to this class to meet the
    * application requirements. This class will only be generated as
    * long as it does not already exist in the output directory.
    */
    class Post extends BasePost
    {
    public function getAbbrTitle()
    {
    return substr($this->title, 0, 15);
    }
    }
    http://propelorm.org/
    MVC
    Métier
    mercredi 5 septembre 12

    View Slide

  34. La couche vue
    MVC
    mercredi 5 septembre 12

    View Slide

  35. {% extends 'layout.html.twig' %}
    {% for post in posts %}

    {{ post.title }}

    {{ post.body | markdown }}


    {% endfor %}
    Twig
    http://twig.sensiolabs.org/
    MVC
    mercredi 5 septembre 12

    View Slide

  36. {% extends 'layout.html.twig' %}
    {% for post in posts %}

    {{ post.title }}

    {{ post.body | markdown }}


    {% endfor %}
    http://twig.sensiolabs.org/
    MVC
    Layout
    mercredi 5 septembre 12

    View Slide

  37. {% extends 'layout.html.twig' %}
    {% for post in posts %}

    {{ post.title }}

    {{ post.body | markdown }}


    {% endfor %}
    http://twig.sensiolabs.org/
    MVC
    Boucles
    mercredi 5 septembre 12

    View Slide

  38. {% extends 'layout.html.twig' %}
    {% for post in posts %}

    {{ post.title }}

    {{ post.body | markdown }}


    {% endfor %}
    http://twig.sensiolabs.org/
    MVC
    Variables
    mercredi 5 septembre 12

    View Slide

  39. {% extends 'layout.html.twig' %}
    {% for post in posts %}

    {{ post.title }}

    {{ post.body | markdown }}


    {% endfor %}
    http://twig.sensiolabs.org/
    MVC
    Filtres
    mercredi 5 septembre 12

    View Slide

  40. Le contrôleur
    MVC
    mercredi 5 septembre 12

    View Slide

  41. namespace MyBundle\Controller;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    class PostController extends Controller
    {
    public function listAction()
    {
    return $this->render('MyBundle:Post:list', array(
    'posts' => PostQuery::create()->find()
    ));
    }
    }
    MVC
    mercredi 5 septembre 12

    View Slide

  42. namespace MyBundle\Controller;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    class PostController extends Controller
    {
    public function listAction()
    {
    return $this->render('MyBundle:Post:list', array(
    'posts' => PostQuery::create()->find()
    ));
    }
    }
    MVC
    Template
    mercredi 5 septembre 12

    View Slide

  43. namespace MyBundle\Controller;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    class PostController extends Controller
    {
    public function listAction()
    {
    return $this->render('MyBundle:Post:list', array(
    'posts' => PostQuery::create()->find()
    ));
    }
    }
    MVC
    Données
    mercredi 5 septembre 12

    View Slide

  44. Logique métier encapsulée
    Facilement testable
    Facilement maintenable
    MVC
    mercredi 5 septembre 12

    View Slide

  45. INJECTION DE DÉPENDANCE
    mercredi 5 septembre 12

    View Slide

  46. class User
    {
    public function __construct()
    {
    $this->storage = new SessionStorage('SESSION_ID');
    }
    public function setLanguage($language)
    {
    $this->storage->set('language', $language);
    }
    }
    $user = new User();
    INJECTION DE DÉPENDANCE
    mercredi 5 septembre 12

    View Slide

  47. class User
    {
    public function __construct()
    {
    $this->storage = new SessionStorage('SESSION_ID');
    }
    public function setLanguage($language)
    {
    $this->storage->set('language', $language);
    }
    }
    $user = new User();
    INJECTION DE DÉPENDANCE
    Dépendance
    forte
    mercredi 5 septembre 12

    View Slide

  48. class User
    {
    private $storage;
    public function __construct(StorageInterface $storage)
    {
    $this->storage = $storage;
    }
    }
    $storage = new SessionStorage('SESSION_ID');
    $user = new User($storage);
    INJECTION DE DÉPENDANCE
    Injection
    mercredi 5 septembre 12

    View Slide

  49. class User
    {
    private $storage;
    public function __construct(StorageInterface $storage)
    {
    $this->storage = $storage;
    }
    }
    $storage = new SessionStorage('my_session_name');
    $user = new User($storage);
    INJECTION DE DÉPENDANCE
    mercredi 5 septembre 12

    View Slide

  50. class User
    {
    private $storage;
    public function __construct(StorageInterface $storage)
    {
    $this->storage = $storage;
    }
    }
    $storage = new MemcacheStorage();
    $user = new User($storage);
    INJECTION DE DÉPENDANCE
    mercredi 5 septembre 12

    View Slide

  51. class User
    {
    private $storage;
    public function __construct(StorageInterface $storage)
    {
    $this->storage = $storage;
    }
    }
    $storage = new MemcacheStorage($memcacheClient);
    $user = new User($storage);
    INJECTION DE DÉPENDANCE
    mercredi 5 septembre 12

    View Slide

  52. http://www.slideshare.net/fabpot/dependency-injection-in-php-5354
    Flexible
    Configurable
    Découplé
    INJECTION DE DÉPENDANCE
    mercredi 5 septembre 12

    View Slide

  53. COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  54. COMPOSANTS
    ClassLoader
    Config
    Console
    DependencyInjection
    EventDispatcher
    Finder
    Form
    HttpFoundation
    Locale
    Process
    Routing
    Security
    Templating
    Validation
    YAML
    ...
    mercredi 5 septembre 12

    View Slide

  55. CLASSLOADER
    mercredi 5 septembre 12

    View Slide

  56. CLASSLOADER
    “Autoloading” respectant le standard PSR-0
    https://github.com/php-fig/fig-standards/blob/master/accepted/
    PSR-0.md
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  57. CLASSLOADER
    $loader = new UniversalClassLoader();
    $loader->registerNamespaces(array(
    'Symfony' => __DIR__.'/../vendor/symfony/src',
    'Monolog' => __DIR__.'/../vendor/monolog/src',
    ));
    $loader->registerPrefixes(array(
    'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes',
    'Twig_' => __DIR__.'/vendor/twig/lib',
    ));
    $loader->register();
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  58. CLASSLOADER
    $loader = new UniversalClassLoader();
    $loader->registerNamespaces(array(
    'Symfony' => __DIR__.'/../vendor/symfony/src',
    'Monolog' => __DIR__.'/../vendor/monolog/src',
    ));
    $loader->registerPrefixes(array(
    'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes',
    'Twig_' => __DIR__.'/vendor/twig/lib',
    ));
    $loader->register();
    COMPOSANTS
    Namespaces
    mercredi 5 septembre 12

    View Slide

  59. CLASSLOADER
    $loader = new UniversalClassLoader();
    $loader->registerNamespaces(array(
    'Symfony' => __DIR__.'/../vendor/symfony/src',
    'Monolog' => __DIR__.'/../vendor/monolog/src',
    ));
    $loader->registerPrefixes(array(
    'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes',
    'Twig_' => __DIR__.'/vendor/twig/lib',
    ));
    $loader->register();
    COMPOSANTS
    Préfixes
    mercredi 5 septembre 12

    View Slide

  60. CONFIG
    mercredi 5 septembre 12

    View Slide

  61. CONFIG
    Gestion avancée de configuration
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  62. CONFIG
    Gestion avancée de configuration
    Chargement de fichiers de configuration
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  63. CONFIG
    Gestion avancée de configuration
    Chargement de fichiers de configuration
    Mise en cache de la configuration
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  64. CONFIG
    Gestion avancée de configuration
    Chargement de fichiers de configuration
    Mise en cache de la configuration
    Définition du format de configuration
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  65. CONFIG
    Gestion avancée de configuration
    Chargement de fichiers de configuration
    Mise en cache de la configuration
    Définition du format de configuration
    Multi-source (fichiers, base de données)
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  66. CONFIG
    Gestion avancée de configuration
    Chargement de fichiers de configuration
    Mise en cache de la configuration
    Définition du format de configuration
    Multi-source (fichiers, base de données)
    Multi-format (YAML, XML, JSON)
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  67. CONSOLE
    mercredi 5 septembre 12

    View Slide

  68. CONSOLE
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  69. CONSOLE
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  70. CONSOLE
    options
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  71. CONSOLE
    options argument
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  72. CONSOLE
    options argument
    valeur par défaut
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  73. DEPENDENCYINJECTION
    mercredi 5 septembre 12

    View Slide

  74. DEPENDENCYINJECTION
    parameters:
    mailer.transport: sendmail
    services:
    mailer:
    class: Mailer
    arguments: [%mailer.transport%]
    newsletter_manager:
    class: NewsletterManager
    calls:
    - [ setMailer, [ @mailer ] ]
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  75. DEPENDENCYINJECTION
    parameters:
    mailer.transport: sendmail
    services:
    mailer:
    class: Mailer
    arguments: [%mailer.transport%]
    newsletter_manager:
    class: NewsletterManager
    calls:
    - [ setMailer, [ @mailer ] ]
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  76. DEPENDENCYINJECTION
    parameters:
    mailer.transport: sendmail
    services:
    mailer:
    class: Mailer
    arguments: [%mailer.transport%]
    newsletter_manager:
    class: NewsletterManager
    calls:
    - [ setMailer, [ @mailer ] ]
    COMPOSANTS
    Paramètre
    mercredi 5 septembre 12

    View Slide

  77. DEPENDENCYINJECTION
    parameters:
    mailer.transport: sendmail
    services:
    mailer:
    class: Mailer
    arguments: [%mailer.transport%]
    newsletter_manager:
    class: NewsletterManager
    calls:
    - [ setMailer, [ @mailer ] ]
    COMPOSANTS
    Service
    mercredi 5 septembre 12

    View Slide

  78. DEPENDENCYINJECTION
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
    $container = new ContainerBuilder();
    $loader = new YamlFileLoader($container, new FileLocator(__DIR__));
    $loader->load('services.yml');
    $manager = $container->get('newsletter_manager');
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  79. DEPENDENCYINJECTION
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
    $container = new ContainerBuilder();
    $loader = new YamlFileLoader($container, new FileLocator(__DIR__));
    $loader->load('services.yml');
    $manager = $container->get('newsletter_manager');
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  80. EVENTDISPATCHER
    mercredi 5 septembre 12

    View Slide

  81. EVENTDISPATCHER
    Implémentation du design pattern “Observer”
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  82. EVENTDISPATCHER
    use Symfony\Component\EventDispatcher\EventDispatcher;
    use Symfony\Component\EventDispatcher\Event;
    $dispatcher = new EventDispatcher();
    $dispatcher->addListener('foo.action', function (Event $event) {
    // will be executed when the foo.action event is dispatched
    });
    $dispatcher->dispatch('foo.action', new Event());
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  83. EVENTDISPATCHER
    use Symfony\Component\EventDispatcher\EventDispatcher;
    use Symfony\Component\EventDispatcher\Event;
    $dispatcher = new EventDispatcher();
    $dispatcher->addListener('foo.action', function (Event $event) {
    // will be executed when the foo.action event is dispatched
    });
    $dispatcher->dispatch('foo.action', new Event());
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  84. EVENTDISPATCHER
    use Symfony\Component\EventDispatcher\EventDispatcher;
    use Symfony\Component\EventDispatcher\Event;
    $dispatcher = new EventDispatcher();
    $dispatcher->addListener('foo.action', function (Event $event) {
    // will be executed when the foo.action event is dispatched
    });
    $dispatcher->dispatch('foo.action', new Event());
    COMPOSANTS
    Listener
    mercredi 5 septembre 12

    View Slide

  85. EVENTDISPATCHER
    use Symfony\Component\EventDispatcher\EventDispatcher;
    use Symfony\Component\EventDispatcher\Event;
    $dispatcher = new EventDispatcher();
    $dispatcher->addListener('foo.action', function (Event $event) {
    // will be executed when the foo.action event is dispatched
    });
    $dispatcher->dispatch('foo.action', new Event());
    COMPOSANTS
    Événement
    mercredi 5 septembre 12

    View Slide

  86. FINDER
    mercredi 5 septembre 12

    View Slide

  87. FINDER
    use Symfony\Component\Finder\Finder;
    $finder = new Finder();
    $finder->files()->in(__DIR__);
    foreach ($finder as $file) {
    // Print the absolute path
    print $file->getRealpath()."\n";
    // Print the relative path to the file, omitting the filename
    print $file->getRelativePath()."\n";
    // Print the relative path to the file
    print $file->getRelativePathname()."\n";
    }
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  88. FINDER
    use Symfony\Component\Finder\Finder;
    $finder = new Finder();
    $finder->files()->in(__DIR__);
    foreach ($finder as $file) {
    // Print the absolute path
    print $file->getRealpath()."\n";
    // Print the relative path to the file, omitting the filename
    print $file->getRelativePath()."\n";
    // Print the relative path to the file
    print $file->getRelativePathname()."\n";
    }
    SplFileInfo
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  89. FINDER
    use Symfony\Component\Finder\Finder;
    $finder = new Finder();
    $finder->files()->in(__DIR__);
    foreach ($finder as $file) {
    // Print the absolute path
    print $file->getRealpath()."\n";
    // Print the relative path to the file, omitting the filename
    print $file->getRelativePath()."\n";
    // Print the relative path to the file
    print $file->getRelativePathname()."\n";
    }
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  90. FINDER
    use Symfony\Component\Finder\Finder;
    $finder = new Finder();
    $finder->files()->in(__DIR__);
    foreach ($finder as $file) {
    // Print the absolute path
    print $file->getRealpath()."\n";
    // Print the relative path to the file, omitting the filename
    print $file->getRelativePath()."\n";
    // Print the relative path to the file
    print $file->getRelativePathname()."\n";
    }
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  91. FINDER
    use Symfony\Component\Finder\Finder;
    $finder = new Finder();
    $finder->files()->in(__DIR__);
    foreach ($finder as $file) {
    // Print the absolute path
    print $file->getRealpath()."\n";
    // Print the relative path to the file, omitting the filename
    print $file->getRelativePath()."\n";
    // Print the relative path to the file
    print $file->getRelativePathname()."\n";
    }
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  92. FINDER
    Recherche dans plusieurs répertoires
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  93. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  94. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    Recherche sur masques de fichiers
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  95. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    Recherche sur masques de fichiers
    Recherche par taille
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  96. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    Recherche sur masques de fichiers
    Recherche par taille
    Recherche par date
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  97. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    Recherche sur masques de fichiers
    Recherche par taille
    Recherche par date
    Tri standard (nom, type)
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  98. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    Recherche sur masques de fichiers
    Recherche par taille
    Recherche par date
    Tri standard (nom, type)
    Tri personnalisé (“callback”)
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  99. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    Recherche sur masques de fichiers
    Recherche par taille
    Recherche par date
    Tri standard (nom, type)
    Tri personnalisé (“callback”)
    Compatible avec les “streams” PHP
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  100. FINDER
    Recherche dans plusieurs répertoires
    Exclusion de répertoire
    Recherche sur masques de fichiers
    Recherche par taille
    Recherche par date
    Tri standard (nom, type)
    Tri personnalisé (“callback”)
    Compatible avec les “streams” PHP
    ...
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  101. FORM
    mercredi 5 septembre 12

    View Slide

  102. FORM
    Gestion de formulaires complexes
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  103. FORM
    Gestion de formulaires complexes
    Rendu personnalisable via Twig
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  104. FORM
    Gestion de formulaires complexes
    Rendu personnalisable via Twig
    Validation des données
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  105. FORM
    Gestion de formulaires complexes
    Rendu personnalisable via Twig
    Validation des données
    Encore en beta (prévu pour la 2.1)
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  106. COMPOSANTS
    ClassLoader
    Config
    Console
    DependencyInjection
    EventDispatcher
    Finder
    Form
    HttpFoundation
    Locale
    Process
    Routing
    Security
    Templating
    Validation
    YAML
    ...
    mercredi 5 septembre 12

    View Slide

  107. “Il y a un composant pour ça”
    http://symfony.com/doc/current/components/index.html
    COMPOSANTS
    mercredi 5 septembre 12

    View Slide

  108. BUNDLES
    mercredi 5 septembre 12

    View Slide

  109. BUNDLES
    “Tout est Bundle !”
    mercredi 5 septembre 12

    View Slide

  110. BUNDLES
    mercredi 5 septembre 12

    View Slide

  111. BUNDLES
    Bundle
    mercredi 5 septembre 12

    View Slide

  112. BUNDLES
    Bundle
    mercredi 5 septembre 12

    View Slide

  113. BUNDLES
    Bundle
    mercredi 5 septembre 12

    View Slide

  114. BUNDLES
    Bundle
    mercredi 5 septembre 12

    View Slide

  115. Un Bundle peut contenir :
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  116. Un Bundle peut contenir :
    Des extensions pour l’injection de dépendance
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  117. Un Bundle peut contenir :
    Des extensions pour l’injection de dépendance
    Des contrôleurs
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  118. Un Bundle peut contenir :
    Des extensions pour l’injection de dépendance
    Des contrôleurs
    Des gabarits Twig
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  119. Un Bundle peut contenir :
    Des extensions pour l’injection de dépendance
    Des contrôleurs
    Des gabarits Twig
    La couche modèle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  120. Un Bundle peut contenir :
    Des extensions pour l’injection de dépendance
    Des contrôleurs
    Des gabarits Twig
    La couche modèle
    Tout le nécessaire pour votre application
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  121. Un moyen efficace de structurer du code
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  122. Un moyen efficace de partager du code
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  123. BUNDLES
    mercredi 5 septembre 12

    View Slide

  124. BUNDLES
    1611 Bundles !
    mercredi 5 septembre 12

    View Slide

  125. AsseticBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  126. AsseticBundle
    AvalancheImagineBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  127. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  128. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  129. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    FOSUserBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  130. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    FOSUserBundle
    GravatarBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  131. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    FOSUserBundle
    GravatarBundle
    HWIOAuthBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  132. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    FOSUserBundle
    GravatarBundle
    HWIOAuthBundle
    KnpMenuBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  133. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    FOSUserBundle
    GravatarBundle
    HWIOAuthBundle
    KnpMenuBundle
    KnpRadBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  134. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    FOSUserBundle
    GravatarBundle
    HWIOAuthBundle
    KnpMenuBundle
    KnpRadBundle
    RabbitMqBundle
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  135. AsseticBundle
    AvalancheImagineBundle
    FOSCommentBundle
    FOSRestBundle
    FOSUserBundle
    GravatarBundle
    HWIOAuthBundle
    KnpMenuBundle
    KnpRadBundle
    RabbitMqBundle
    ...
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  136. “Il y a un Bundle pour ça !”
    http://knpbundles.com/
    BUNDLES
    mercredi 5 septembre 12

    View Slide

  137. CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  138. CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  139. // src/Acme/DemoBundle/Tests/Utility/CalculatorTest.php
    namespace Acme\DemoBundle\Tests\Utility;
    use Acme\DemoBundle\Utility\Calculator;
    class CalculatorTest extends \PHPUnit_Framework_TestCase
    {
    public function testAdd()
    {
    $calc = new Calculator();
    $result = $calc->add(30, 12);
    // assert that our calculator added the numbers correctly!
    $this->assertEquals(42, $result);
    }
    }
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  140. CONTRÔLE QUALITÉ
    Barre verte !
    mercredi 5 septembre 12

    View Slide

  141. CONTRÔLE QUALITÉ
    Seulement une partie des tests
    mercredi 5 septembre 12

    View Slide

  142. http://phpunit.de/
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  143. Tests fonctionnels
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  144. // src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php
    namespace Acme\DemoBundle\Tests\Controller;
    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
    class DemoControllerTest extends WebTestCase
    {
    public function testIndex()
    {
    $client = static::createClient();
    $crawler = $client->request('GET', '/demo/hello/Fabien');
    $count = $crawler
    ->filter('html:contains("Hello Fabien")')
    ->count();
    $this->assertGreaterThan(0, $count);
    }
    }
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  145. // src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php
    namespace Acme\DemoBundle\Tests\Controller;
    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
    class DemoControllerTest extends WebTestCase
    {
    public function testIndex()
    {
    $client = static::createClient();
    $crawler = $client->request('GET', '/demo/hello/Fabien');
    $count = $crawler
    ->filter('html:contains("Hello Fabien")')
    ->count();
    $this->assertGreaterThan(0, $count);
    }
    }
    CONTRÔLE QUALITÉ
    Navigateur
    mercredi 5 septembre 12

    View Slide

  146. // src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php
    namespace Acme\DemoBundle\Tests\Controller;
    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
    class DemoControllerTest extends WebTestCase
    {
    public function testIndex()
    {
    $client = static::createClient();
    $crawler = $client->request('GET', '/demo/hello/Fabien');
    $count = $crawler
    ->filter('html:contains("Hello Fabien")')
    ->count();
    $this->assertGreaterThan(0, $count);
    }
    }
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  147. // src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php
    namespace Acme\DemoBundle\Tests\Controller;
    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
    class DemoControllerTest extends WebTestCase
    {
    public function testIndex()
    {
    $client = static::createClient();
    $crawler = $client->request('GET', '/demo/hello/Fabien');
    $count = $crawler
    ->filter('html:contains("Hello Fabien")')
    ->count();
    $this->assertGreaterThan(0, $count);
    }
    }
    CONTRÔLE QUALITÉ
    Assertion
    mercredi 5 septembre 12

    View Slide

  148. CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  149. “A PHP framework for testing your business expectations.”
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  150. Feature: buy an article
    In order to be happy
    As a consumer
    I want to be able to buy something
    Scenario:
    Given I am on the homepage
    When I search for "fridge"
    And I follow "Awesome Fridge"
    And I add the article to my cart
    And I follow "checkout"
    # steps that describe the checkout process
    Then I should see "Your order is complete!"
    And I should be happy to have a new fridge
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  151. Feature: buy an article
    In order to be happy
    As a consumer
    I want to be able to buy something
    Scenario:
    Given I am on the homepage
    When I search for "fridge"
    And I follow "Awesome Fridge"
    And I add the article to my cart
    And I follow "checkout"
    # steps that describe the checkout process
    Then I should see "Your order is complete!"
    And I should be happy to have a new fridge
    CONTRÔLE QUALITÉ
    Step
    mercredi 5 septembre 12

    View Slide

  152. CONTRÔLE QUALITÉ
    /**
    * @When /^I search for "(?P[^"]*)"$/
    */
    public function iSearchFor($term)
    {
    $this->fillField('Search', $term);
    $this->pressButton('Find');
    }
    mercredi 5 septembre 12

    View Slide

  153. CONTRÔLE QUALITÉ
    Extensible
    mercredi 5 septembre 12

    View Slide

  154. CONTRÔLE QUALITÉ
    Extensible
    Support de Selenium 1/2, ZombieJS, etc
    mercredi 5 septembre 12

    View Slide

  155. CONTRÔLE QUALITÉ
    Extensible
    Support de Selenium 1/2, ZombieJS, etc
    Extension Symfony 2
    mercredi 5 septembre 12

    View Slide

  156. http://behat.org/
    CONTRÔLE QUALITÉ
    mercredi 5 septembre 12

    View Slide

  157. RÉSUMÉ
    mercredi 5 septembre 12

    View Slide

  158. HTTP
    mercredi 5 septembre 12

    View Slide

  159. HTTP
    Design Pattern MVC
    mercredi 5 septembre 12

    View Slide

  160. HTTP
    Design Pattern MVC
    Injection de dependance
    mercredi 5 septembre 12

    View Slide

  161. HTTP
    Design Pattern MVC
    Injection de dependance
    Composants
    mercredi 5 septembre 12

    View Slide

  162. HTTP
    Design Pattern MVC
    Injection de dependance
    Composants
    Bundles
    mercredi 5 septembre 12

    View Slide

  163. HTTP
    Design Pattern MVC
    Injection de dependance
    Composants
    Bundles
    Contrôle qualité
    mercredi 5 septembre 12

    View Slide

  164. Documentation complète
    mercredi 5 septembre 12

    View Slide

  165. Documentation complète
    Sur le “framework”
    mercredi 5 septembre 12

    View Slide

  166. Documentation complète
    Sur le “framework”
    Par composant
    mercredi 5 septembre 12

    View Slide

  167. Documentation complète
    Sur le “framework”
    Par composant
    “Cookbooks”
    mercredi 5 septembre 12

    View Slide

  168. plus de 100 contributeurs
    mercredi 5 septembre 12

    View Slide

  169. plus de 1600 bundles
    mercredi 5 septembre 12

    View Slide

  170. Drupal
    mercredi 5 septembre 12

    View Slide

  171. Drupal
    PHPBB
    mercredi 5 septembre 12

    View Slide

  172. Drupal
    PHPBB
    Symfony-CMF / PHPCR
    mercredi 5 septembre 12

    View Slide

  173. Drupal
    PHPBB
    Symfony-CMF / PHPCR
    Midgard / MIDCOM
    mercredi 5 septembre 12

    View Slide

  174. Drupal
    PHPBB
    Symfony-CMF / PHPCR
    Midgard / MIDCOM
    ...
    mercredi 5 septembre 12

    View Slide

  175. Pourquoi pas vous ?
    mercredi 5 septembre 12

    View Slide

  176. Geoffrey Bachelet
    https://github.com/ubermuda
    https://twitter.com/ubermuda
    http://pandanova.com/
    http://knplabs.ca/
    [email protected]
    mercredi 5 septembre 12

    View Slide

  177. Geoffrey Bachelet
    https://github.com/ubermuda
    https://twitter.com/ubermuda
    http://pandanova.com/
    http://knplabs.ca/
    [email protected]
    WE’RE

    View Slide