Slide 1

Slide 1 text

Here comes Symfony 6.3! @nicolasgrekas

Slide 2

Slide 2 text

symfony.com/releases @nicolasgrekas

Slide 3

Slide 3 text

Symfony 6 • PHP >= 8.1 • Upgrade every 6 months for features • Backward Compatibility promise • Upgrade every month for bug fixes @nicolasgrekas

Slide 4

Slide 4 text

Symfony 7 • PHP >= 8.2 • Upgrade every 2 years for new major • Continuous Upgrade Path promise • Fix deprecations every 6 months @nicolasgrekas

Slide 5

Slide 5 text

7 merges / day Since Nov 25th • 355 minors • 390 bug fixes • 223 features • 280 merges up • 42 releases @nicolasgrekas

Slide 6

Slide 6 text

Minors 🧹 @nicolasgrekas

Slide 7

Slide 7 text

Performance #48802 Cut compilation time #49781 Improve perf. of translation messages extraction #49676 Improve perf. of GlobResource @nicolasgrekas

Slide 8

Slide 8 text

./{apps,src}/**/*Controller.php @nicolasgrekas

Slide 9

Slide 9 text

Types #49383 Add missing return types to interfaces #49022 Add missing template annotation on ServiceLocator #48750 Add generics to PasswordUpgraderInterface @nicolasgrekas

Slide 10

Slide 10 text

