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

Symfony 4 : une nouvelle expérience de développement

Symfony 4 : une nouvelle expérience de développement

364d59ac0b4b4e5eee8aeb27a127d176?s=128

Titouan Galopin

October 25, 2018
Tweet

Transcript

  1. Symfony 4 Une nouvelle expérience de développement Octobre 2018 Forum

    PHP
  2. Titouan Galopin Product Manager SymfonyInsight 2

  3. 3 Agenda 1. Symfony 4 2. Symfony Flex 3. Le

    maker bundle 4. Webpack Encore 5. L’intégration dans les infrastructures modernes 6. L’injection de dépendances
  4. Symfony 4

  5. Symfony 4 Versionnement sémantique 5

  6. Symfony 4 PHP 7.1+ Migration 3 => 4 simplifiée par

    le système de dépréciations 6
  7. Symfony 4 Symfony 4 = Symfony 3.4 sans la couche

    de compatibilité … 7
  8. Symfony 4 Symfony 4 = Symfony 3.4 sans la couche

    de compatibilité … … mais aussi bien plus que ca ! 8
  9. Symfony 4 Réévaluation de toutes les idées de Symfony pour

    les adapter au développement en 2018 9
  10. Symfony 4 Réévaluation de toutes les idées de Symfony pour

    les adapter au développement en 2018 Plus facile à apprendre / configurer / utiliser / déployer Framework PHP le plus rapide du marché 10 phpbenchmarks.com
  11. Symfony Flex

  12. Symfony Flex composer create-project symfony/skeleton mydir 12

  13. 13 ├── bin/console ├── config │ ├── bundles.php │ ├──

    packages │ │ ├── dev/routing.yaml │ │ ├── framework.yaml │ │ ├── routing.yaml │ │ └── test/framework.yaml │ ├── routes.yaml │ └── services.yaml ├── public/index.php └── src ├── Controller └── Kernel.php Nouvelle structure Projet minimal : - 13 fichiers - 4 dépendances directes
  14. 14 ~ composer create-project symfony/skeleton mydir Installing symfony/skeleton (v4.1.5.3) -

    Installing symfony/skeleton (v4.1.5.3) Created project in mydir - Installing symfony/flex (v1.1.1) - ... Generating autoload files Symfony operations: 4 recipes (a4070919102626e6a1736d4d1896e8d8) - Configuring symfony/flex (>=1.0): From github.com/symfony/recipes:master - Configuring symfony/framework-bundle (>=3.3): From github.com/symfony/recipes:master - Configuring symfony/console (>=3.3): From github.com/symfony/recipes:master - Configuring symfony/routing (>=4.0): From github.com/symfony/recipes:master Executing script cache:clear [OK] Executing script assets:install public [OK] Some files may have been created or updated to configure your new packages. Please review, edit and commit them: these files are yours.
  15. Symfony Flex Plugin Composer Au moment de l’installation d’un package,

    Symfony Flex le configure automatiquement 15
  16. Sans Flex - composer require bundle - Ajouter une ligne

    dans app/AppKernel.php - Créer la configuration dans app/config/config.yml - Importer le routing dans app/config/routing.yml Installation d’un bundle Avec Flex - composer require bundle 16
  17. Symfony Flex composer require symfony/monolog-bundle 17

  18. 18 ~/mydir composer require symfony/monolog-bundle Restricting packages listed in "symfony/symfony"

    to "4.1.*" Using version ^3.3 for symfony/monolog-bundle Restricting packages listed in "symfony/symfony" to "4.1.*" Package operations: 3 installs, 0 updates, 0 removals - Installing monolog/monolog (1.23.0) - Installing symfony/monolog-bridge (v4.1.6) - Installing symfony/monolog-bundle (v3.3.0) Writing lock file Generating autoload files Symfony operations: 1 recipe (3ccbdff84ac79218c4bcf54d45c68b02) - Configuring symfony/monolog-bundle (>=3.1): From github.com/symfony/recipes:master Executing script cache:clear [OK] Executing script assets:install public [OK] Some files may have been created or updated to configure your new packages. Please review, edit and commit them: these files are yours.
  19. 19 ├── config │ ├── bundles.php │ ├── packages │

    │ ├── dev/monolog.yaml │ │ ├── prod/monolog.yaml │ │ └── test/monolog.yaml │ ├── routes.yaml │ └── services.yaml └── public/index.php
  20. 20 // config/bundles.php return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],

    Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], ]; ├── config │ ├── bundles.php │ ├── packages │ │ ├── dev/monolog.yaml │ │ ├── prod/monolog.yaml │ │ └── test/monolog.yaml │ ├── routes.yaml │ └── services.yaml └── public/index.php
  21. Symfony Flex Définit un écosystème à partir d’alias officiels 21

  22. Symfony Flex composer req logger 22

  23. 23 ~/mydir composer req logger Restricting packages listed in "symfony/symfony"

    to "4.1.*" Using version ^3.3 for symfony/monolog-bundle Restricting packages listed in "symfony/symfony" to "4.1.*" Package operations: 3 installs, 0 updates, 0 removals - Installing monolog/monolog (1.23.0) - Installing symfony/monolog-bridge (v4.1.6) - Installing symfony/monolog-bundle (v3.3.0) Writing lock file Generating autoload files Symfony operations: 1 recipe (3ccbdff84ac79218c4bcf54d45c68b02) - Configuring symfony/monolog-bundle (>=3.1): From github.com/symfony/recipes:master Executing script cache:clear [OK] Executing script assets:install public [OK] Some files may have been created or updated to configure your new packages. Please review, edit and commit them: these files are yours.
  24. Symfony Flex Besoin d’un ORM ? composer req orm Besoin

    de Twig ? composer req twig 24
  25. Symfony Flex Besoin d’une API ? composer req api Besoin

    d’une interface d’admin ? composer req admin 25
  26. “ Mais comment ca marche ? 26

  27. Symfony Flex Système de “recettes” : une recette par package

    27 Un recette peut : - ajouter des variables d’env - ajouter des paramètres de container - ajouter des fichiers/dossiers au gitignore - créer des fichiers de configuration - enregistrer des bundles
  28. Symfony Flex Composition over Inheritance, pour votre projet complet !

    28
  29. Symfony Flex Le kernel découvre la configuration 29

  30. 30 ├── bin/console ├── config │ ├── bundles.php │ ├──

    packages │ │ ├── dev/routing.yaml │ │ ├── framework.yaml │ │ ├── routing.yaml │ │ └── test/framework.yaml │ ├── routes.yaml │ └── services.yaml ├── public/index.php └── src ├── Controller └── Kernel.php
  31. 31 ├── bin/console ├── config │ ├── bundles.php │ ├──

    packages │ │ ├── dev/routing.yaml │ │ ├── framework.yaml │ │ ├── routing.yaml │ │ └── test/framework.yaml │ ├── routes.yaml │ └── services.yaml ├── public/index.php └── src ├── Controller └── Kernel.php Simple tableau associatif listant les bundles
  32. 32 ├── bin/console ├── config │ ├── bundles.php │ ├──

    packages │ │ ├── dev/routing.yaml │ │ ├── framework.yaml │ │ ├── routing.yaml │ │ └── test/framework.yaml │ ├── routes.yaml │ └── services.yaml ├── public/index.php └── src ├── Controller └── Kernel.php Simple tableau associatif listant les bundles Equivalent de AppKernel, charge les bons fichiers de configuration / services / routing
  33. 33 ├── bin/console ├── config │ ├── bundles.php │ ├──

    packages │ │ ├── dev/routing.yaml │ │ ├── framework.yaml │ │ ├── routing.yaml │ │ └── test/framework.yaml │ ├── routes.yaml │ └── services.yaml ├── public/index.php └── src ├── Controller └── Kernel.php Découverte automatique du contenu du dossier packages par le Kernel Simple tableau associatif listant les bundles Equivalent de AppKernel, charge les bons fichiers de configuration / services / routing
  34. 34 ├── bin/console ├── config │ ├── bundles.php │ ├──

    packages │ │ ├── dev/routing.yaml │ │ ├── framework.yaml │ │ ├── routing.yaml │ │ └── test/framework.yaml │ ├── routes.yaml │ └── services.yaml ├── public/index.php └── src ├── Controller └── Kernel.php Découverte automatique du contenu du dossier packages par le Kernel Simple tableau associatif listant les bundles Equivalent de AppKernel, charge les bons fichiers de configuration / services / routing Chaque environnement peut avoir son sous-dossier dédié
  35. 35 protected function configureContainer($container, loader) { $container->addResource( new FileResource($this->getProjectDir().'/config/bundles.php') );

    // ... $loader->load( $confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob' ); $loader->load( $confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob' ); $loader->load( $confDir.'/{services}'.self::CONFIG_EXTS, 'glob' ); $loader->load( $confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob' ); }
  36. Symfony Flex https://flex.symfony.com 2 types de recettes : officielles et

    contrib 36
  37. Le maker bundle

  38. Le maker bundle composer require --dev maker 38

  39. Le maker bundle Un générateur qui fait bien les choses

    39 make:auth make:command make:controller make:crud make:entity make:fixtures make:form make:functional-test make:migration make:serializer:encoder make:subscriber make:twig-extension make:unit-test make:user make:validator make:voter
  40. 40 ~/mydir composer req annotations ~/mydir composer req --dev maker

    ~/mydir bin/console make:controller Choose a name for your controller class (e.g. OrangeJellybeanController): > HomeController created: src/Controller/HomeController.php _Success!_ Next: Open your new controller class and add some pages! Nécessaire pour maker:controller
  41. Le maker bundle Le code généré vous appartient : Modifiez-le,

    adaptez-le, commitez-le ! 41
  42. Webpack Encore

  43. Webpack Regroupe des imports SASS/JS/TS/… pour créer un seul fichier

    43 // app.js const ApiClient = require('./api/client');
  44. Webpack Encore Symfony Webpack Encore Librairie Javascript pour utiliser Webpack

    facilement 44
  45. Webpack Encore composer require --dev webpack 45

  46. 46 ├── assets │ ├── css/app.css │ └── js/app.js ├──

    config/… ├── public │ ├── build/app.min.css │ ├── build/app.min.js │ └── index.php ├── src/... ├── package.json ├── webpack.config.js └── ... Dossier de source des assets
  47. 47 ├── assets │ ├── css/app.css │ └── js/app.js ├──

    config/… ├── public │ ├── build/app.min.css │ ├── build/app.min.js │ └── index.php ├── src/... ├── package.json ├── webpack.config.js └── ... Dossier des assets minifiés Dossier de source des assets
  48. 48 ├── assets │ ├── css/app.css │ └── js/app.js ├──

    config/… ├── public │ ├── build/app.min.css │ ├── build/app.min.js │ └── index.php ├── src/... ├── package.json ├── webpack.config.js └── ... Dossier des assets minifiés Dossier de source des assets “composer.json pour Javascript”
  49. 49 ├── assets │ ├── css/app.css │ └── js/app.js ├──

    config/… ├── public │ ├── build/app.min.css │ ├── build/app.min.js │ └── index.php ├── src/... ├── package.json ├── webpack.config.js └── ... Dossier des assets minifiés Dossier de source des assets Configuration de Webpack “composer.json pour Javascript”
  50. 50 var Encore = require('@symfony/webpack-encore'); Encore .setOutputPath('public/build/') .setPublicPath('/build') .addEntry('app', './assets/js/app.js')

    .cleanupOutputBeforeBuild() .enableBuildNotifications() .enableSourceMaps(!Encore.isProduction()) .enableVersioning(Encore.isProduction()) // enables Sass/SCSS support //.enableSassLoader() // uncomment if you use TypeScript //.enableTypeScriptLoader() // uncomment if you're having problems with a jQuery plugin //.autoProvidejQuery()
  51. L’intégration dans les infrastructures modernes

  52. L’intégration dans les infrastructures modernes Deux types de caches 52

  53. Deux types de cache 53 Cache système : - Container

    compilé - Templates Twig compilés - Metadata Doctrine ... Cache applicatif : Vos données à mettre en cache
  54. Deux types de cache 54 Cache système : Ne change

    pas au cours de la vie de l’application (read-only) Cache applicatif : Change au cours de la vie de l’application
  55. Deux types de cache 55 Cache système : N’a pas

    besoin d’être synchronisé entre plusieurs instances frontales Cache applicatif : Doit être synchronisé entre plusieurs instances frontales
  56. Deux types de cache 56 Cache système : Filesystem Cache

    applicatif : Votre backend (Redis, PDO, …)
  57. Deux types de cache 57 framework: cache: app: cache.adapter.redis default_redis_provider:

    'redis://%env(REDIS_HOST)%'
  58. L’intégration dans les infrastructures modernes Les variables d’environnement 58

  59. Les variables d’environnement .env Intégré dans les recettes Référençable dans

    la configuration / les services 59
  60. 60 .env ###> symfony/framework-bundle ### APP_ENV=dev APP_SECRET=95b679e8ee0683314cece8ea8126795d #TRUSTED_PROXIES=127.0.0.1,127.0.0.2 #TRUSTED_HOSTS=localhost,example.com ###<

    symfony/framework-bundle ### config/packages/framework.yaml framework: secret: '%env(APP_SECRET)%'
  61. L’injection de dépendances

  62. L’injection de dépendances Probablement le composant qui a le plus

    changé en 3.4/4.0 62 - Autodiscovery - Autowiring - Autoconfiguration - Defaults - Bindings - Services taggués - Controllers as services
  63. Comment fonctionne le composant DependencyInjection ? 63 class Persister {/*

    ... */} class Mailer {/* ... */} class RegistrationManager { private $persister; private $mailer; public function __construct( Persister $persister, Mailer $mailer ) { /* ... */ } public function register() {} } Objectif : $manager = new RegistrationManager( new Persister($doctrine), new Mailer($twig, $swiftmailer) );
  64. Comment fonctionne le composant DependencyInjection ? 64 Mailer Persister RegistrationManager

    Swiftmailer Twig Doctrine
  65. L’injection de dépendances Configuration => Graphe => Container compilé 65

  66. L’injection de dépendances En Symfony 3, pour configurer ce graphe

    : app/config/services.yml 66
  67. L’injection de dépendances Symfony 4 introduit différentes automatisations pour créer

    ce graphe plus simplement 67
  68. L’injection de dépendances Identifiant de service = Nom complet de

    la classe 68
  69. Identifiant de service = nom complet de la classe 69

    Symfony 3 app.mailer: class: AppBundle\Mailer\Mailer arguments: ['@twig', '@mailer'] app.persister: class: AppBundle\Doctrine\Persister arguments: ['@doctrine'] app.registration_manager: class: AppBundle\Registration\RegistrationManager arguments: ['@app.persister', '@app.mailer']
  70. Identifiant de service = nom complet de la classe 70

    Symfony 4 App\Mailer\Mailer: arguments: ['@twig', '@mailer'] App\Doctrine\Persister: arguments: ['@doctrine'] App\Registration\RegistrationManager: arguments: ['@App\Doctrine\Persister', '@App\Mailer\Mailer']
  71. Identifiant de service = nom complet de la classe 71

    Symfony 4 App\Mailer\Mailer: arguments: ['@twig', '@mailer'] App\Doctrine\Persister: arguments: ['@doctrine'] App\Registration\RegistrationManager: arguments: ['@App\Doctrine\Persister', '@App\Mailer\Mailer'] Permet $container->get(Mailer::class) !
  72. L’injection de dépendances Autodiscovery + Autowiring 72

  73. Autodiscovery + Autowiring 73 App\Mailer\Mailer: arguments: ['@twig', '@mailer'] App\Doctrine\Persister: arguments:

    ['@doctrine'] App\Registration\RegistrationManager: arguments: ['@App\Doctrine\Persister', '@App\Mailer\Mailer'] App\: resource: '../src/*'
  74. Comment fonctionne le composant DependencyInjection ? 74 Mailer Persister RegistrationManager

    Swiftmailer Twig Doctrine Autodiscovery Autowiring
  75. “ L’autowiring n’a rien de magique Il est basé uniquement

    sur les noms de classes et des typehints 75
  76. Comment fonctionne le composant DependencyInjection ? 76 class Persister {/*

    ... */} class Mailer {/* ... */} class RegistrationManager { private $persister; private $mailer; public function __construct(Persister $persister, Mailer $mailer) { /* ... */ } public function register() {} } Nom des services à injecter = typehints
  77. L’injection de dépendances Defaults + Autoconfiguration 77

  78. Defaults + Autoconfiguration 78 services: _defaults: autowire: true autoconfigure: true

    public: false App\: resource: '../src/*' Defaults (par fichier) : Les nouvelles fonctionnalités sont opt-in Services privés par défaut
  79. Defaults + Autoconfiguration 79 services: _defaults: autowire: true autoconfigure: true

    public: false App\: resource: '../src/*' Defaults (par fichier) : Autoconfiguration : Configure automatiquement les services en fonctions de leurs interfaces (extensions Twig, listeners, etc.)
  80. L’injection de dépendances Bindings : et les paramètres ? 80

  81. Bindings 81 services: # pour un service précis App\Registration\RegistrationManager: arguments:

    $projectDir: '%kernel.project_dir%' # pour tous les services du fichier _defaults: bind: $projectDir: '%kernel.project_dir%' Automatise l’injection des paramètres
  82. L’injection de dépendances Les contrôleurs sont des services 82

  83. Controllers as services 83 services: App\Controller\: resource: '../src/Controller' tags: ['controller.service_arguments']

    public function contact( Request $request, Mailer $mailer ) { // … } Le tag permet d’injecter les services en paramètres de l’action
  84. Comment fonctionne le composant DependencyInjection ? 84 Mailer Persister RegistrationManager

    Swiftmailer Twig Doctrine RegistrationController
  85. 85 Contribuez ! symfony.com/support => Slack Pinguez Nicolas Grekas

  86. 86 Merci ! Venez me voir au stand Symfony !

    ▪ Twitter : @titouangalopin ▪ Github : @tgalopin ▪ titouan.galopin@symfony.com