Slide 1

Slide 1 text

Symfony 4 Une nouvelle expérience de développement Juin 2018 AFUP Limoges

Slide 2

Slide 2 text

Titouan Galopin Product Lead à Symfony 2

Slide 3

Slide 3 text

Symfony 4 Versionnement sémantique 3

Slide 4

Slide 4 text

Symfony 4 Symfony 4 = Symfony 3.4 sans la couche de compatibilité … 4

Slide 5

Slide 5 text

Symfony 4 Symfony 4 = Symfony 3.4 sans la couche de compatibilité … … mais aussi bien plus que ca ! 5

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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é 7 phpbenchmarks.com

Slide 8

Slide 8 text

Symfony 4 PHP 7.1+ Migration 3 => 4 simplifiée par le système de dépréciations 8

Slide 9

Slide 9 text

9 ├── 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 vide : - 13 fichiers - 4 dépendances directes

Slide 10

Slide 10 text

Symfony Flex composer create-project symfony/skeleton mydir 10

Slide 11

Slide 11 text

11

Slide 12

Slide 12 text

Symfony Flex Plugin Composer Au moment de l’installation d’un package, Symfony Flex le configure automatiquement 12

Slide 13

Slide 13 text

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 13

Slide 14

Slide 14 text

Symfony Flex composer require symfony/monolog-bundle 14

Slide 15

Slide 15 text

15

Slide 16

Slide 16 text

Symfony Flex Définit un écosystème à partir d’alias officiels 16

Slide 17

Slide 17 text

Symfony Flex composer require logger 17

Slide 18

Slide 18 text

18

Slide 19

Slide 19 text

Symfony Flex Besoin d’un ORM ? composer require orm Besoin de Twig ? composer require twig 19

Slide 20

Slide 20 text

Symfony Flex Besoin d’une API ? composer require api Besoin d’une interface d’admin ? composer require admin 20

Slide 21

Slide 21 text

“ Mais comment ca marche ? 21

Slide 22

Slide 22 text

Symfony Flex Système de “recettes” : Décrit comment un package doit être configuré https://symfony.sh 2 types : officielles et contrib 22

Slide 23

Slide 23 text

Symfony Flex Plus de bundle d’application ! Nouveau kernel pour charger la configuration 23

Slide 24

Slide 24 text

24

Slide 25

Slide 25 text

Le maker bundle

Slide 26

Slide 26 text

Le maker bundle composer require maker 26

Slide 27

Slide 27 text

Le maker bundle Un générateur qui fait bien les choses 27 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:validator make:voter

Slide 28

Slide 28 text

28

Slide 29

Slide 29 text

L’intégration dans les infrastructures modernes

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Deux types de cache 32 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

Slide 33

Slide 33 text

Deux types de cache 33 Cache système : N’a pas besoin d’être synchronisé entre plusieurs instances frontales Cache applicatif : Doit être synchronisé entre plusieurs instances frontales

Slide 34

Slide 34 text

Deux types de cache 34 Cache système : Filesystem Cache applicatif : Votre backend (Redis, PDO, …)

Slide 35

Slide 35 text

Deux types de cache 35 framework: cache: app: cache.adapter.redis default_redis_provider: 'redis://%env(REDIS_HOST)%'

Slide 36

Slide 36 text

L’intégration dans les infrastructures modernes Les variables d’environnement 36

Slide 37

Slide 37 text

Les variables d’environnement .env Intégré dans les recettes Référençable dans la configuration de services 37

Slide 38

Slide 38 text

38

Slide 39

Slide 39 text

L’injection de dépendances

Slide 40

Slide 40 text

L’injection de dépendances Probablement le composant qui a le plus changé en 3.4/4.0 40 - Autodiscovery - Autowiring - Autoconfiguration - Defaults - Bindings - Services taggués - Controllers as services

Slide 41

Slide 41 text

Comment fonctionne le composant DependencyInjection ? 41 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) );

Slide 42

Slide 42 text

Comment fonctionne le composant DependencyInjection ? 42 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine

Slide 43

Slide 43 text

L’injection de dépendances Configuration => Graphe => Container compilé 43

Slide 44

Slide 44 text

L’injection de dépendances En Symfony 3, pour configurer ce graphe : app/config/services.yml 44

Slide 45

Slide 45 text

L’injection de dépendances Symfony 4 introduit différentes automatisations pour créer ce graphe plus simplement 45

Slide 46

Slide 46 text

L’injection de dépendances Identifiant de service = Nom complet de la classe 46

Slide 47

Slide 47 text

Identifiant de service = nom complet de la classe 47 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']

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

Identifiant de service = nom complet de la classe 49 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) !

Slide 50

Slide 50 text

L’injection de dépendances Autodiscovery + Autowiring 50

Slide 51

Slide 51 text

Autodiscovery + Autowiring 51 App\Mailer\Mailer: arguments: ['@twig', '@mailer'] App\Doctrine\Persister: arguments: ['@doctrine'] App\Registration\RegistrationManager: arguments: ['@App\Doctrine\Persister', '@App\Mailer\Mailer'] App\: resource: '../src/*'

Slide 52

Slide 52 text

Comment fonctionne le composant DependencyInjection ? 52 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine Autodiscovery Autowiring

Slide 53

Slide 53 text

“ L’autowiring n’a rien de magique Il est basé uniquement sur les noms de classes et des typehints 53

Slide 54

Slide 54 text

Comment fonctionne le composant DependencyInjection ? 54 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

Slide 55

Slide 55 text

L’injection de dépendances Defaults + Autoconfiguration 55

Slide 56

Slide 56 text

Defaults + Autoconfiguration 56 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

Slide 57

Slide 57 text

Defaults + Autoconfiguration 57 services: _defaults: autowire: true autoconfigure: true public: false App\: resource: '../src/*' Defaults (par fichier) : Autoconfiguration : Configure automatiquement les services en fonctions des interfaces qu’ils implémentent

Slide 58

Slide 58 text

L’injection de dépendances Bindings : et les paramètres ? 58

Slide 59

Slide 59 text

Bindings 59 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

Slide 60

Slide 60 text

L’injection de dépendances Controllers as services Les contrôleurs sont des services 60

Slide 61

Slide 61 text

Controllers as services 61 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

Slide 62

Slide 62 text

Comment fonctionne le composant DependencyInjection ? 62 Mailer Persister RegistrationManager Swiftmailer Twig Doctrine RegistrationController

Slide 63

Slide 63 text

L’injection de dépendances Services taggués 63

Slide 64

Slide 64 text

L’injection de dépendances 64 services: App\Manager\TwigManager: arguments: [!tagged twig.extension]

Slide 65

Slide 65 text

65

Slide 66

Slide 66 text

66 Contribuez ! symfony.com/support => Slack Pinguez Nicolas Grekas

Slide 67

Slide 67 text

67 Merci ! Questions ? Bières ? ▪ Twitter : @titouangalopin ▪ Github : @tgalopin ▪ [email protected]