Slide 1

Slide 1 text

@saro0h Sarah Khalil Quoi de neuf dans depuis 1 an ? jeudi 30 mars 2017

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Oh nice, ça fait belle lurette que je mate plus trop le blog sur symfony.com

Slide 4

Slide 4 text

Oh nice, ça fait belle lurette que je mate plus trop le blog sur symfony.com Pinaise j’vais enfin pouvoir marquer comme lues toutes mes notifs Github !

Slide 5

Slide 5 text

https://speakerdeck.com/saro0h

Slide 6

Slide 6 text

https://speakerdeck.com/saro0h 3.1 & 3.2 + Community stuff

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

• 4 nouvelles versions mineures : 3.0, 3.1, 3.2 et et et 3.3 • Une pelleté de releases : ± 70 versions 1 928 mergées 3455 ouvertes

Slide 10

Slide 10 text

• 4 nouvelles versions mineures : 3.0, 3.1, 3.2 et et et 3.3 • Une pelleté de releases : ± 70 versions 1 928 mergées 3455 ouvertes

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

v3.3

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Ce que nous allons aborder

Slide 17

Slide 17 text

Ce que nous allons aborder Deprecations & Features 1

Slide 18

Slide 18 text

Ce que nous allons aborder Deprecations & Features 1 2-3 trucs à savoir 2

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Deprecations J’en ai choisi 7

Slide 22

Slide 22 text

Deprecations J’en ai choisi 7

Slide 23

Slide 23 text

On en a fini avec SYMFONY__ • SYMFONY__ ne sera plus interprété en version 4.x • Il faut utiliser : %env()% (à partir de 3.2.x) # app/config/parameters.yml parameters: database_host: '%env(DATABASE_HOST)%' env(DATABASE_HOST): localhost

Slide 24

Slide 24 text

On en a fini avec SYMFONY__ • SYMFONY__ ne sera plus interprété en version 4.x • Il faut utiliser : %env()% (à partir de 3.2.x) # app/config/parameters.yml parameters: database_host: '%env(DATABASE_HOST)%' env(DATABASE_HOST): localhost Valeur par défaut

Slide 25

Slide 25 text

cache:clear avec warmup • Version 4 : Faire en sorte qu’il soit possible de générer le cache complet pour exécuter l’application sur un système « read-only ». • Le warmup exécuté au moment du cache clear n’est pas aussi fiable que la commande cache:warmup.

Slide 26

Slide 26 text

cache:clear avec warmup • Version 4 : Faire en sorte qu’il soit possible de générer le cache complet pour exécuter l’application sur un système « read-only ». • Le warmup exécuté au moment du cache clear n’est pas aussi fiable que la commande cache:warmup. $ ./bin/console cache:clear (--env=prod|dev) Avant

Slide 27

Slide 27 text

cache:clear avec warmup • Version 4 : Faire en sorte qu’il soit possible de générer le cache complet pour exécuter l’application sur un système « read-only ». • Le warmup exécuté au moment du cache clear n’est pas aussi fiable que la commande cache:warmup. $ ./bin/console cache:clear (--env=prod|dev) Avant $ ./bin/console cache:clear --no-warmup (--env=prod|dev) $ ./bin/console cache:warmup (--env=prod|dev) Après

Slide 28

Slide 28 text

Console.EXCEPTION • console.EXCEPTION : exception lancée dans Command::execute(). • Pour le reste, tout est traité dans un bloc try catch dans la méthode Command::doRunCommand(). • Impossible d’overrider la manière de gérer les exceptions dans ces cas là. • Désormais, un nouvel évènement est lancé, console.ERROR après ce try catch.

Slide 29

Slide 29 text

X-Status-Code

Slide 30

Slide 30 text

X-Status-Code use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); // 500 is the original status code; but the end user will get a 404 $response = new Response('...', 500, ['X-Status-Code' => 404]); // ... $event->setResponse($response); } Avant

Slide 31

Slide 31 text

