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

[SymfonyCon Berlin] A year of Symfony

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.

Sarah KHALIL

December 03, 2016
Tweet

More Decks by Sarah KHALIL

Other Decks in Technology

Transcript

  1. @saro0h
    Sarah Khalil
    A year of

    View full-size slide

  2. A year ago…

    View full-size slide

  3. 2 main axes in this
    conference

    View full-size slide

  4. 1. Community

    View full-size slide

  5. 1. Community

    View full-size slide

  6. A week of Symfony
    Every week!

    View full-size slide

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

    View full-size slide

  8. Pull requests
    1,282 merged
    2,411 opened

    View full-size slide

  9. Issues
    1,438 closed

    View full-size slide

  10. 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

    View full-size slide

  11. 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

    View full-size slide

  12. SymfonyLive
    Cancelled

    View full-size slide

  13. Virtual hackdays

    View full-size slide

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

    View full-size slide

  15. Getting started: all basics about
    developing apps with Symfony.

    View full-size slide

  16. 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.

    View full-size slide

  17. 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.

    View full-size slide

  18. http://symfony.com/blog/the-new-symfony-documentation-search-engine
    Wanna use Algolia?

    View full-size slide

  19. Influence of
    and many others…

    View full-size slide

  20. Influence of
    and many others…

    View full-size slide

  21. 3.1
    I chose 11 features

    View full-size slide

  22. Deprecation helper improvements
    Detection of deprecation are done thanks to the PHPUnit bridge.









    3.1

    View full-size slide

  23. « 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.









    3.1

    View full-size slide

  24. « /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.









    3.1

    View full-size slide

  25. « 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.









    3.1

    View full-size slide

  26. • 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…

    View full-size slide

  27. • 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…

    View full-size slide

  28. Display forwards and redirects in the
    WDT and the profiler
    3.1
    Forward Redirect

    View full-size slide

  29. Security profiler panel improvements 3.1

    View full-size slide

  30. Security profiler panel improvements 3.1

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. Profiler: Silenced errors in logs 3.1

    View full-size slide

  34. Profiler: Filters in requests 3.1

    View full-size slide

  35. Profiler: Filters in requests 3.1

    View full-size slide

  36. 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";}'

    View full-size slide

  37. 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

    View full-size slide

  38. Process: Output stream 3.1
    Process::OUT
    Process::ERR
    or

    View full-size slide

  39. 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

    View full-size slide

  40. 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

    View full-size slide

  41. « Saisissez une citation ici. »

    View full-size slide

  42. 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

    View full-size slide

  43. 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

    View full-size slide

  44. 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

    View full-size slide

  45. Compiler pass improvements 2/2 3.2
    $container->addCompilerPass(new CustomPass(), PassConfig::TYPE_AFTER_REMOVING , 30 );
    Step
    Priority

    View full-size slide

  46. 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,
    ))

    View full-size slide

  47. 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

    View full-size slide

  48. 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() { ... }

    View full-size slide

  49. 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

    View full-size slide

  50. 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

    View full-size slide

  51. Console improvements 3.2
    $output->writeln('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)
    ;
    }
    }

    View full-size slide

  52. 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');

    View full-size slide

  53. 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];

    View full-size slide

  54. Cache improvements 3.2

    View full-size slide

  55. Get information about the firewall 1/2
    • Symfony\Bundle\SecurityBundle\Security\FirewallConfig
    • name, provider, context, entrypoint, access denied URL…
    3.2

    View full-size slide

  56. Get information about the firewall 2/2 3.2

    View full-size slide

  57. Get information about the firewall 2/2 3.2

    View full-size slide

  58. 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

    View full-size slide

  59. Support for PhpStorm links (\o/) 3.2
    # app/config/config.yml
    framework:
    ide: 'phpstorm://open?file=%%f&line=%%l

    View full-size slide

  60. Source link 3.2

    View full-size slide

  61. 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

    View full-size slide

  62. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  65. • 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

    View full-size slide

  66. • 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

    View full-size slide

  67. 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();

    View full-size slide

  68. 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']);

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  71. " #
    Thank you Javi!

    View full-size slide

  72. Big thank to this amazing community
    "

    View full-size slide

  73. See ya next year!
    @catlannister

    View full-size slide