+/** + * @template-covariant T of mixed + * @implements ServiceProviderInterface + */ class ServiceLocator implements ServiceProviderInterface, \Countable { @nicolasgrekas

Slide 11

Slide 11 text

PHPUnit 10 #49663 Remove withConsecutive() calls from tests #49233 Use PHPUnit 9.6 to run Symfony's test suite #48668 Migrate to static data providers #49253 Use TestCase suffix for abstract test cases @nicolasgrekas

Slide 12

Slide 12 text

- public function provideUidEntityClasses() + public static function provideUidEntityClasses() @nicolasgrekas

Slide 13

Slide 13 text

New syntax #48793 Leverage arrow function syntax for closure #48670 Use ::class #48069 Use ??= more @nicolasgrekas

Slide 14

Slide 14 text

- $this->class = get_class($object); + $this->class = $object::class; - $values = array_filter($values, function ($val) { return null !== $val; }); + $values = array_filter($values, fn ($val) => null !== $val); - if (null === $path) { - $path = '/'; - } + $path ??= '/'; @nicolasgrekas

Slide 15

Slide 15 text

Continuous Integration #49001 Speed up Psalm tests (12 to 2 minutes) #47180 Add ossf/scorecard GitHub action @nicolasgrekas

Slide 16

Slide 16 text

Features 🤩 @nicolasgrekas

Slide 17

Slide 17 text

📅 🗺 🤝 🕸 New components #47112 Add a Scheduler component #50112 Add AssetMapper to manage JS deps without nodejs #48542 Add the RemoteEvent and Webhook @nicolasgrekas https://speakerdeck.com/fabpot/

Slide 18

Slide 18 text

🔔️ Notifier #47373 Add Chatwork bridge #46395 Add Contact Everyone bridge #46724 Add SMSFactor bridge #49454 Add Pushover bridge #49461 Add MailerSend bridge #48855 Add PagerDuty bridge #48101 Add Mastodon bridge #48466 Add Line bridge #48389 Add Bandwidth bridge #48394 Add Plivo bridge #48397 Add RingCentral bridge #48398 Add Termii bridge #48399 Add iSendPro bridge #48084 Add Twitter bridge @nicolasgrekas

Slide 19

Slide 19 text

⌚ Clock #48642 Add Clock class and now() function #48362 Add ClockAwareTrait @nicolasgrekas use function Symfony\Component\Clock\now; $now = now(); // returns a DateTimeImmutable instance Clock::set(new MockClock()); // for testing

Slide 20

Slide 20 text

🕹️ Controllers #49358 Deprecate @route annotations in favor of attributes #48128 Add support for the 103 Early Hints and other 1XX #49134 Add #[MapQueryParameter] to map query parameters #49138 Add #[MapRequestBody] and #[MapQueryString] @nicolasgrekas

Slide 21

Slide 21 text

@nicolasgrekas // Matches /blog?page=1 #[Route(path: '/blog', name: 'blog')] public function index( #[MapQueryParameter(options: ['min_range' => 0])] int $page = 0, ) { // ...

Slide 22

Slide 22 text

@nicolasgrekas // Matches /blog?page=1 #[Route(path: '/blog', name: 'blog')] public function index( #[MapQueryParameter(options: ['min_range' => 1])] int $page = 0, ) { // ...

Slide 23

Slide 23 text

@nicolasgrekas #[Route('/product-review', methods: ['POST'])] public function post( #[MapRequestPayload] ProductReviewDto $productReview, ) { // ... 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, ) { // ...

Slide 24

Slide 24 text

🌽 HttpKernel #48352 #[WithHttpStatus] for defining status codes for exceptions #48747 #[WithLogLevel] for defining log levels for exceptions @nicolasgrekas #[WithHttpStatus(429, ['Retry-After' => 10])] #[WithLogLevel(LogLevel::INFO)] class RateLimitedException extends \Exception {

Slide 25

Slide 25 text

🌐 HttpClient @nicolasgrekas #49302 Add UriTemplateHttpClient to use RFC-6570 #49911 Support mime/multipart file uploads #49809 Allow using multiple base_uri as array for retries #50274 Set the minimum TLS version to v1.2

Slide 26

Slide 26 text

🛡️ Security #48272 OpenID Connect Token Handler #49300 Add #[NoSuspiciousCharacters] to spot spoofing attempt #49789 New #[PasswordStrength] constraint #49306 Add logout configuration for Clear-Site-Data header @nicolasgrekas Clear-Site-Data: "cookies"

Slide 27

Slide 27 text

🧙‍♂️ Dependency Injection 1/2 #47680 Remove parameters starting with a dot when compiling #47719 Add ContainerBuilder::deprecateParameter() #49411 Add support for #[AsAlias] during auto-discovery @nicolasgrekas

Slide 28

Slide 28 text

@nicolasgrekas #[AsAlias('my-alias', public: true)] #[AsAlias(MyInterface::class)] class MyService implements MyInterface {

Slide 29

Slide 29 text

🧙‍♀️ Dependency Injection 2/2 #46752 Generate lazy proxies out of the box #48484 Deprecate proxy-manager bridge #49685 Add support for #[Autowire(lazy: true)] #49628 Autowire services as closures with #[AutowireCallable] @nicolasgrekas

Slide 30

Slide 30 text

@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(...)

Slide 31

Slide 31 text

🫶 Developer eXperience #47352 Remove profiles automatically after two days #48059 Auto-create Doctrine migrations for sessions and locks #48707 Fail if #[Target] attribute does not exist during compilation #48938 Allow setting private services with the test container #48432 Add support of named arguments to dd() and dump() @nicolasgrekas

Slide 32

Slide 32 text

@nicolasgrekas static::getContainer() ->set('http_client.transport', new MockHttpClient(...)); dump(hello: 'World');

Slide 33

Slide 33 text

🎁 Various Goodies #49614 Add Request::getPayload(): array #49913 [Twig] Add {{ app.locale }} #49529 Add support for better signal handling in commands #49588 Render date/time form types using HTML5 by default @nicolasgrekas

Slide 34

Slide 34 text

Help Wanted See issues with "Help Wanted" label Contribute to the documentation! @nicolasgrekas

Slide 35

Slide 35 text

360+ contributors @nicolasgrekas

Slide 36

Slide 36 text

Backers for 6.3 @nicolasgrekas

Slide 37

Slide 37 text

symfony.com/ sponsor • Become a backer • Deploy on Platform.sh • Attend Symfony conferences • Get certified • Sign up for SymfonyInsight • Buy the Symfony book • Subscribe to SymfonyCasts @nicolasgrekas

Slide 38

Slide 38 text

symfony.com/slack Mutual aid Kindness CARE team @nicolasgrekas

Slide 39

Slide 39 text

Merci ! 🫶 @nicolasgrekas