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

Symfony 7: A tribute to Attributes

Symfony 7: A tribute to Attributes

In the ever-evolving landscape of web development, Symfony 7 stands out with its use of Attributes. This talk delves into the heart of Symfony 7, celebrating its innovative use of Attributes to simplify annotations, streamline configuration, and boost readability. We'll journey through examples showcasing the transformative power of Attributes in Symfony projects. Whether you're new to Symfony or a seasoned developer, join us to witness the synergy of modern PHP and Symfony's elegant architecture.

Nicolas Grekas

October 05, 2023
Tweet

More Decks by Nicolas Grekas

Other Decks in Programming

Transcript

  1. Backward Compatibility Promise • Upgrade every month for bug fixes

    • Upgrade every 6 months for features @nicolasgrekas "extra": { "symfony": { "require": "6.4.*" } }
  2. Continuous Upgrade Path • Fix deprecations every 6 months •

    Upgrade every 2 years for new major @nicolasgrekas "require": { "php": ">=8.2" }
  3. 🎉 Symfony 7 • Remove deprecated code paths • Add

    native return types • Add native types to public|protectedproperties @nicolasgrekas
  4. RIP Doctrine Annotations ⚠️ PHP 8 introduced attributes, which are

    a native replacement for annotations @nicolasgrekas
  5. 😍 #[Attributes] @nicolasgrekas #[Route(path: '/', name: 'home')] // return list<ReflectionAttribute>

    ReflectionMethod::getAttributes(); // return new Route(path: '/', name: 'home'); ReflectionAttribute::newInstance(); // return ['path' => '/', 'name' => 'home']; ReflectionAttribute::getArguments();
  6. Attributes are ignorable; they don't create coupling Attributes are useful

    hints telling how some code could be used @nicolasgrekas
  7. @nicolasgrekas services: _defaults: autowire: true # Look at parameter types

    to auto-inject deps autoconfigure: true # Look at parent types to auto-register classes # Load every class in a namespace/directory as a service App\: resource: '../src/' # Add more service definitions when explicit configuration is needed config/services.yaml
  8. @nicolasgrekas Just Enjoy on your side #[AsEventListener] class MyRequestListener {

    public function __invoke(RequestEvent $event): void { // ... } }
  9. @nicolasgrekas Enjoy your rules class ChannelBroadcaster { public function __construct(

    #[AutowireIterator(ChannelInterface::class)] iterable $channels ) { // ... }
  10. @nicolasgrekas #[Autoconfigure(lazy: true)] class PlotFactory { public function __construct( #[Autowire(param:

    'kernel.debug')] private bool $debug, private HeavyDependency $heavyDependency, ) { } }
  11. @nicolasgrekas public function __construct( #[AutowireCallable(UriTemplate::class, 'expand')] UriExpanderInterface $expander, ) new

    class($uriTemplate->expand(...)) implements UriExpanderInterface { public function __construct( private \Closure $closure, ) { } public function expand(string $url, array $vars): string { return $this->closure->__invoke($url, $vars); } } $uriTemplate->expand(...)
  12. @nicolasgrekas class ProductReviewDto { public function __construct( #[Assert\NotBlank] #[Assert\Length(min: 10,

    max: 500)] public readonly string $comment, #[Assert\GreaterThanOrEqual(1)] #[Assert\LessThanOrEqual(5)] public readonly int $rating, ) { // ...