Home / Symfony / New in Symfony 7.4: DX Improvements (Part 1)

New in Symfony 7.4: DX Improvements (Part 1)

Developer Experience (DX) refers to how smooth and efficient it feels to work
with a framework or tool. In Symfony 7.4, we’ve added many small DX improvements,
and this post highlights some of them.

Question Helper Timeout


Jan Nedbal
Contributed by
Jan Nedbal
in
#61092

The Question helper from the Console component provides utilities to ask
users for input. In Symfony 7.4, you can now set a timeout for questions.
If the user doesn’t respond within the specified time, a MissingInputException
will be thrown:

use SymfonyComponentConsoleExceptionMissingInputException;
use SymfonyComponentConsoleQuestionConfirmationQuestion;

// ...
public function __invoke(InputInterface $input, OutputInterface $output): int
{
    // ...
    $helper = new QuestionHelper();

    $question = new ConfirmationQuestion('Restart the server?', false);
    $question->setTimeout(10); // user must confirm in 10 seconds or less
}

Enum Type Guesser for Forms


Matthias Schmidt
Contributed by
Matthias Schmidt
in
#61297

The Symfony Form component uses type guessers to decide which form types to
use for fields that don’t define their type explicitly. In Symfony 7.4, we added
a new type guesser for PHP enums.

You no longer need to define enum fields manually. Symfony will automatically use
the EnumType class and set its class option whenever it finds an enum field.

New Command to Generate OIDC Tokens


Hubert Lenoir
Contributed by
Hubert Lenoir
in
#60660

In Symfony 6.3, we introduced an OpenID Connect Token Handler that allows you
to decode JWT tokens, validate them, and extract user information. In Symfony 7.4,
we’re adding a command to generate JWTs, which is useful for testing and development:

$ php bin/console security:oidc-token:generate [email protected] 
      --firewall="api" 
      --algorithm="HS256" 
      --issuer="https://example.com" 
      --ttl=7200 
      --not-before=tomorrow

Default Locale Outside HTTP Context


Mathieu
Contributed by
Mathieu
in
#62010

When generating URLs outside the HTTP context, there are special challenges,
such as defining the hostname or locale. In Symfony 7.4, the
kernel.default_locale parameter is now also used as the default locale when
generating URLs outside HTTP requests.

New Helpers for BrowserKit


Santiago San Martin
Contributed by
Santiago San Martin
in
#60895
and #60955

The BrowserKit component simulates the behavior of a web browser, allowing
you to make requests, click links, and submit forms programmatically. In Symfony
7.4, it adds two new helpers:

  • isFirstPage(): returns true if the current position is at the start
    of the history stack.
  • isLastPage(): returns true if the current position is at the end
    of the history stack.

These are especially useful in tests, so we also added a few new PHPUnit constraints:

$this->assertBrowserHistoryIsOnFirstPage();
$this->assertBrowserHistoryIsNotOnFirstPage();
$this->assertBrowserHistoryIsOnLastPage();
$this->assertBrowserHistoryIsNotOnLastPage();

Better Dumps in non-HTML Contexts


Alexandre Daubois
Contributed by
Alexandre Daubois
in
#58070

In Symfony 7.4, we improved exceptions in the terminal to avoid rendering
them as HTML. Similarly, the dd() and dump() functions now only render HTML
when the request contains an Accept HTTP header with an html value.
In all other cases (e.g. API debugging, terminal output), dumps are rendered as
plain text.

Simpler Target Attributes


Valmont Pehaut-Pietri
Contributed by
Valmont Pehaut-Pietri
in
#60874

When dealing with multiple implementations of the same type, the
#[Target] attribute helps you select which one to inject. In Symfony 7.4,
we’ve simplified how you can define those values.

You can now use the same names as in your configuration files, without adding
extra suffixes based on the service type:

// Before - Asset Packages
#[Target('foo_package.package')] private PackageInterface $package
// After
#[Target('foo_package')] private PackageInterface $package

// Before - Lock Factories
#[Target('invoice.lock.factory')] private LockFactory $lockFactory
// After
#[Target('invoice')] private LockFactory $lockFactory

// Before - Rate Limiters
#[Target('anonymous_api.limiter')] RateLimiterFactoryInterface $rateLimiter
// After
#[Target('anonymous_api')] RateLimiterFactoryInterface $rateLimiter


Sponsor the Symfony project.
Tagged:

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *