Depuis sa sortie, PHP 8 a bouleversé le quotidien des développeurs avec ses attributs, sa syntaxe modernisée et son approche plus stricte de la qualité du code. À chaque nouvelle version, le langage affine son comportement, rendant nos scripts à la fois plus clairs et plus sûrs. Et avec PHP 8.5, un petit nouveau attire l’attention : l’attribut #[NoDiscard].
Derrière ce nom un peu mystérieux se cache un mécanisme très utile pour éviter une erreur courante : ignorer une valeur de retour importante. Combien de fois avez-vous écrit une fonction qui renvoie une valeur essentielle, mais que vous avez oubliée d’utiliser ?
Par exemple, une méthode censée retourner un objet modifié, et que vous appelez sans rien faire du résultat. C’est le genre de détail qui ne fait pas planter le programme, mais qui peut provoquer des bugs silencieux et de longues heures de débogage.
Dans ce guide, nous allons découvrir ensemble ce qu’est #[NoDiscard], pourquoi il a été introduit, comment l’utiliser efficacement et dans quels cas il devient vraiment précieux. Vous verrez aussi quelques exemples concrets pour comprendre son utilité au quotidien, même si vous débutez en PHP.
Comprendre ce qu’est un attribut en PHP
Avant de plonger dans #[NoDiscard], prenons un petit moment pour revenir sur le concept d’attribut en PHP, car c’est la base pour bien comprendre ce qui suit.
Les attributs ont été introduits avec PHP 8.0. Ils permettent d’ajouter des métadonnées à votre code — autrement dit, des informations supplémentaires que PHP ou d’autres outils peuvent lire pour modifier le comportement d’un élément (comme une classe, une fonction ou une méthode).
Ces attributs s’écrivent entre #[ ... ].
Prenons un exemple tout simple :
#[Deprecated]
function ancienneFonction() {
// ...
}Ici, l’attribut #[Deprecated] indique que la fonction est obsolète. Ce n’est pas PHP qui l’invente automatiquement : c’est un signal pour les outils d’analyse, les IDE ou les frameworks (comme Symfony ou Laravel) pour avertir le développeur.
C’est donc une façon propre et lisible d’ajouter des “annotations” directement dans le code, sans commentaires ambigus.
L’attribut #[NoDiscard] : une nouveauté de PHP 8.5
Entrons maintenant dans le vif du sujet. PHP 8.5 introduit un nouvel attribut nommé #[NoDiscard].
Son rôle est simple mais puissant : prévenir le développeur quand la valeur de retour d’une fonction ou d’une méthode est ignorée.
Autrement dit, si vous écrivez une fonction qui retourne une donnée importante (un objet, un booléen, un résultat de calcul…), mais que vous appelez cette fonction sans utiliser ce qu’elle renvoie, PHP vous affichera désormais un avertissement.
Imaginez un instant que vous ayez une fonction comme celle-ci :
function calculerPrixTTC(float $prixHT, float $tva): float {
return $prixHT * (1 + $tva / 100);
}
calculerPrixTTC(100, 20);
// Oups ! On ne récupère pas le résultatCe code s’exécute, mais la valeur retournée n’est jamais utilisée. En soi, ce n’est pas une erreur, mais c’est souvent le signe d’un oubli. Avec l’attribut #[NoDiscard], vous pouvez dire à PHP : « Hé, si quelqu’un appelle cette fonction sans utiliser sa valeur, avertis-le ! »
Voici comment cela fonctionne :
#[NoDiscard]
function calculerPrixTTC(float $prixHT, float $tva): float {
return $prixHT * (1 + $tva / 100);
}
calculerPrixTTC(100, 20);
// Avertissement : valeur de retour ignoréeC’est tout ! En une seule ligne, vous indiquez clairement que la valeur renvoyée doit être utilisée.
Pourquoi cette nouveauté est-elle importante ?
Au premier abord, #[NoDiscard] peut sembler anecdotique. Après tout, PHP n’interdit pas d’ignorer une valeur. Pourtant, cette petite amélioration touche à quelque chose de fondamental : la fiabilité du code.
Beaucoup d’erreurs dans les applications web ne viennent pas de la logique elle-même, mais de petits oublis :
- un retour de fonction ignoré,
- un booléen non vérifié,
- une copie d’objet qu’on pensait avoir modifiée,
et ainsi de suite.
PHP, jusqu’ici, ne disait rien. Mais avec #[NoDiscard], le langage devient plus expressif : il permet au code de “communiquer ses intentions”.
En tant que développeur, vous pouvez désormais définir explicitement que le résultat d’une fonction est important. Cela permet aux autres (ou à vous-même, dans quelques semaines) de savoir qu’il ne faut pas l’ignorer.
Et ce n’est pas qu’une question de confort. Dans les projets d’équipe ou les frameworks, cela aide à éviter des comportements imprévus, surtout quand plusieurs personnes manipulent le même code.
D’ailleurs, c’est une idée inspirée d’autres langages modernes comme C++ ou Rust, qui utilisent aussi des attributs similaires ([[nodiscard]] ou #[must_use]) pour signaler exactement ce genre de problème.
Exemple concret : sécuriser une API interne
Prenons un exemple plus concret pour illustrer le rôle de #[NoDiscard]. Imaginez que vous travailliez sur une classe qui gère les transactions d’un panier d’achat.
class Panier {
private array $articles = [];
public function ajouter(string $article): self {
$this->articles[] = $article;
return $this;
}
#[NoDiscard]
public function valider(): bool {
// Simulation de validation
return !empty($this->articles);
}
}Dans cet exemple, la méthode valider() retourne true si le panier est correct, sinon false. Mais si un développeur oublie de vérifier ce retour, cela peut avoir des conséquences :
$panier = new Panier();
$panier->ajouter('Chaussures');
$panier->valider();
// Avertissement : valeur ignoréeGrâce à #[NoDiscard], PHP avertira que la valeur de retour a été perdue. Cela incite à écrire un code plus explicite :
if ($panier->valider()) {
echo "Panier validé avec succès !";
}C’est un petit détail, mais dans un projet professionnel, ce genre de garde-fou peut vous éviter bien des nuits blanches à chercher un bug “invisible”.
Un attribut utile mais pas autoritaire
Ce qu’il faut bien comprendre, c’est que #[NoDiscard] n’empêche pas l’exécution du code. PHP ne bloque pas le programme : il affiche simplement un warning (avertissement).
L’objectif n’est donc pas de rendre le langage plus strict, mais de prévenir les oublis. C’est une aide au développement, pas une punition.
D’ailleurs, cet avertissement n’apparaîtra que si l’environnement PHP est configuré pour afficher les warnings. Autrement dit, dans un environnement de production, il n’y a pas de danger que votre site plante pour ça.
On peut donc le voir comme une aide pédagogique. C’est un outil qui vous apprend à adopter de bonnes pratiques, sans jamais vous contraindre.
Utiliser #[NoDiscard] dans des cas réels
Vous vous demandez peut-être : « D’accord, mais dans la pratique, dans quels cas précis est-ce vraiment utile ? » La réponse est : bien plus souvent qu’on ne le pense.
Prenons un scénario très courant dans les projets modernes : la manipulation d’objets immuables. Un objet immuable est un objet qui ne peut pas être modifié après sa création. Chaque fois que vous voulez le “changer”, vous devez en créer une nouvelle version.
Pour en savoir plus, consultez notre tutoriel complet sur La POO en PHP.
Des formations informatique pour tous !
Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…
Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.
Découvrez mes formations Qui suis-je ?
C’est une pratique très utilisée dans les frameworks orientés vers la programmation fonctionnelle ou dans des outils comme Doctrine, Symfony ou Laravel.
Imaginons un exemple simple :
class Utilisateur {
public function __construct(
public string $nom,
public string $email
) {}
#[NoDiscard]
public function avecEmail(string $nouvelEmail): self {
return new self($this->nom, $nouvelEmail);
}
}
$u = new Utilisateur("Alban", "[email protected]");
$u->avecEmail("[email protected]");
// Valeur ignoréeIci, la méthode avecEmail() ne modifie pas l’objet d’origine, mais renvoie une nouvelle instance. Si vous oubliez d’utiliser cette nouvelle version, votre code ne fera rien — et vous risquez de passer des heures à vous demander pourquoi le changement d’email ne fonctionne pas.
Avec #[NoDiscard], PHP vous avertira immédiatement, vous rappelant que le résultat doit être stocké :
$u = $u->avecEmail("[email protected]");
// CorrectC’est typiquement dans ces cas d’objets immuables que #[NoDiscard] montre toute sa pertinence.
Une aide précieuse dans les bibliothèques et frameworks
Les grands frameworks PHP — tels que Symfony, Laravel ou CodeIgniter — pourraient rapidement tirer parti de cet attribut. En effet, beaucoup de leurs méthodes renvoient des objets ou des statuts qui ne doivent pas être ignorés.
Par exemple, dans Symfony, certaines méthodes de Response, Request ou Form retournent des valeurs qui influencent le comportement de l’application. Un développeur qui oublie de les utiliser pourrait involontairement casser une partie du flux logique.
Avec #[NoDiscard], ces bibliothèques peuvent désormais documenter leurs intentions directement dans le code, sans commentaire ambigu ni documentation cachée. L’IDE ou l’analyseur statique pourra alors afficher un message du type :
“Attention, vous avez ignoré la valeur de retour de cette méthode annotée #[NoDiscard].”
C’est un pas de plus vers un PHP plus sûr, plus lisible et plus auto-documenté. Un peu comme si le code devenait capable de se défendre lui-même contre les erreurs humaines.
Comment fonctionne l’avertissement techniquement ?
Vous l’aurez remarqué : #[NoDiscard] ne lève pas une exception, et il ne coupe pas le programme. Son comportement repose sur le moteur d’avertissement de PHP.
Concrètement, lorsque PHP voit qu’une fonction marquée #[NoDiscard] est appelée sans que sa valeur soit utilisée (assignée, passée à une autre fonction, comparée, etc.), il émet un E_WARNING.
Ce type d’avertissement peut être affiché à l’écran (en mode développement), enregistré dans un fichier de log ou totalement ignoré selon vos paramètres error_reporting.
Cela signifie que si vous exécutez votre code avec :
php -d error_reporting=E_ALL votre_script.phpvous verrez apparaître un message du genre :
Warning: La valeur retournée par la fonction 'calculerPrixTTC()' (annotée #[NoDiscard]) a été ignorée.C’est clair, explicite, et surtout non bloquant.
Vous gardez donc la liberté de votre logique métier, tout en profitant d’un filet de sécurité supplémentaire.
Les limites et précautions à connaître
Comme toute nouveauté, #[NoDiscard] doit être utilisé avec discernement. Il serait contre-productif de l’ajouter partout, simplement “par sécurité”.
D’abord, il faut comprendre que certains retours de fonctions peuvent être facultatifs : par exemple, une méthode log() qui retourne true ou false selon que l’opération a réussi ou non, mais dont le résultat n’est pas toujours critique. Dans ces cas-là, émettre un avertissement à chaque appel pourrait vite devenir agaçant.
Ensuite, #[NoDiscard] n’est pas rétroactif : il ne s’applique qu’aux fonctions et méthodes explicitement décorées avec cet attribut. Si vous travaillez avec du vieux code ou des bibliothèques non mises à jour, il n’aura aucun effet.
Enfin, notez qu’il n’existe pas encore de moyen d’ajouter un message personnalisé à cet avertissement, contrairement à d’autres systèmes d’attributs dans certains langages. Il faudra donc se contenter du message générique fourni par PHP.
Mais ne boudons pas notre plaisir : c’est une première étape vers une écriture plus claire et intentionnelle du code PHP.
Quand un oubli coûte des heures …
Imaginez-vous travailler sur un système de paiement en ligne. Un beau matin, un client se plaint : « J’ai payé, mais ma commande est restée bloquée ! » Après des heures à scruter les logs, vous découvrez que la fonction confirmerPaiement() retourne un booléen… mais que personne ne vérifie le retour.
Résultat : si le paiement échouait, le site affichait “succès” quand même, et inversement. Un simple #[NoDiscard] aurait signalé l’oubli dès les premiers tests. Ce genre de mésaventure montre bien que parfois, une petite amélioration syntaxique peut épargner beaucoup de frustration.
Comparaison avec d’autres langages
Il est intéressant de noter que PHP s’aligne ici sur des standards déjà éprouvés ailleurs. En C++, l’attribut équivalent [[nodiscard]] existe depuis plusieurs années. En Rust, on retrouve #[must_use], qui impose exactement la même idée : rappeler au programmeur qu’une valeur retournée doit être traitée.
L’arrivée de l’attribut #[NoDiscard] en PHP 8.5 montre une volonté claire : faire du langage un outil de développement plus sérieux, plus rigoureux et plus adapté aux grandes applications d’aujourd’hui. PHP n’est plus ce “langage de script rapide” qu’il était il y a vingt ans. Il devient un langage moderne, doté de véritables garde-fous intelligents.
Intégrer #[NoDiscard] dans ses habitudes de code
Si vous débutez, je vous conseille d’utiliser #[NoDiscard] dans trois situations principales :
- Quand une fonction retourne un résultat essentiel (par exemple, une validation ou un calcul).
- Quand une méthode retourne un nouvel objet immuable qu’il faut absolument réutiliser.
- Quand vous écrivez du code partagé (librairie, framework, package open source).
C’est un moyen simple de rendre votre code plus robuste et de mieux communiquer vos intentions. Et plus votre projet grandira, plus vous vous remercierez d’avoir pris cette habitude tôt.
Vers un PHP de plus en plus expressif
Avec PHP 8.5, la tendance est claire : chaque nouvelle version vise à rendre le code plus expressif, c’est-à-dire plus proche de la pensée du développeur. Les attributs comme #[NoDiscard] sont là pour ajouter de la sémantique à votre code, pour que ce dernier “parle” de lui-même.
Cela s’inscrit dans la même logique que les types stricts, les promoted properties ou les readonly classes : des outils pour écrire un PHP propre, lisible et durable. Et c’est une excellente nouvelle pour tous ceux qui veulent élever leur niveau de qualité sans perdre la simplicité du langage.
#[NoDiscard] n’est peut-être qu’une ligne de plus dans la documentation de PHP 8.5, mais son impact sur la qualité du code est bien réel. Ce petit attribut incarne une philosophie : celle du code intentionnel. Vous ne laissez plus place à l’ambiguïté : vous dites clairement ce que le programme doit respecter, même face à un oubli humain.
C’est aussi un pas de plus vers un PHP mature, un langage où les bonnes pratiques deviennent naturelles, presque intégrées dans la syntaxe elle-même. Et c’est sans doute ce qui fait la beauté de son évolution : PHP reste accessible aux débutants tout en offrant des outils de plus en plus puissants pour les développeurs exigeants.
Si vous débutez, n’ayez pas peur d’expérimenter #[NoDiscard]. Ajoutez-le à vos fonctions importantes, observez son comportement, et voyez comment votre code devient plus clair, plus fiable et, osons le dire, plus élégant.
Après tout, un bon code, c’est un peu comme une conversation : ce qu’on dit compte, mais ce qu’on oublie de dire peut parfois tout changer.


