Symfony 7.3 is packed with powerful enhancements to boost your development experience. Here's a quick overview:
1. ObjectMapper Component
Say goodbye to repetitive mapping code! The new ObjectMapper component simplifies data transfer between objects, such as mapping DTOs to entities, reducing boilerplate and potential errors.
// when creating a new object from another one
$user = $mapper->map($dto, User::class);
// when updating an existing object with another one
$mapper->map($dto, $user);
2. Explaining Security Voter Decisions
Debugging access control just got easier. Security voters can now provide detailed reasons for their decisions, which are displayed in the Symfony profiler and logs, aiding in understanding authorization outcomes.
namespace App\Security\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Vote;
use Symfony\Component\Security\Core\Authorization\Voter\Voter as BaseVoter;
// ...
class BlogCommentVoter extends BaseVoter
{
protected function supports(string $attribute, mixed $subject): bool
{
// ...
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token, ?Vote $vote = null): bool
{
// ...
if (...) {
$vote?->addReason(sprintf('The post (id: %d) no longer accepts comments', $post->getId()));
return false;
}
if (...) {
$vote?->addReason(sprintf('The logged in user (username: %s) was banned from adding new comments', $user->getUsername()));
return false;
}
return true;
}
}
3. JsonPath Component
Introducing a powerful tool to query and extract data from JSON structures. The JsonPath component allows you to perform complex queries on JSON data, similar to XPath for XML, enhancing data manipulation capabilities.
// extract descendants from items (e.g. to get all authors)
$result = $crawler->find('$..author');
// outputs: ['Nigel Rees', 'Evelyn Waugh']
// filter contents using expressions
$result = $crawler->find('$.store.book[?(@.price < 10)]');
// you can use functions like length(), count(), match(), etc.
$result = $crawler->find('$.store.book[?length(@.author) > 11]');
$result = $crawler->find('$.store.book[?match(@.author, "[A-Z].*el.+")]');
4. Static Error Pages
Ensure consistent error handling even when your application can't process requests. Symfony 7.3 introduces a command to generate static HTML error pages, which can be served directly by the web server, improving user experience during failures.
# the first argument is the directory where the HTML files will be stored
# (they are named 400.html, 401.html, 402.html, .., 510.html, 511.html)
APP_ENV=prod php bin/console error:dump var/cache/prod/error_pages/
# by default, it generates the pages of all 4xx and 5xx errors, but you can
# pass a list of HTTP status codes to generate only those pages
APP_ENV=prod php bin/console error:dump var/cache/prod/error_pages/ 401 403 404 500
5. Simpler Server Event Streaming
Implement real-time features more effortlessly with the new EventStreamResponse and ServerEvent classes. These tools streamline server-sent events (SSE), making it easier to push updates to clients without external dependencies.
public function __invoke(): EventStreamResponse
{
return new EventStreamResponse(function () {
foreach ($this->watchJobsInProgress() as $job) {
yield new ServerEvent($job->toJson(), type: 'jobs');
sleep(1);
}
});
}
Explore these features in detail in the official Symfony blog posts.
Top comments (2)
I would add invokable commands.
You're absolutely right!