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

Symfony 4 : une nouvelle expérience de développ...

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

Titouan Galopin

October 25, 2018
Tweet

More Decks by Titouan Galopin

Other Decks in Programming

Transcript

  1. 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
  2. Symfony 4 PHP 7.1+ Migration 3 => 4 simplifiée par

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

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

    les adapter au développement en 2018 9
  5. 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
  6. 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
  7. 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.
  8. 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
  9. 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.
  10. 19 ├── config │ ├── bundles.php │ ├── packages │

    │ ├── dev/monolog.yaml │ │ ├── prod/monolog.yaml │ │ └── test/monolog.yaml │ ├── routes.yaml │ └── services.yaml └── public/index.php
  11. 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
  12. 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.
  13. Symfony Flex Besoin d’une API ? composer req api Besoin

    d’une interface d’admin ? composer req admin 25
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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é
  20. 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' ); }
  21. 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
  22. 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
  23. Webpack Regroupe des imports SASS/JS/TS/… pour créer un seul fichier

    43 // app.js const ApiClient = require('./api/client');
  24. 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
  25. 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
  26. 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”
  27. 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”
  28. 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()
  29. Deux types de cache 53 Cache système : - Container

    compilé - Templates Twig compilés - Metadata Doctrine ... Cache applicatif : Vos données à mettre en cache
  30. 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
  31. 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
  32. Deux types de cache 56 Cache système : Filesystem Cache

    applicatif : Votre backend (Redis, PDO, …)
  33. 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
  34. 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) );
  35. 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']
  36. 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']
  37. 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) !
  38. 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/*'
  39. “ L’autowiring n’a rien de magique Il est basé uniquement

    sur les noms de classes et des typehints 75
  40. 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
  41. 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
  42. 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.)
  43. 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
  44. 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
  45. 86 Merci ! Venez me voir au stand Symfony !

    ▪ Twitter : @titouangalopin ▪ Github : @tgalopin ▪ [email protected]