Mauvaises utilisations de l'opérateur @

En PHP, @ est appelé l’opérateur de suppression d’erreurs. C’est parfois une façon pratique de dire à PHP qu’il ne devrait pas générer d’avertissement (warning) ou de remarques (notice) pour un certain morceau de code parce qu’on sait qu’il est parfaitement correct d’ignorer un certain avertissement. J’ai trouvé que l’opérateur @, si surutilisé, peut imposer une grande pénalité en vitesse. Alors voici une liste de choses que vous ne devriez pas faire avec cet opérateur.

Remplacer isset

Quand vous avez une variable où vous n’êtes pas sûr qu’elle ait été déclaré précédemment, n’utilisez pas l’opérateur de suppression d’erreur pour enlever la remarque « variable not set », c’est à peu près 2 fois plus lent que d’utiliser isset. Exemple :

if (isset($albus))  $albert = $albus;
else                $albert = NULL;

est équivalent à :

$albert = @$albus;

mais malgré que la seconde forme soit une jolie syntaxe, le code s’exécute à peu près deux fois plus lentement. Une meilleure solution est d’assigner la variable par référence ce qui ne générera pas de remarque :

$albert =& $albus;

Cependant, ce truc d’assignation par référence peut induire des effets secondaires si vous modifier le contenu d’une des deux variables plus loin. Ma règle est d’utiliser ce principe seulement dans les bouts de code critiques au niveau de la vitesse.

Avec le mot-clé list

PHP vous permet d’assigner plusieurs variables en même temps à partir d’un tableau (array) en utilisant le mot-clé list. Le cas le plus commun de l’utilisation de list est avec la fonction explode qui sépare une chaîne en plusieurs morceaux. Par exemple :

list($a, $b, $c) = explode('/', 'partie1/partie2/partie3');

Mais souvent, vous ne pouvez pas être certain que la chaîne que vous « explosez » donnera tous les morceaux pour les variables que vous aurez listés. Ceci résultera en une remarque PHP qu’on peut faire disparaître facilement avec l’opérateur de suppression d’erreur :

@list($a, $b, $c) = explode('/', 'partie1/partie2');

et dans ce cas-ci, la variables $c sera mise à NULL. Mais encore une fois, @ est plutôt lent. Il est tellement lent en fait que, pour cet exemple du moins, j’ai trouvé que c’était plus rapide d’utiliser array_pad pour finir de remplir le tableau pour qu’il contiennent toutes les valeurs nécessaires que d’utiliser l’opérateur de suppression d’erreurs :

list($a, $b, $c) = array_pad(explode('/', 'partie1/partie2'), 4, NULL);

Ça devient pas mal ridicule.

La meilleure solution que j’ai trouvé est d’assigner chaque variable séparément par référence, comme ceci :

$resultat = explode('/', 'partie1/partie2');
$a =& $resultat[0];
$b =& $resultat[1];
$c =& $resultat[2];

Puisque vous n’avez pas à utiliser la variable $resultat de toute façon — vous utilisiez list qui n’assignait pas le tableau à aucune variable — l’assignation par référence ne devrait pas causer de problème. D’après mes tests, c’est un peu plus lent que d’utiliser list, mais c’est bien plus rapide que l’opérateur de suppression d’erreurs.

Conclusion

Alors que doit-on retenir de tout ceci ? Simplement qu’il ne faut pas utiliser l’opérateur de suppression d’erreur dans du code critique au niveau de la vitesse. Écrire plus de code pour contourner les cas d’exception sera toujours plus rapide.

Évidemment, si vous ne vous préoccupez pas des remarques (notice), probablement parce que vous avez ajusté le niveau d’erreur pour les exclure, vous n’avez pas besoin de l’opérateur de suppression d’erreur pour les assignations de variables. Mais si vous déployez votre logiciel sur un serveur qui enregistre les remarques, cette informations vous sera peut-être utile. Du moins, elle va m’être utile pour mes propres projets en PHP.


Remarques : Tous les tests ont été effectués avec PHP 5 et un rapport d’erreur à E_ALL. Les résultats peuvent varier avec d’autre versions et d’autre réglages.


  • © 2003–2019 Michel Fortin.