Symfony 7.3 includes many small improvements aimed at making developers' lives easier and more productive. This blog post highlights some of the most useful DX (Developer Experience) features added in this release.
Read the second part of this blog post.
Collect All Twig Deprecations
The lint:twig
command checks the syntax of your Twig templates and reports
any errors and deprecations. Previously, it only reported the first deprecation
found, so you had to run it repeatedly to list all of them.
In Symfony 7.3, this command has been improved to report all deprecations at once:
1 2 3 4 5 6 7 8
$ php bin/console lint:twig --show-deprecations
DEPRECATION in /app/templates/index.html.twig (line 5)
>> Since foo/bar 1.1: Twig filter "deprecated_filter" is deprecated
DEPRECATION in /app/templates/index.html.twig (line 6)
>> Since foo/bar 1.1: Twig filter "deprecated_filter" is deprecated
[OK] All 2 Twig files contain valid syntax.
Transform Strings to Pascal Case
The String component provides several methods to transform the case of a string
(lower()
, upper()
, camel()
, snake()
, kebab()
). In Symfony 7.3,
a new pascal()
method has been added to convert strings to PascalCase:
1 2 3 4
// before Symfony 7.3
u('Foo: Bar-baz.')->camel()->title(); // 'FooBarBaz'
// in Symfony 7.3
u('Foo: Bar-baz.')->pascal(); // 'FooBarBaz'
Field id
Form Helper
Rendering the id
attribute of a form field is a common need in templates.
You can already access it via the vars
array of each form field, but Symfony 7.3
introduces a new Twig function to simplify this:
1 2 3 4 5
{# before Symfony 7.3 #}
<input id="{{ form.task.vars.id }}" ... />
{# in Symfony 7.3 #}
<input id="{{ field_id(form.task) }}" ... />
noStore
Cache Argument
The #[Cache]
attribute allows you to configure various HTTP Cache options.
In Symfony 7.3, it has been improved to support the no-store response directive,
which tells caches not to store any part of the request or response:
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\HttpKernel\Attribute\Cache;
#[Cache(noStore: true)]
final class MyController
{
public function __invoke(): Response
{
// This response will NOT be stored in ANY cache
}
}
Union Types in Options Resolver
The OptionsResolver component lets you define allowed types for options.
Until now, you could only pass an array of basic types (e.g. ['int', 'string']
),
but not actual union types like (int|string)[]
.
However, sometimes you have to use the union type (e.g. (int|string)[]
)
because you can't define the same type information using arrays
(e.g. ['string[]', 'int[]']
is not equivalent).
Symfony 7.3 now fully supports PHP-style union types when defining option types.
Improved ImportMap Require Command
The importmap:require
command lets you import third-party JavaScript and CSS packages
when using AssetMapper. In Symfony 7.3, this command has been enhanced with a
--dry-run
option, so you can preview the packages to be installed:
1
$ php bin/console importmap:require --dry-run bootstrap
Clock Mock in URI Signer
Symfony provides a utility to sign URIs, which can include an expiration date.
In Symfony 7.3, the Clock component has been integrated with UriSigner
so
you can mock the current time in your tests, making them simpler and more reliable.
DatePoint
Doctrine Type
The DatePoint
class was introduced in Symfony 6.4 as a modern alternative
to DateTime
and DateTimeImmutable
. However, Doctrine couldn't use it as a
field type directly.
Symfony 7.3 introduces a DatePointType
that you can now use in your entities:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Entity/Product.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Clock\DatePoint;
#[ORM\Entity]
class Product
{
#[ORM\Column]
private DatePoint $created;
// ...
}