Duplicate Preferred Choices
The preferred_choices option of the ChoiceType field allows you to display certain choices at the top of your list with a visual separator between them and the complete list of options.
Originally, those preferred choices were included only once at the top of the list. In Symfony 4.4, to avoid confusion from some people, we changed this and the choices are now rendered both at the top of the list and their original location.
This new behavior is also confusing for some people, so we've added a new config option so you can fully control if they should be rendered twice or not:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('language', ChoiceType::class, [
'choices' => [
'PHP' => 'php',
'JavaScript' => 'js',
'Twig' => 'twig',
// ...
],
'preferred_choices' => ['php', 'twig'],
'duplicate_preferred_choices' => true,
]);
Add Server Parameters when Clicking Links
The BrowserKit component simulates the behavior of a web browser, allowing
you to make requests, click on links and submit forms programmatically. In
Symfony 6.4 we've improved the click()
and clickLink()
methods to allow
setting custom server parameters that are added as request headers when clicking
on the link:
1 2 3 4 5 6 7
$client = new Client();
$client->request('GET', '/product/123');
$crawler = $client->clickLink('Proceed to Checkout', ['X-Custom-Header' => 'Some data']);
$link = $crawler->selectLink('Proceed to Checkout')->link();
$client->click($link, ['X-Custom-Header' => 'Some data']);
Default Crawler Attributes
The DomCrawler component eases the DOM navigation for HTML and XML documents.
The methods text()
and html()
, which extract the text/HTML contents
of the given node allow to define a default value. This is useful because trying
to access the text/HTML of a node that doesn't exist will throw an exception:
1 2 3 4 5
// if the node does not exist, calling to text() will result in an exception
$message = $crawler->filterXPath('//body/p')->text();
// avoid the exception passing an argument that text() returns when node does not exist
$message = $crawler->filterXPath('//body/p')->text('Default text content');
In Symfony 6.4, we've improved the attr()
method to also support a default
value for the same reasons, to avoid exceptions when the node doesn't exist:
1 2 3 4 5 6 7 8 9
// instead of this...
try {
$value = $dom->filter('a.someclass')->attr('href');
} catch (\InvalidArgumentException $e) {
$value = '';
}
// ...do this
$value = $dom->filter('a.someclass')->attr('href', '');
Maximum Retries in HTTP Client
By default, when requests fail because of network issues or temporary server errors, the HttpClient component retries failed requests up to 3 times, with an exponential delay between retries. In Symfony 6.4 we're improving this feature to allow you to set the exact number of max retries to attempt:
1 2 3 4
// ...
$client->request('GET', '/foo-bar', [
'max_retries' => 1, // 0 disables retrying
]);
Defined Env Var Processor
The environment variable processors transform the original contents of a given environment variable (which is always a string) to turn it into other data types or to change its contents.
In Symfony 6.4 we're adding a new processor called defined
which returns
false
if the env var doesn't exist or if it's null
or the empty string.
It returns true
otherwise:
1 2 3
parameters:
# ...
is_captcha_enabled: '%env(defined:CLOUDFLARE_TURNSTILE_SITE_KEY)%'
It's a small nitpick but even if the blog post doesn't get updated, it is good to know for everyone that reads this regarding the retries of the HttpClient.
The HttpClient does NOT retry requests by default. You have to decorate your HttpClient with the RetryableHttpClient first. The RetryableHttpClient takes a "maxRetries" argument. The client will then retry the request that amount of times.
You can now overwrite this argument on a per request basis without having to use a different HttpClient service. For example you want request A to be retried up to 10 times, but request B only a maximum of 2 times. As mentioned in the blog post, you can even pass 0 to disable retrying completely for request C.
This is especially useful when you have the default "http_client" service configured with the "retry_failed" option in the framework configuration.