Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symfony 2, un framework robuste et moderne

88b8138397e1d1441f4e4a54348bde09?s=47 ubermuda
September 06, 2012

Symfony 2, un framework robuste et moderne

Présentation du framework PHP 5 Symfony 2

88b8138397e1d1441f4e4a54348bde09?s=128

ubermuda

September 06, 2012
Tweet

Transcript

  1. Un framework PHP robuste et moderne Geoffrey Bachelet – Pandanova

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

    5 septembre 12
  3. HTTP mercredi 5 septembre 12

  4. HTTP Quel est le cycle de vie d’une page web

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Cache (etags, validation, ...) Tirer parti du protocole HTTP HTTP mercredi 5 septembre 12
  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
  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
  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
  24. MVC mercredi 5 septembre 12

  25. MVC mercredi 5 septembre 12

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

  27. <?php /** @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
  28. <?php /** @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
  29. <?php /** @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
  30. <?xml version="1.0" encoding="UTF-8"?> <database> <table name="post"> <column name="id" type="integer" required="true"

    primaryKey="true" autoIncrement="true" /> <column name="title" type="varchar" required="true" /> <column name="body" type="text" required="true" /> </table> </database> http://propelorm.org/ MVC mercredi 5 septembre 12
  31. <?xml version="1.0" encoding="UTF-8"?> <database> <table name="post"> <column name="id" type="integer" required="true"

    primaryKey="true" autoIncrement="true" /> <column name="title" type="varchar" required="true" /> <column name="body" type="text" required="true" /> </table> </database> http://propelorm.org/ MVC Données mercredi 5 septembre 12
  32. <?php /** * 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
  33. <?php /** * 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
  34. La couche vue MVC mercredi 5 septembre 12

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

    <div class="post" id="post-{{ post.id }}"> <h2>{{ post.title }}</h2> <div class="post-body"> {{ post.body | markdown }} </div> </div> {% endfor %} Twig http://twig.sensiolabs.org/ MVC mercredi 5 septembre 12
  36. {% extends 'layout.html.twig' %} {% for post in posts %}

    <div class="post" id="post-{{ post.id }}"> <h2>{{ post.title }}</h2> <div class="post-body"> {{ post.body | markdown }} </div> </div> {% endfor %} http://twig.sensiolabs.org/ MVC Layout mercredi 5 septembre 12
  37. {% extends 'layout.html.twig' %} {% for post in posts %}

    <div class="post" id="post-{{ post.id }}"> <h2>{{ post.title }}</h2> <div class="post-body"> {{ post.body | markdown }} </div> </div> {% endfor %} http://twig.sensiolabs.org/ MVC Boucles mercredi 5 septembre 12
  38. {% extends 'layout.html.twig' %} {% for post in posts %}

    <div class="post" id="post-{{ post.id }}"> <h2>{{ post.title }}</h2> <div class="post-body"> {{ post.body | markdown }} </div> </div> {% endfor %} http://twig.sensiolabs.org/ MVC Variables mercredi 5 septembre 12
  39. {% extends 'layout.html.twig' %} {% for post in posts %}

    <div class="post" id="post-{{ post.id }}"> <h2>{{ post.title }}</h2> <div class="post-body"> {{ post.body | markdown }} </div> </div> {% endfor %} http://twig.sensiolabs.org/ MVC Filtres mercredi 5 septembre 12
  40. Le contrôleur MVC mercredi 5 septembre 12

  41. <?php 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
  42. <?php 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
  43. <?php 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
  44. Logique métier encapsulée Facilement testable Facilement maintenable MVC mercredi 5

    septembre 12
  45. INJECTION DE DÉPENDANCE mercredi 5 septembre 12

  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
  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
  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
  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
  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
  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
  52. http://www.slideshare.net/fabpot/dependency-injection-in-php-5354 Flexible Configurable Découplé INJECTION DE DÉPENDANCE mercredi 5 septembre

    12
  53. COMPOSANTS mercredi 5 septembre 12

  54. COMPOSANTS ClassLoader Config Console DependencyInjection EventDispatcher Finder Form HttpFoundation Locale

    Process Routing Security Templating Validation YAML ... mercredi 5 septembre 12
  55. CLASSLOADER mercredi 5 septembre 12

  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
  57. CLASSLOADER <?php $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
  58. CLASSLOADER <?php $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
  59. CLASSLOADER <?php $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
  60. CONFIG mercredi 5 septembre 12

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

  62. CONFIG Gestion avancée de configuration Chargement de fichiers de configuration

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

    Mise en cache de la configuration COMPOSANTS mercredi 5 septembre 12
  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
  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
  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
  67. CONSOLE mercredi 5 septembre 12

  68. CONSOLE COMPOSANTS mercredi 5 septembre 12

  69. CONSOLE COMPOSANTS mercredi 5 septembre 12

  70. CONSOLE options COMPOSANTS mercredi 5 septembre 12

  71. CONSOLE options argument COMPOSANTS mercredi 5 septembre 12

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

    12
  73. DEPENDENCYINJECTION mercredi 5 septembre 12

  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
  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
  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
  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
  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
  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
  80. EVENTDISPATCHER mercredi 5 septembre 12

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

    12
  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
  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
  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
  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
  86. FINDER mercredi 5 septembre 12

  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
  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
  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
  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
  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
  92. FINDER Recherche dans plusieurs répertoires COMPOSANTS mercredi 5 septembre 12

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

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

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

    masques de fichiers Recherche par taille COMPOSANTS mercredi 5 septembre 12
  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
  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
  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
  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
  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
  101. FORM mercredi 5 septembre 12

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

  103. FORM Gestion de formulaires complexes Rendu personnalisable via Twig COMPOSANTS

    mercredi 5 septembre 12
  104. FORM Gestion de formulaires complexes Rendu personnalisable via Twig Validation

    des données COMPOSANTS mercredi 5 septembre 12
  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
  106. COMPOSANTS ClassLoader Config Console DependencyInjection EventDispatcher Finder Form HttpFoundation Locale

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

    5 septembre 12
  108. BUNDLES mercredi 5 septembre 12

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

  110. BUNDLES mercredi 5 septembre 12

  111. BUNDLES Bundle mercredi 5 septembre 12

  112. BUNDLES Bundle mercredi 5 septembre 12

  113. BUNDLES Bundle mercredi 5 septembre 12

  114. BUNDLES Bundle mercredi 5 septembre 12

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

  116. Un Bundle peut contenir : Des extensions pour l’injection de

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

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

    dépendance Des contrôleurs Des gabarits Twig BUNDLES mercredi 5 septembre 12
  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
  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
  121. Un moyen efficace de structurer du code BUNDLES mercredi 5

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

    septembre 12
  123. BUNDLES mercredi 5 septembre 12

  124. BUNDLES 1611 Bundles ! mercredi 5 septembre 12

  125. AsseticBundle BUNDLES mercredi 5 septembre 12

  126. AsseticBundle AvalancheImagineBundle BUNDLES mercredi 5 septembre 12

  127. AsseticBundle AvalancheImagineBundle FOSCommentBundle BUNDLES mercredi 5 septembre 12

  128. AsseticBundle AvalancheImagineBundle FOSCommentBundle FOSRestBundle BUNDLES mercredi 5 septembre 12

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

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

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

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

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

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

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

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

    mercredi 5 septembre 12
  137. CONTRÔLE QUALITÉ mercredi 5 septembre 12

  138. CONTRÔLE QUALITÉ mercredi 5 septembre 12

  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
  140. CONTRÔLE QUALITÉ Barre verte ! mercredi 5 septembre 12

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

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

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

  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
  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
  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
  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
  148. CONTRÔLE QUALITÉ mercredi 5 septembre 12

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

    mercredi 5 septembre 12
  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
  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
  152. CONTRÔLE QUALITÉ /** * @When /^I search for "(?P<term>[^"]*)"$/ */

    public function iSearchFor($term) { $this->fillField('Search', $term); $this->pressButton('Find'); } mercredi 5 septembre 12
  153. CONTRÔLE QUALITÉ Extensible mercredi 5 septembre 12

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

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

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

  157. RÉSUMÉ mercredi 5 septembre 12

  158. HTTP mercredi 5 septembre 12

  159. HTTP Design Pattern MVC mercredi 5 septembre 12

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

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

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

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

    qualité mercredi 5 septembre 12
  164. Documentation complète mercredi 5 septembre 12

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

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

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

    septembre 12
  168. plus de 100 contributeurs mercredi 5 septembre 12

  169. plus de 1600 bundles mercredi 5 septembre 12

  170. Drupal mercredi 5 septembre 12

  171. Drupal PHPBB mercredi 5 septembre 12

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

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

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

    5 septembre 12
  175. Pourquoi pas vous ? mercredi 5 septembre 12

  176. Geoffrey Bachelet https://github.com/ubermuda https://twitter.com/ubermuda http://pandanova.com/ http://knplabs.ca/ geoffrey.bachelet@pandanova.com mercredi 5 septembre

    12
  177. Geoffrey Bachelet https://github.com/ubermuda https://twitter.com/ubermuda http://pandanova.com/ http://knplabs.ca/ geoffrey.bachelet@pandanova.com WE’RE