Les arguments nommés en PHP 8

Vous êtes vous déjà demandé à quoi servait le 6éme argument d'une fonction en lisant du code que vous aviez écrit il y a 2 mois ? Je pense que cela est déjà arrivé à tous les développeurs quelque soit le language utilisé. Sauf si le language à des arguments nommés ou assimilés.

Dans cette série d'articles, je reviens avec vous sur les nouveautés de la dernière version de PHP. Découvrons ensemble ce que la version 8 de PHP a de nouveau à nous apporter et comment cela pourrait nous être utile.

Les arguments nommés ne sont pas une très grosse nouveauté. Comme je l'ai déjà dit plus haut, il s'agit d'une fonctionnalité qui existe déjà dans d'autres languages. Ces derniers utilisent parfois d'autres noms comme les "labels" en Swift mais il s'agit sensiblement de la même chose.

Même dans le monde de PHP, les arguments nommés ne sont pas une grosse nouveauté. Depuis plusieurs versions (et donc plusieurs années) JetBrains affiche dans PHPStorm le nom des arguments devant les valeurs que l'on souhaite y mettre à l'exécution d'une fonction. C'est une aide à la lecture et à la compréhension du code. Bien-sûr il ne s'agit que d'affichage, la signature de votre fonction ne change pas réellement.

Les spécificités de PHP 8

La syntaxe proposée par PHP pour cette nouvelle fonctionnalité est la suivante :

<?php

functionName(paramName: $value);

Et cela sans changer la déclaration :

<?php

function functionName($paramName) { ... }

À première vue, cela ne change pas grand chose et peut même paraître inutile. Mais les arguments nommés apportent beaucoup de flexibilité, simplifient le code et le rendent plus lisible.

Par exemple, vous pouvez maintenant ignorer complètement les arguments optionnels dans vos appels de fonction. Surtout lorsque vous ne souhaitez changer que le dernier arguments optionnel.

<?php

function getValue($key, $obj = null, $depth = 0, $isCaseSensitive = true) { ... }

getValue("key", null, 0, false); // arguments positionnés seulement
getValue(key: "key", isCaseSensitive: false);

Comme vous précisez le nom de l'argument que vous souhaitez utiliser, l'interpréteur sait de quoi vous parlez. Vous n'êtes donc plus obligé de respecter l'ordre de déclaration des arguments.

<?php

function getValue($key, $obj = null, $depth = 0, $isCaseSensitive = true) { ... }

getValue(depth: 3, key: "key", isCaseSensitive: false);

Il est aussi possible de mélanger les arguments positionnés (la façon classique de faire) et les arguments nommés. À vous de voir ce qui convient le mieux à votre situation.

<?php

function trim($text, $leftOnly = false, $rightOnly = false) { ... }

trim($text, false, true); // arguments positionnés seulement
trim($text, rightOnly: true);

Par contre, il faut toujours que vous utilisiez les arguments positionnés avant les arguments nommés. On comprend assez facilement pourquoi : si nous avons déjà indiqué des arguments comment l'interpréteur peut-il deviner quel argument nous souhaitons utiliser uniquement grâce à sa position.

<?php

trim(righOnly: true, $text) // Erreur

Bien-sûr toutes ces régles et nouveautés s'appliquent aussi aux constructeurs et méthodes de classes. Voyez plutôt l'exemple ci-dessous :

<?php

class MyClass extends ParentClass {
    private string $title;
    private bool $isUnique;
    private bool $isVariadic;
    
    public function __construct(
        string $title,
        bool $isUnique = false,
        bool $isVariadic = false,
        string $desc = null,
    ) {
        parent::__construct($text);
        
        $this->title = $title;
        $this->isUnique = $isUnique;
        $this->isVariadic = $variadic;
    }
}

new MyClass(title: "Science for All", isVariadic: true);
// or
new MyClass("Science for Anyone", isUnique: true);

Maintenant vous savez à peu près tout sur les arguments nommés. Vous savez comment les utiliser et éviter les erreurs les plus grossières.

Pour avoir déjà utiliser cette fonctionnalité dans plusieurs autres languages, je suis plutôt convaincu de l'utilité de celle-ci. Cela permet de rendre le code beaucoup plus lisible sans tomber dans le piège de noms de variable à rallonge que l'on a connu en Java.

D'ailleurs le code devient plus lisible directement après écriture mais aussi plusieurs mois après. Il y a besoin de beaucoup moins de contexte pour comprendre le code ce qui facilite aussi la maintenance.

Quel est votre avis sur la question ? N'hésitez pas à m'en faire part et pour aller plus loin je vous mets des liens vers quelques autres articles intéressants du blog :