[SymfonyCon Berlin] A year of Symfony

34ade09dd3d11004ca8ee4174fd3d6a2?s=47 Sarah KHALIL
December 03, 2016

[SymfonyCon Berlin] A year of Symfony

Last year, Symfony 3 was out right before the SymfonyCon. A lot happened! 52 blog posts to help you keep up with all new things, 1200+ pull requests, 2 new versions out… Well I'm sure you missed something. Let's review what happened during last year: basically we'll see and/or discover nice new features that appeared since the last SymfonyCon.

34ade09dd3d11004ca8ee4174fd3d6a2?s=128

Sarah KHALIL

December 03, 2016
Tweet

Transcript

  1. @saro0h Sarah Khalil A year of

  2. A year ago…

  3. None
  4. None
  5. 2 main axes in this conference

  6. 1. Community

  7. 1. Community

  8. 2. Features

  9. 2. Features

  10. 2. Features

  11. Community

  12. A week of Symfony Every week!

  13. A new core contributor Grégoire Pineau Merger on the Workflow

    component
  14. Pull requests 1,282 merged 2,411 opened

  15. Issues 1,438 closed

  16. 57 versions 2.6.x 1 version 2.7.x 14 versions 2.8.x 14

    versions 3.0.x 9 versions 3.1.x 10 versions 3.2.x 4 versions ➡ ➡ ➡ ➡ ➡ ➡ Releases
  17. New way of releasing Symfony • A new minor version

    every 6 months • in november and may, usually at the end of the month • A new major version every 2 years • released at the same time as the last minor version
  18. SymfonyLive Cancelled

  19. Virtual hackdays

  20. Documentation Mercury project,150 hours of great work.

  21. None
  22. Getting started: all basics about developing apps with Symfony.

  23. Getting started: all basics about developing apps with Symfony. Components:

    all about the standalone Symfony libraries. Bundles: commonly used bundles when developing Symfony apps. Reference: Form types, DI tags & Symfony configuration.
  24. Getting started: all basics about developing apps with Symfony. Guides

    and tutorials: Everything else. Components: all about the standalone Symfony libraries. Bundles: commonly used bundles when developing Symfony apps. Reference: Form types, DI tags & Symfony configuration.
  25. http://symfony.com/blog/the-new-symfony-documentation-search-engine Wanna use Algolia?

  26. Influence of and many others…

  27. Influence of and many others…

  28. None
  29. 3.1 I chose 11 features

  30. None
  31. Deprecation helper improvements Detection of deprecation are done thanks to

    the PHPUnit bridge. <!-- phpunit.xml --> <phpunit> <!-- ... --> <php> <server name="KERNEL_DIR" value="app/" /> <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" /> </php> </phpunit> … 3.1
  32. « disabled » PHPUnit won’t list the deprecations ; avoid

    your test suite failing. Deprecation helper improvements Detection of deprecation are done thanks to the PHPUnit bridge. <!-- phpunit.xml --> <phpunit> <!-- ... --> <php> <server name="KERNEL_DIR" value="app/" /> <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" /> </php> </phpunit> … 3.1
  33. « /Passing callable strings .*/ » Will be matched as

    a regular expression against the deprecation message. « disabled » PHPUnit won’t list the deprecations ; avoid your test suite failing. Deprecation helper improvements Detection of deprecation are done thanks to the PHPUnit bridge. <!-- phpunit.xml --> <phpunit> <!-- ... --> <php> <server name="KERNEL_DIR" value="app/" /> <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" /> </php> </phpunit> … 3.1
  34. « 10 » Test suite will fail if 10 or

    more deprecations are triggered. « /Passing callable strings .*/ » Will be matched as a regular expression against the deprecation message. « disabled » PHPUnit won’t list the deprecations ; avoid your test suite failing. Deprecation helper improvements Detection of deprecation are done thanks to the PHPUnit bridge. <!-- phpunit.xml --> <phpunit> <!-- ... --> <php> <server name="KERNEL_DIR" value="app/" /> <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" /> </php> </phpunit> … 3.1
  35. • Implementation of the PSR-6 - Caching interface standard. •

    Cache arbitrary content in your application. • Symfony components use it to improve their performances. New component: Cache 3.1 class BlogController extends Controller { public function indexAction() { // create a new item and getting it from the cache $cachedCategories = $this->get('cache.app')->getItem('categories'); if (!$cachedCategories->isHit()) { $categories = ... // fetch categories from the database $cachedCategories->set($categories); $this->get('cache.app')->save($cachedCategories); } else { $categories = $cachedCategories->get(); } // ... } } Adapters for common backends Redis, APCu, Memcache…
  36. • Implementation of the PSR-6 - Caching interface standard. •

    Cache arbitrary content in your application. • Symfony components use it to improve their performances. New component: Cache 3.1 class BlogController extends Controller { public function indexAction() { // create a new item and getting it from the cache $cachedCategories = $this->get('cache.app')->getItem('categories'); if (!$cachedCategories->isHit()) { $categories = ... // fetch categories from the database $cachedCategories->set($categories); $this->get('cache.app')->save($cachedCategories); } else { $categories = $cachedCategories->get(); } // ... } } Adapters for common backends Redis, APCu, Memcache…
  37. Display forwards and redirects in the WDT and the profiler

    3.1 Forward Redirect
  38. Security profiler panel improvements 3.1

  39. Security profiler panel improvements 3.1

  40. WDT: Color coded HTTP status for ajax requests 3.1

  41. WDT: Color coded HTTP status for ajax requests 3.1

  42. Profiler: Silenced errors in logs 3.1

  43. Profiler: Filters in requests 3.1

  44. Profiler: Filters in requests 3.1

  45. YAML deprecation 3.1 framework: secret: %secret% framework: secret: '%secret%' parameters:

    my_object: '!php/object:O:27:"AppBundle\Service\MyService":1:{s:1:"b";s:3:"foo";}' parameters: my_object: '!!php/object:O:27:"AppBundle\Service\MyService":1:{s:1:"b";s:3:"foo";}'
  46. Process: Input stream 3.1 use Symfony\Component\Process\Process; $process = new Process('cat');

    $process->setInput('file.txt'); $process->run(); use Symfony\Component\Process\InputStream; $input = new InputStream(); $input->write('foo'); $process = new Process('my_script'); $process->setInput($input); $process-> start(); // ... read process output or do other things $input->write('bar'); // ... read process output or do other things $input->write('qux'); $input-> close(); before Cannot provide more input now
  47. Process: Output stream 3.1 Process::OUT Process::ERR or

  48. Process: Output stream 3.1 Process::OUT Process::ERR or use Symfony\Component\Process\Process; $process

    = new Process('ls -lsa'); $process->start(); foreach ($process as $type => $data) { if ($process::OUT === $type) { echo $data."\n"; } else { echo "[ERR] ".$data."\n"; } } returns an iterator
  49. Process: Output stream 3.1 Process::OUT Process::ERR or use Symfony\Component\Process\Process; $process

    = new Process('ls -lsa'); $process->start(); foreach ($process as $type => $data) { if ($process::OUT === $type) { echo $data."\n"; } else { echo "[ERR] ".$data."\n"; } } returns an iterator
  50. 3.2

  51. « Saisissez une citation ici. »

  52. use Symfony\Bundle\FrameworkBundle\Controller\Controller; class DefaultController extends Controller { public function downloadAction()

    { $pdfPath = $this->getParameter('dir.downloads').'/my_file.pdf'; return $this->file($pdfPath, ‘my_new_filename.pdf’, ResponseHeaderBag::DISPOSITION_INLINE); } } New file method helper protected function file($file, $fileName = null, $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT) 3.2
  53. YAML supports PHP constants parameters: # this is considered a

    regular string foo: PHP_INT_MAX # this is considered a PHP constant bar: !php/const:PHP_INT_MAX 3.2
  54. Compiler pass improvements 1/2 // in compiler pass before 3.2

    $warmers = array(); foreach ($container->findTaggedServiceIds('kernel.cache_warmer') as $id => $attributes) { $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; $warmers[$priority][] = new Reference($id); } krsort($warmers); $warmers = call_user_func_array('array_merge', $warmers); // since 3.2 $warmers = $this->findAndSortTaggedServices('kernel.cache_warmer', $container); 3.2
  55. Compiler pass improvements 2/2 3.2 $container->addCompilerPass(new CustomPass(), PassConfig::TYPE_AFTER_REMOVING , 30

    ); Step Priority
  56. New form type: DateInterval 3.2 ->add('remindEvery', DateIntervalType::class, array( 'placeholder' =>

    array('years' => 'Years', 'months' => 'Months', 'days' => 'Days'), 'widget' => 'choice', // customize which text boxes are shown 'with_years' => true, 'with_months' => true, 'with_days' => true, 'with_hours' => false, ))
  57. Tagged cache $cache = new FilesystemAdapter(); $review = $cache->getItem('reviews-'.$reviewId); $review->set('...');

    $review->tag(['reviews', 'products', 'product-'.$productId]); $cache->save($review); //… // the HTML structure of reviews has changed: // invalidate all reviews $cache->invalidateTags('reviews'); // instead of $cache->deleteItem('reviews-'.$reviewId); 3.2
  58. Routing improvement 3.2 // generating a URL with a fragment

    $this->get('router')->generate('user_settings', ['_fragment' => 'password']); /settings#password // route definition /** * @Route("/settings", defaults={"_fragment" = "password"}, name="user_settings") */ public function settingsAction() { ... }
  59. YAML deprecations • No more duplicated keys otherwise you’ll get

    a ParseException 3.2 parameters: foo: bar parameters: key: 'aaa' # ... key: 'bbb' • Always put a space after colon otherwise you’ll get a ParseException
  60. Runtime Environment variable What’s new? • No longer obliged to

    prefix them by SYMFONY__ • The value is resolved at runtime! (the app has the updated value) 3.2 doctrine: dbal: # ... password: "%env(DB_PASSWORD)%" To set default value and avoid not set env variable: parameters: env(DB_PASSWORD): s3cr3t_p4ssw0rd
  61. Console improvements 3.2 $output->writeln('<fg=green;options=bold,underscore>Test</>'); Multiple text style options Hidden commands

    namespace AppBundle\Command; use Symfony\Component\Console\Command\Command; class FooCommand extends Command { protected function configure() { $this ->setName('app:foo') // ... ->setHidden(true) ; } }
  62. Serializer: CSV encoder 3.2 // instantiation, when using it inside

    the Symfony framework $serializer = $container->get('serializer'); $data = [ 'foo' => 'aaa', 'bar' => [ ['id' => 111, 1 => 'bbb'], ['lorem' => 'ipsum'], ] ]; file_put_contents( 'data.csv', $container->get('serializer')->encode($data, 'csv') ); // decoding CSV contents $data = $serializer->decode(file_get_contents('data.csv'), 'csv');
  63. Serializer: YAML encoder 3.2 $obj = new \stdClass(); $obj->bar =

    2; $data = $this->container->get('serializer')->encode( ['foo' => $obj], 'yaml' // these are the default values applied by the encoder ['yaml_inline' => 1, 'yaml_indent' => 4, 'yaml_flags' => 0] ); // $data = ' foo: !php/object:O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}\n'; $data = $this->container->get('serializer')->decode( 'foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml' ); // $data = ['foo' => $obj];
  64. Cache improvements 3.2

  65. Get information about the firewall 1/2 • Symfony\Bundle\SecurityBundle\Security\FirewallConfig • name,

    provider, context, entrypoint, access denied URL… 3.2
  66. Get information about the firewall 2/2 3.2

  67. Get information about the firewall 2/2 3.2

  68. Translation improvements // Before $this->get('translator') ->transChoice('1 apple|%count% apples', 7, ['%count%'

    => 7]); // After $this->get('translator') ->transChoice('1 apple|%count% apples', 7); 3.2 ./bin/console translation:update en --force --domain=admin
  69. Support for PhpStorm links (\o/) 3.2 # app/config/config.yml framework: ide:

    'phpstorm://open?file=%%f&line=%%l
  70. Source link 3.2

  71. Unicode routing support UTF-8 characters in route paths and requirements

    /** * @Route( * "/category/{name}", * "requirements" = { "name": "䴰ᬨ|بيحرت" } * "options" = { "utf8": true } * ) */ public function categoryAction($name) { // ... } /category/䴰ᬨ, /category/بيحرت 3.2
  72. Unicode routing support UTF-8 characters in route paths and requirements

    /** * @Route( * "/category/{name}", * "requirements" = { "name": "䴰ᬨ|بيحرت" } * "options" = { "utf8": true } * ) */ public function categoryAction($name) { // ... } /category/䴰ᬨ, /category/بيحرت not needed before 4.0 is able to detect UTF-8 3.2
  73. • Implementation of the petri net (Transitions, places…) • Supports

    state machine New component: Workflow 3.2
  74. • Implementation of the petri net (Transitions, places…) • Supports

    state machine New component: Workflow https://speakerdeck.com/lyrixx/le-reveil-du-workflow 3.2
  75. • Implementation of the petri net (Transitions, places…) • Supports

    state machine New component: Workflow https://speakerdeck.com/lyrixx/le-reveil-du-workflow https://speakerdeck.com/tucksaun/symfonylive-london-2016-the-workflow-awakens 3.2
  76. • Implementation of the petri net (Transitions, places…) • Supports

    state machine New component: Workflow https://speakerdeck.com/lyrixx/le-reveil-du-workflow https://speakerdeck.com/tucksaun/symfonylive-london-2016-the-workflow-awakens https://speakerdeck.com/saro0h/openclassrooms-workflow-component 3.2
  77. Better support for one command applications 3.2 use Symfony\Component\Console\Application; $command

    = new \FooCommand(); $application = new Application(); $application->add($command); // the second boolean argument tells if this is a single-command app $application->setDefaultCommand($command->getName(), true); // this now executes the 'FooCommand' without passing its name $application->run();
  78. Simpler command testing 3.2 use Symfony\Component\Console\Tester\CommandTester; $commandTester = new CommandTester($command);

    $helper = $command->getHelper('question'); $helper->setInputStream($this->getInputStream("123\nfoo\nbar\n")); protected function getInputStream($input) { $stream = fopen('php://memory', 'r+', false); fputs($stream, $input); rewind($stream); return $stream; } use Symfony\Component\Console\Tester\CommandTester; $commandTester = new CommandTester($command); $commandTester->setInputs(['123', 'foo', 'bar']);
  79. Thank you Javier. Without you… our life would be…

  80. Thank you Javier. Without you… our life would be…

  81. " # Thank you Javi!

  82. Big thank to this amazing community "

  83. See ya next year! @catlannister