X-Status-Code use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); // 500 is the original status code; but the end user will get a 404 $response = new Response('...', 500, ['X-Status-Code' => 404]); // ... $event->setResponse($response); } Avant use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); $response = new Response('...', 404); // ... $event->allowCustomResponseCode(); $event->setResponse($response); } Après

Slide 32

Slide 32 text

Composant ClassLoader • Composer a pris le relais ! • Si vous utilisez PHP 7 (et la version 3.3), vous pouvez dores et déjà tester en supprimant la ligne dans votre front controller. $kernel->loadClassCache();

Slide 33

Slide 33 text

autowiring-types

Slide 34

Slide 34 text

Autowiring services: rot13_transformer: class: AppBundle\Rot13Transformer twitter_client: class: AppBundle\TwitterClient autowire: true namespace AppBundle; class Rot13Transformer implements TransformerInterface { // … } namespace AppBundle; class TwitterClient { private $transformer; public function __construct(TransformerInterface $transformer) { $this->transformer = $transformer; } // … }

Slide 35

Slide 35 text

%

Slide 36

Slide 36 text

MAIS

Slide 37

Slide 37 text

services: rot13_transformer: class: AppBundle\Rot13Transformer another_transformer: class: AppBundle\AnotherTransformer autowiring_types: AppBundle\TransformerInterface twitter_client: class: AppBundle\TwitterClient autowire: true namespace AppBundle; class Rot13Transformer implements TransformerInterface { // … } namespace AppBundle; class TwitterClient { private $transformer; public function __construct(TransformerInterface $transformer) { $this->transformer = $transformer; } // … } namespace AppBundle; class AnotherTransformer implements TransformerInterface { // … } Autowiring

Slide 38

Slide 38 text

services: rot13_transformer: class: AppBundle\Rot13Transformer another_transformer: class: AppBundle\AnotherTransformer autowiring_types: AppBundle\TransformerInterface twitter_client: class: AppBundle\TwitterClient autowire: true namespace AppBundle; class Rot13Transformer implements TransformerInterface { // … } namespace AppBundle; class TwitterClient { private $transformer; public function __construct(TransformerInterface $transformer) { $this->transformer = $transformer; } // … } namespace AppBundle; class AnotherTransformer implements TransformerInterface { // … } Autowiring Implémentation par défaut

Slide 39

Slide 39 text

On veut simplifier

Slide 40

Slide 40 text

autowiring-types services: rot13_transformer: class: AppBundle\Rot13Transformer another_transformer: class: AppBundle\AnotherTransformer autowiring_types: AppBundle\TransformerInterface twitter_client: class: AppBundle\TwitterClient autowire: true Avant

Slide 41

Slide 41 text

autowiring-types services: rot13_transformer: class: AppBundle\Rot13Transformer another_transformer: class: AppBundle\AnotherTransformer autowiring_types: AppBundle\TransformerInterface twitter_client: class: AppBundle\TwitterClient autowire: true Avant services: rot13_transformer: class: AppBundle\Rot13Transformer another_transformer: class: AppBundle\AnotherTransformer alias: rot13_transformer public: false twitter_client: class: AppBundle\TwitterClient autowire: true Après

Slide 42

Slide 42 text

autowiring-types Implémentation par défaut services: rot13_transformer: class: AppBundle\Rot13Transformer another_transformer: class: AppBundle\AnotherTransformer autowiring_types: AppBundle\TransformerInterface twitter_client: class: AppBundle\TwitterClient autowire: true Avant services: rot13_transformer: class: AppBundle\Rot13Transformer another_transformer: class: AppBundle\AnotherTransformer alias: rot13_transformer public: false twitter_client: class: AppBundle\TwitterClient autowire: true Après

Slide 43

Slide 43 text

Insensibilité à la casse des identifiants de services services: MyService: class: AppBundle\RandomClass services: myService: class: AppBundle\AnotherClass ≠

Slide 44

Slide 44 text

Features 3.3 J’en ai choisi 20

Slide 45

Slide 45 text

Features 3.3 J’en ai choisi 20

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

Récupérer les flash messages plus facilement (1/3) {% if app.session is not null and app.session.started %} {% for label, messages in app.session.flashbag.all %} {% for message in messages %}
{{ message }}
{% endfor %} {% endfor %} {% endif %} {% for label, messages in app.flashes %} {% for message in messages %}
{{ message }}
{% endfor %} {% endfor %} Avant Après 1/20

Slide 49

Slide 49 text

{% if app.session is not null and app.session.started %} {% for message in app.session.flashbag.get('notice') %}
{{ message }}
{% endfor %} {% endif %} {% for message in app.flashes('notice') %}
{{ message }}
{% endfor %} Avant Après Récupérer les flash messages plus facilement (2/3) 1/20

Slide 50

Slide 50 text

{% for label, messages in app.flashes(['warning', 'error']) %} {% for message in messages %}
{{ message }}
{% endfor %} {% endfor %} Récupérer les flash messages plus facilement (3/3) 1/20

Slide 51

Slide 51 text

Le username des utilisateurs in memory ne sont plus normalisés Avant foo-bar@gmail.com devenait foo_bar@gmail.com Après foo-bar@gmail.com reste foo-bar@gmail.com 2/20

Slide 52

Slide 52 text

Symfony\Bundle\FrameworkBundle\Controller\Controller • On encourage à utiliser le Symfony\Bundle\FrameworkBundle\Controller\AbstractController. • Fournit les même helpers que le Controller, mais ne donne plus accès au container via la méthode get(). • Encourager la déclaration explicite des dépendances dans son Controller. 3/20

Slide 53

Slide 53 text

Workflow : Guard expression transitions: journalist_approval: guard: "is_fully_authenticated() and has_role('ROLE_JOURNALIST') or is_granted('POST_EDIT', subject)" from: wait_for_journalist to: approved_by_journalist publish: guard: "subject.isPublic()" from: approved_by_journalist to: published 4/20

Slide 54

Slide 54 text

XLiff linter $ bin/console lint:xliff 5/20

Slide 55

Slide 55 text

Recherche dans le contenu d’un dump() Dans la WebDebugToolbar Dans le profiler Dans une page 6/20

Slide 56

Slide 56 text

Nouveau data collector : cache 7/20

Slide 57

Slide 57 text

Plus besoin d’activer les bundles un à un Le but : installer les bundles / composants dont on a besoin. 8/20

Slide 58

Slide 58 text

Plus besoin d’activer les bundles un à un Le but : installer les bundles / composants dont on a besoin. Avant 1. Tout est là (composants/bundles) 2. Activer les fonctionnalités un à un en config 8/20

Slide 59

Slide 59 text

Plus besoin d’activer les bundles un à un Le but : installer les bundles / composants dont on a besoin. Avant 1. Tout est là (composants/bundles) 2. Activer les fonctionnalités un à un en config Installer ce dont on a besoin Après 8/20

Slide 60

Slide 60 text

Plus besoin d’activer les bundles un à un Le but : installer les bundles / composants dont on a besoin. Avant 1. Tout est là (composants/bundles) 2. Activer les fonctionnalités un à un en config Installer ce dont on a besoin Après NB : Une nouvelle classe Symfony\Bundle\Fullstack pour vérifier si tout symfony est installé (plutôt que le mode composant par composant) 8/20

Slide 61

Slide 61 text

use Symfony\Component\Cache\Adapter\FilesystemAdapter; $cache = new FilesystemAdapter(); Avant Après simple cache 9/20 Implémentation de la PSR-16 (1/2)

Slide 62

Slide 62 text

use Symfony\Component\Cache\Adapter\FilesystemAdapter; $cache = new FilesystemAdapter(); // sauvegarder un élément en cache $numProducts = $cache->getItem('stats.num_products'); $numProducts->set(4711); $cache->save($numProducts); // sauvegarder un élément en cache $cache->set('stats.num_products', 4711); Avant Après simple cache 9/20 Implémentation de la PSR-16 (1/2)

Slide 63

Slide 63 text

use Symfony\Component\Cache\Adapter\FilesystemAdapter; $cache = new FilesystemAdapter(); // sauvegarder un élément en cache $numProducts = $cache->getItem('stats.num_products'); $numProducts->set(4711); $cache->save($numProducts); // sauvegarder un élément en cache $cache->set('stats.num_products', 4711); Avant Après // récupérer un élément du cache $numProducts = $cache->getItem('stats.num_products'); if (!$numProducts->isHit()) { // ... item does not exist in the cache } else { $total = $numProducts->get(); } // récupérer un élément du cache if (!$cache->has('stats.num_products')) { // ... item does not exist in the cache } else { $total = $cache->get('stats.num_products'); } simple cache 9/20 Implémentation de la PSR-16 (1/2)

Slide 64

Slide 64 text

use Symfony\Component\Cache\Adapter\FilesystemAdapter; $cache = new FilesystemAdapter(); // sauvegarder un élément en cache $numProducts = $cache->getItem('stats.num_products'); $numProducts->set(4711); $cache->save($numProducts); // sauvegarder un élément en cache $cache->set('stats.num_products', 4711); Avant Après // récupérer un élément du cache $numProducts = $cache->getItem('stats.num_products'); if (!$numProducts->isHit()) { // ... item does not exist in the cache } else { $total = $numProducts->get(); } // récupérer un élément du cache if (!$cache->has('stats.num_products')) { // ... item does not exist in the cache } else { $total = $cache->get('stats.num_products'); } // supprimer un élément du cache $cache->deleteItem('stats.num_products'); // supprimer un élément du cache $cache->delete('stats.num_products'); simple cache 9/20 Implémentation de la PSR-16 (1/2)

Slide 65

Slide 65 text

Implémentation de la PSR-16 (2/2) getMultiple($values) setMultiple($values, $ttl = null) deleteMultiple($values) 9/20

Slide 66

Slide 66 text

WebserverBundle • Code déplacé • $ bin/console server:start trouve un port disponible pour vous ! 10/20

Slide 67

Slide 67 text

Log automatique des erreurs console • Le listener se repose sur le standard PSR-3 pour la sortie. • Il suffit de configurer monolog pour adapter la sortie. 11/20

Slide 68

Slide 68 text

Beaucoup de nouveautés côté Dependency Injection

Slide 69

Slide 69 text

FQCN comme id de service services: app.manager.user: class: AppBundle\EventListener\UserManager tags: ['kernel.event_subscriber'] services: AppBundle\EventListener\UserManager: tags: ['kernel.event_subscriber'] use AppBundle\EventListener\UserManager; // ... public function editAction() { $this->get(UserManager::class)->save($user); } Avant Après use AppBundle\EventListener\UserManager; // ... public function editAction() { $this->get('app.manager.user')->save($user); } 12/20

Slide 70

Slide 70 text

La vie sans bundle Kernel::build() Enregistrer de la configuration Enregistrer les compiler pass Plus besoin d’enregistrer une classe de bundle 13/20

Slide 71

Slide 71 text

Importer un ensemble de fichiers de configuration imports: - { resource: "*.yml" } - { resource: "common/**/*.xml" } - { resource: "/etc/myapp/*.{yml,xml}" } - { resource: "bundles/*/{xml,yaml}/services.{yml,xml}" } glob pattern 14/20

Slide 72

Slide 72 text

Arguments nommés use Doctrine\ORM\EntityManager; use Psr\Log\LoggerInterface; namespace Acme; class NewsletterManager { private $logger; private $apiKey; public function __construct(LoggerInterface $logger, $apiKey) { $this->logger = $logger; $this->apiKey = $apiKey; } } services: newsletter_manager: class: Acme\NewsletterManager arguments: $apiKey: "%mandrill_api_key%" autowire: true 15/20

Slide 73

Slide 73 text

Implémentation de la PSR-11 16/20

Slide 74

Slide 74 text

Implémentation de la PSR-11 Symfony\Component\DependencyInjection\ContainerInterface étend la Psr\Container\ContainerInterface 16/20

Slide 75

Slide 75 text

Implémentation de la PSR-11 Symfony\Component\DependencyInjection\ContainerInterface étend la Psr\Container\ContainerInterface get() & has() 16/20

Slide 76

Slide 76 text

Implémentation de la PSR-11 Symfony\Component\DependencyInjection\ContainerInterface étend la Psr\Container\ContainerInterface get() & has() 2 nouvelles Exceptions : ContainerExceptionInterface & NotFoundExceptionInterface 16/20

Slide 77

Slide 77 text

Déclaration de service : Configuration par défaut pour tout un fichier services: _defaults: public: false autowire: true foo: class: Foo 17/20

Slide 78

Slide 78 text

Remplacement des wildcards pour les méthodes lors de l’autowiring services: _defaults: public: false autowire: ['set*'] foo: class: Foo Avant Après services: _defaults: public: false autowire: true foo: class: Foo Et class Foo { //… /** * @required */ public function setBar(Bar $bar) { // devrait être appelé } } https://github.com/symfony/symfony/pull/21763 bonus

Slide 79

Slide 79 text

Amélioration sur le panel config Avant 18/20

Slide 80

Slide 80 text

Amélioration sur le panel config Avant Après 18/20

Slide 81

Slide 81 text

Amélioration sur le panel config 19/20

Slide 82

Slide 82 text

Une petite dernière pour la route

Slide 83

Slide 83 text

README 20/20

Slide 84

Slide 84 text

No content

Slide 85

Slide 85 text

2 nouveaux composants

Slide 86

Slide 86 text

Composant Lock Gestion avancée du lock dans de nombreux systèmes (fichiers, redis, memcache). Ping Fabien Bourigault !

Slide 87

Slide 87 text

Composant Lock Gestion avancée du lock dans de nombreux systèmes (fichiers, redis, memcache). Ping Fabien Bourigault !

Slide 88

Slide 88 text

Composant Dotenv • On se doute un peu de ce qu’il fait ;) • « Superb error messages to easily spot any issue »

Slide 89

Slide 89 text

Composant Dotenv Charge, parse vos fichiers .env et popule vos variables d’environnement.

Slide 90

Slide 90 text

2 - 3 trucs à savoir

Slide 91

Slide 91 text

Symfony Demo 1.0.0 • Référence en matière de bonnes pratiques • Fork pour reproduire les bugs • Benchmark de performances • Montrer ce qui est possible avec http://symfony.com/blog/symfony-demo-1-0-0-released

Slide 92

Slide 92 text

Introduction des features expérimentales • Pour assurer la rétrocompatibilité (BC break promise) • Certaines features • @experimental http://symfony.com/blog/experimental-features

Slide 93

Slide 93 text

Make the Symfony ecosystem stronger and standardized

Slide 94

Slide 94 text

Make the Symfony ecosystem stronger and standardized

Slide 95

Slide 95 text

Make the Symfony ecosystem stronger and standardized

Slide 96

Slide 96 text

Topics sur Github http://symfony.com/blog/standardizing-the-github-topics-for-symfony-repositories 2-3 règles à suivre par là

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

Sans lui, nous passerions notre temps là dessus…

Slide 99

Slide 99 text

Sans lui, nous passerions notre temps là dessus…

Slide 100

Slide 100 text

' ( Merci Javi!

Slide 101

Slide 101 text

Un grand merci à toute cette communauté au topzer ! '

Slide 102

Slide 102 text

No content

Slide 103

Slide 103 text

Merci ! @catlannister

Slide 104

Slide 104 text

Merci ! @catlannister *NB : Symfony 4 requerra PHP 7