Le passage d’un projet d’agence à PHP 8 a fait remonter 340 occurrences de Warning: Undefined array key dans une suite de tests jusque-là silencieuse sous PHP 7.4, où ce type d’accès générait simplement une notice ignorée par défaut. La tentation immédiate était de configurer PHPUnit pour ignorer ces avertissements et passer à autre chose. Un examen plus attentif a révélé que douze de ces occurrences correspondaient à de vrais bugs latents — des données manquantes silencieusement traitées comme vides, avec des conséquences métier bien réelles.
La bonne approche n’est donc ni d’ignorer systématiquement ces avertissements, ni de tout corriger sans discernement : il faut les trier.
Comprendre ce qui a changé avec PHP 8
Avant PHP 8, accéder à une clé de tableau inexistante générait une notice de faible sévérité, souvent invisible en pratique. Depuis PHP 8.0, ce même accès émet un Warning, une sévérité supérieure, ce qui a des conséquences directes sur PHPUnit : selon sa configuration, un warning PHP peut être converti en échec de test, via le mécanisme convertWarningsToExceptions (retiré en configuration explicite à partir de PHPUnit 10, où ce comportement devient le défaut non désactivable).
Catégorie 1 — Un vrai bug révélé
Le cas le plus intéressant : un champ de formulaire optionnel, jamais rempli par certains utilisateurs, était lu sans vérification préalable, et sa valeur manquante était silencieusement traitée comme une chaîne vide dans un calcul de remise :
// Avant : bug silencieux sous PHP 7.4, warning sous PHP 8
$code_promo = $donnees_formulaire['code_promo'];
if ($code_promo === '') {
$remise = 0;
}
Le correctif ne consiste pas à supprimer l’avertissement, mais à traiter explicitement l’absence de la clé, ce qui clarifie aussi l’intention du code pour le prochain développeur qui le lira :
// Après : intention explicite, aucun avertissement
$code_promo = $donnees_formulaire['code_promo'] ?? '';
if ($code_promo === '') {
$remise = 0;
}
Catégorie 2 — Une clé optionnelle légitime
D’autres occurrences correspondaient à des cas parfaitement normaux : un tableau de métadonnées où une clé n’existe que pour certains types de contenu. Le correctif est similaire, mais la lecture du code révèle qu’il ne s’agit pas d’un bug corrigé, seulement d’une syntaxe rendue plus rigoureuse :
$duree_evenement = $meta['duree_minutes'] ?? null;
if ($duree_evenement !== null) {
afficher_duree($duree_evenement);
}

Méthode pour trier 340 occurrences sans y passer un mois
- Regrouper les occurrences par fichier source plutôt que par test qui les révèle — plusieurs tests différents pointent souvent vers la même ligne de code fautive.
- Prioriser les fichiers qui touchent à un calcul financier, une validation de sécurité ou un traitement de commande : c’est là que les bugs silencieux coûtent le plus cher.
- Pour chaque occurrence restante, se poser une seule question : « cette clé peut-elle légitimement être absente ? » Si la réponse est oui, l’opérateur
??suffit. Si la réponse est non, il faut comprendre pourquoi elle manque avant de corriger. - Ne jamais utiliser
@pour faire taire l’avertissement : cet opérateur masque l’erreur sans documenter l’intention, et cache potentiellement un vrai bug pour le prochain audit.
Un test qui aurait pu prévenir la catégorie 1
Une fois le bug corrigé, un test dédié garantit qu’il ne réapparaîtra pas silencieusement :
public function test_code_promo_absent_ne_genere_pas_de_warning(): void {
$donnees_sans_code = ['montant' => 49.90];
$resultat = calculer_remise($donnees_sans_code);
$this->assertSame(0.0, $resultat);
}
Un avertissement PHP dans une suite de tests n’est jamais du bruit à faire taire : c’est une question posée par le langage lui-même — « es-tu sûr que cette clé existe toujours ? » — à laquelle chaque occurrence mérite une réponse explicite.
Ce que ce chantier ne remplace pas
Corriger ces avertissements ponctuellement ne remplace pas une migration complète et méthodique vers PHP 8, qui touche aussi les changements de signature de fonctions natives, le typage plus strict des arguments et d’autres comportements dépréciés — un chantier plus large déjà traité séparément. Ce travail-ci se concentre uniquement sur la classe d’avertissements liée aux accès de tableau, révélée en priorité par l’exécution de la suite de tests existante.
En résumé
Passer une suite de tests à PHP 8 sans effort de tri sur les avertissements de tableau revient à laisser passer une opportunité rare : celle où le langage lui-même désigne, gratuitement, les endroits du code où une hypothèse implicite sur la présence d’une donnée n’était jamais vérifiée. Sur ce projet, un tiers seulement des occurrences correspondait à un vrai bug — mais ce tiers valait largement les quelques heures passées à trier les 340 lignes.