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

Get ready for Symfony 4

Get ready for Symfony 4

Christian Flothmann

February 23, 2017
Tweet

More Decks by Christian Flothmann

Other Decks in Programming

Transcript

  1. Christian Flothmann Symfony Core Team & Documentation Team work at

    SensioLabs Germany github.com/xabbuh @xabbuh
  2. • one patch release a month • minor releases twice

    a year • new major releases every two years • N.4 at the same time as (N+1).0 • N.4 is an LTS release The Symfony Release Cycle http://symfony.com/roadmap
  3. • new component • reads .env files • makes them

    available through getenv(), $_SERVER, and $_ENV Dotenv
  4. Loading a .env file $loader = require __DIR__.'/../app/autoload.php'; use Symfony\Component\Dotenv\Dotenv;

    if (file_exists(__DIR__.'/../.env')) { $dotenv = new Dotenv(); $dotenv->load(__DIR__.'/../.env'); } Debug::enable(); $kernel = new AppKernel('dev', true); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response);
  5. • compatible with PSR-16 o simple caching Layer o support

    to convert PSR-16 caches to PSR-6 adapters and vice versa • Memcached Support Cache
  6. Cache – PSR-6 interface CacheItemInterface { public function getKey(); public

    function get(); public function isHit(); public function set($value); public function expiresAt($expiration); public function expiresAfter($time); }
  7. Cache – PSR-6 interface CacheItemPoolInterface { public function getItem($key); public

    function getItems(array $keys = array()); public function hasItem($key); public function clear(); public function deleteItem($key); public function deleteItems(array $keys); public function save(CacheItemInterface $item); public function saveDeferred(CacheItemInterface $item); public function commit(); }
  8. Cache – PSR-16 interface CacheInterface { public function get($key, $default

    = null); public function set($key, $value, $ttl = null); public function delete($key); public function clear(); public function getMultiple($keys, $default = null); public function setMultiple($values, $ttl = null); public function deleteMultiple($keys); public function has($key); }
  9. Cache – Using PSR-16 Caches use Symfony\Component\Cache\Simple\FilesystemCache; $cache = new

    FilesystemCache(); $cache->set('stats.num_products', 4711, 3600); if (!$cache->has('stats.num_products')) { // ... item does not exists in the cache } $numProducts = $cache->get( 'stats.num_products‘, 100 ); $cache->delete('stats.num_products'); $cache->clear();
  10. Importing config files in Symfony 3.2 imports: - { resource:

    parameters.yml } - { resource: security.yml } - { resource: services.yml } - { resource: admin/ }
  11. Importing config files using glob patterns imports: - { resource:

    "*.yml" } - { resource: "common/**/*.xml" } - { resource: "/etc/myapp/*.{yml,xml}" } - { resource: "bundles/*/{xml,yaml}/services.{yml,xml}" } Support for double star (**) in glob patterns is part of the Finder component in 3.3.
  12. • class is optional, falls back to id • support

    for default values per file • inheritance of tags from parent definition Configuration improvements
  13. Verbose config before Symfony 3.3 services: app.voter: abstract: true autowire:

    true public: false app.category_voter: class: AppBundle\Security\CategoryVoter parent: app.voter tags: [ { name: security.voter } ] app.comment_voter: class: AppBundle\Security\CommentVoter parent: app.voter tags: [ { name: security.voter } ] app.post_voter: class: AppBundle\Security\PostVoter parent: app.voter tags: [ { name: security.voter } ]
  14. Shortened config with Symfony 3.3 services: _defaults: autowire: true public:

    false tags: - name: security.voter AppBundle\Security\CategoryVoter: ~ AppBundle\Security\CommentVoter: ~ AppBundle\Security\PostVoter: ~
  15. Inheriting tags in Symfony 3.3 services: _defaults: autowire: true public:

    false inherit_tags: true app.voter: abstract: true tags: [ { name: security.voter } ] AppBundle\Security\CategoryVoter: parent: app.voter AppBundle\Security\CommentVoter: parent: app.voter AppBundle\Security\PostVoter: parent: app.voter AppBundle\Security\UserProvider: inherit_tags: false
  16. Simplifying the voter example services: _defaults: autowire: true public: false

    tags: - name: security.voter AppBundle\Security\CategoryVoter: ~ AppBundle\Security\CommentVoter: ~ AppBundle\Security\PostVoter: ~
  17. Getter injection abstract class NewsletterManager { abstract protected function getMailer():

    MailerInterface; protected function getLogger(): LoggerInterface { return new NullLogger(); } // ... }
  18. Inheriting tags in Symfony 3.3 services: _defaults: autowire: true public:

    false inherit_tags: true app.voter: abstract: true tags: [ { name: security.voter } ] AppBundle\Security\CategoryVoter: parent: app.voter AppBundle\Security\CommentVoter: parent: app.voter AppBundle\Security\PostVoter: parent: app.voter AppBundle\Security\UserProvider: inherit_tags: false
  19. Interface based attribute configuration services: _defaults: autowire: true public: false

    _instanceof: Symfony\Component\Security\Core\Authorization\Voter\Voter: tags: [ { name: security.voter } ] AppBundle\Security\CategoryVoter: ~ AppBundle\Security\CommentVoter: ~ AppBundle\Security\PostVoter: ~ AppBundle\Security\UserProvider: ~
  20. • component is to be removed • use Composer instead

    • (or any other PSR-4 compatible autoloader package) ClassLoader
  21. • service identifiers are case sensitive • invalid options (YAML

    format) lead to exceptions • private services are not accessible through Container::has() or Container::get(), inject them if needed DependencyInjection
  22. DefinitionDecorator is deprecated $mailer = $container->register('mailer', 'Mailer'); $mailer->setAbstract(true); $smtpMailer =

    new DefinitionDecorator('mailer'); $smtpMailer->setArguments([ 'username' => 'foo', 'password' => 'bar', ]); $container->setDefinition('mailer1', $smtpMailer);
  23. Use ChildDefinition instead $mailer = $container->register('mailer', 'Mailer'); $mailer->setAbstract(true); $smtpMailer =

    new ChildDefinition ('mailer'); $smtpMailer->setArguments([ 'username' => 'foo', 'password' => 'bar', ]); $container->setDefinition('mailer1', $smtpMailer);
  24. • choices_as_values option removed • part of BC layer of

    Symfony 2.7 • deprecated since Symfony 3.1 ChoiceType
  25. Callable as string, before Symfony 4 public function buildForm( FormBuilderInterface

    $builder, array $options ) { $builder->add( 'categories', ChoiceType::class, [ 'choice_label' => 'strtolower', ] ); }
  26. Callables in Symfony 4 public function buildForm( FormBuilderInterface $builder, array

    $options ) { $builder->add( 'categories', ChoiceType::class, [ 'choice_label' => function ($choice) { return strtolower($choice); }, ] ); }
  27. Before Symfony 4 $form = $this->createForm( UserType::class, $user ); $form->handleRequest($request);

    if ($form->isValid()) { // do something with // the submitted data }
  28. Symfony 4 $form = $this->createForm( UserType::class, $user ); $form->handleRequest($request); if

    ( $form->isSubmitted() && $form->isValid() ) { // do something with // the submitted data }
  29. • lots of methods are final • don‘t override them

    in custom response classes Response
  30. • isMethodSafe() doesn‘t check for cacheable methods • HEAD and

    GET are cacheable • OPTIONS and TRACE are safe too Request
  31. Check for safe methods // note: true necessary only for

    // BC in Symfony 3.x if ( $request->isMethodSafe(true) ) { // true for GET, HEAD, // OPTIONS, and TRACE }
  32. • RoleInterface removed • use strings for roles • not

    recommend: extending the Role class o Role class likely to be removed too Security
  33. strict option defaults to true /** * @Assert\Choice( * choices

    = { * "male", "female“ * }, * strict = true * ) */
  34. • mapping keys must be unique • colons separating keys

    and values need a following space • strings starting with % must be quoted Parser changes
  35. • dropped boolean arguments of Yaml::parse() • dropped boolean arguments

    of Yaml::dump() • use flags instead API changes
  36. Parsing/dumping before Yaml::parse( '{ "foo": "bar", "foobar": "baz" }', true,

    true, true ); Yaml::dump( array('foo' => new A(), 'bar' => 1), 2, 4, true, true );
  37. Parsing/dumping with Symfony 4 Yaml::parse( '{ "foo": "bar", "foobar": "baz"

    }', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE | Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP ); Yaml::dump( array('foo' => new A(), 'bar' => 1), 2, 4, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE | Yaml::DUMP_OBJECT );