Ça y est, la version LTS de Symfony 5 est là, accompagnée de la première version stable de Symfony 6.
L'occasion pour nous de jeter un coup d’œil à ce qu'elle contient d'assez intéressant pour avoir envie de mettre à jour son application.
Nous y voilà, la dernière 5.x
de Symfony !
A bien y réfléchir, la 4.4
ne semble pas si loin... Et pourtant !
Comme chaque nouvelle version, elle apporte son lot de nouveautés et Symfony a la bonne idée de faire un focus sur certaines nouveautés directement sur son blog.
Vous pouvez tous les lire depuis la page associée.
Nous vous proposons de revenir sur quelques éléments de cette nouvelle version qui nous ont particulièrement plu ou méritent toute notre attention.
C'est peut-être le changement le plus radical.
Symfony a décidé (et c'est une très bonne chose) d'ajouter du typage sur toute sa codebase.
Nous sommes d'ailleurs incités à nous préparer pour ce changement, car ce n'est pas anodin.
En gros, jusqu'à présent, vous étiez libre de typer votre code custom (et ça sera toujours le cas).
Mais pour ce qui était du code hérité de Symfony, ce n'était pas nécessaire (et parfois pas possible).
Cette fois ça y est, si ce n'était pas déjà fait, vous allez devoir vous lancer.
class User implements UserInterface
{
- public function getRoles()
+ public function getRoles(): array
{
}
}
interface VoterInterface
{
- public function vote(TokenInterface $token, $subject, array $attributes);
+ public function vote(TokenInterface $token, mixed $subject, array $attributes): int;
}
Il y a donc beaucoup de changements, et Symfony en est bien conscient.
Mais il ne faut pas en avoir peur pour autant, car plusieurs solutions s'offrent à vous :
Vous pouvez utiliser PHP 8.1
avec Symfony 4.4
, à priori sans rencontrer plus de problème que ça.
Mais dans cette version, Symfony n'intègre pas parfaitement tous les changements importants des version 8.x
.
La version 5.4
devrait remédier à cela grâce à ces quelques nouveautés :
8.0
PHP 8.0
intègre la notion d'attribut, qui devrait remplacer à terme celle des annotations (puisqu'au final ce ne sont que des commentaires).
Depuis Symfony 4.0
, nous tendons vers toujours plus d'inversion de contrôle (un de piliers de l'AOP), il était donc tout naturel que l'on tende vers plus de configuration via des attributs.
Ce changement (qui n'est pas le seul) vous autorisera à tagger vos services via attributs, injecter des services dans des propriétés / des méthodes via attributs...
#[MyAttribute]
class MyService {
}
class MyOtherService {
#[MyAttribute]
public function myMethod() {}
}
8.1
Si vous n'avez pas suivi cette nouveauté, vous devriez prendre un peu de temps pour lire sa RFC, ainsi qu'un article d'exemple (c'est une nouveauté que j'attends avec impatience).
Cette fonctionnalité donnera donc à Symfony la possibilité de traiter les enum
comme une liste de valeurs possibles, tant dans les formulaires que dans la validation.
enum Suit: string
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
$form->add('suit', EnumType::class, [
'class' => Suit::class,
'required' => false,
'expanded' => true,
]);
Une nouveauté qui peut paraître triviale, mais ceux qui ont des sites avec beaucoup de trafic (ou des APIs), sont régulièrement confrontés aux difficultés de séparer les vraies erreurs du reste.
Grâce à un peu de configuration, vous pouvez maintenant contrôler le logging des exceptions :
framework:
exceptions:
Symfony\Component\HttpKernel\Exception\BadRequestHttpException:
log_level: debug
status_code: 422
C'est une nouveauté assez simple, mais qui vous fera gagner un peu de temps.
Cette nouvelle classe du package symfony/filesystem
a été extraite de webmozart/path-util
.
Elle permet de nombreuses opérations sur les chemins de fichiers, sans vérification d’existence.
use Symfony\Component\Filesystem\Path;
Path::canonicalize("\symfony\puli\..\css\style‧css"); // => /symfony/css/style‧css
Path::getHomeDirectory(); // => /home/me ou C:/users/me
Path::isAbsolute("../path"); // => false
Path::getExtension("/path/to/file.XLSX", true); // => xlsx
Path::getFilenameWithoutExtension("/path/to/file.XLSX"); // => file
//...
L'arrivée de cette 5.4
est également l'occasion d'ajouter les dernières dépréciations avant l'arrivée de la 6.0
.
AbstractController::getDoctrine()
& AbstractController::dispatchMessage()
ont été dépréciées.Ici, l'objectif est simple : ne doit subsister dans AbstractController
que ce qui concerne la couche HTTP.
C'est une très bonne chose de mon point de vue, ça permet de clarifier l'utilisation de cette classe et permet d'éliminer les méthodes qui cachent l'utilisation de services.
class FooController extends AbstractController
{
- public function index(): Response
+ public function index(EntityManagerInterface $doctrine): Response
{
- $doctrine = $this->getDoctrine();
}
}
AbstractController::get()
& AbstractController::has()
ont été dépréciées.On continue sur AbstractController
, mais le changement est plus éducatif : certains utilisent ces méthodes comme un accesseur de services, mais ne comprennent pas que le Container
qui est utilisé alors, est un Container
light, ne contenant que les services essentiels au fonctionnement du AbstractController
.
class FooController extends AbstractController
{
- public function index(): Response
+ public function index(EntityManagerInterface $doctrine): Response
{
- $doctrine = $this->get('doctrine');
}
}
Request::get()
a été marquée comme interneCe n'est donc pas à proprement parler une dépréciations, mais à l'usage c'est la même chose : vous ne devriez pas vous servir de cette méthode, qualifiée de "magique".
A la place, il faudra viser le ParameterBag
dans lequel se trouve la valeur que vous recherchez : Request::$query
, Request::$request
, ...
class FooController
{
public function index(Request $request): Response
{
- $id = $request->get('id');
+ $id = $request->query->get('id');
}
}
Evidemment, la version 5.4 contient bien plus de nouveautés, nous aurions aussi pu vous parler de la complétion de la console qu'on a hâte d'utiliser.
En tout cas nous espérons que, tout comme nous, cette revue 5.4
& 6.0
vous aura donné envie de mettre à jour votre application !