Un hébergeur mutualisé a prévenu ses clients par courriel : passage forcé à PHP 7.4 dans trois semaines, sans option de retour arrière. Le site concerné, une vitrine associative sous Twenty Quinze jamais mise à jour depuis 2016, s’est mis à afficher des notices PHP en pagaille dès le premier test sur un environnement de préproduction. Le client ne voulait ni changer de thème ni payer une refonte : il fallait stabiliser l’existant.
Ce genre de mission revient régulièrement en maintenance WordPress. Voici le diagnostic que j’ai posé et les correctifs minimaux appliqués, sans toucher à l’architecture du thème ni à sa logique métier.
Symptôme : notices en pagaille, page blanche par endroits
Avec WP_DEBUG activé sur l’environnement de test, la page d’accueil de Twenty Quinze affichait des dizaines de lignes du type Notice: Undefined index et Notice: Undefined variable, injectées en plein milieu du HTML puisque le thème n’utilisait pas la sortie d’erreurs vers un journal. Sur certaines pages d’archive, l’affichage de la pagination provoquait carrément un Warning suivi d’un rendu tronqné, PHP 7.4 étant plus strict que les versions précédentes sur les accès à des index ou variables inexistants.
Diagnostic : remonter à la source des notices
Plutôt que de corriger au hasard, j’ai activé le journal d’erreurs PHP dans wp-config.php pour capturer chaque notice avec son fichier et sa ligne précise.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
En parcourant wp-content/debug.log après un chargement complet du site (accueil, article, archive, recherche), j’ai isolé six fichiers du thème responsables de la quasi-totalité des notices : functions.php, content.php, content-link.php, image.php, search.php et inc/customizer.php. Le point commun : des accès directs à des clés de tableau ou des variables globales sans vérification préalable d’existence.
Correctif 1 : les accès à des index de tableau
La cause la plus fréquente concernait des lectures comme $_GET['paged'] ou des clés de tableaux d’options non garanties. La correction consiste à encadrer chaque accès avec isset() ou array_key_exists() avant de l’utiliser, sans changer la logique existante.
// Avant (notice sous PHP 7.4)
$paged = $wp_query->query_vars['paged'];
// Après
$paged = isset( $wp_query->query_vars['paged'] )
? $wp_query->query_vars['paged']
: 1;

Correctif 2 : les variables non initialisées dans les boucles
Dans content-link.php, une variable $content était utilisée avant d’être définie dans certains chemins conditionnels du fichier d’origine. La correction la plus sûre, sans réécrire la logique, consiste à initialiser la variable à une valeur neutre en haut de la portée concernée.
$content = '';
if ( has_excerpt() ) {
$content = get_the_excerpt();
}
Ce genre de correctif reste local et n’affecte jamais le comportement observable du thème : il se contente de donner une valeur par défaut à ce que PHP 7.4 refuse désormais de considérer comme implicitement vide.
Correctif 3 : count() sur une valeur non tableau
PHP 7.4 renvoie un avertissement (et PHP 8 une erreur fatale) quand count() reçoit autre chose qu’un tableau ou un objet Countable. Le fichier inc/customizer.php appelait count() sur un résultat de get_theme_mod() qui pouvait être une chaîne vide dans certains parcours du Customizer.
$choices = get_theme_mod( 'twentyfifteen_sidebar_order', array() );
if ( ! is_array( $choices ) ) {
$choices = array();
}
$total = count( $choices );
Correctif 4 : les fonctions dépréciées annexes
Twenty Quinze n’utilisait heureusement aucune fonction supprimée en PHP 7.4, mais un plugin tiers activé sur le même site appelait encore create_function(), retirée définitivement à cette version. Ce n’est pas un défaut du thème, mais un point à vérifier systématiquement dans ce genre de montée de version : le thème n’est jamais seul en cause.
Prévention : verrouiller le comportement pour la suite
Une fois les six fichiers corrigés, j’ai ajouté un test automatisé minimal exécutant chaque template principal avec WP_DEBUG actif, sur un environnement de staging, avant chaque future montée de version PHP. Ce filet est volontairement léger : il ne remplace pas une suite de tests complète, mais il évite de redécouvrir les mêmes six fichiers dans deux ans lors du passage à une version PHP ultérieure.
- Conserver une copie du thème original avant tout correctif, pour pouvoir comparer les diffs.
- Documenter chaque correctif dans un commit séparé, avec le numéro de ligne d’origine.
- Éviter la tentation de refactoriser au passage : le but est la stabilité, pas la modernisation.
Sur ce type de mission, je résiste toujours à l’envie de tout réécrire proprement : le client paie pour que le site continue de fonctionner, pas pour un thème repensé qu’il n’a pas demandé.
Pour aller plus loin
Remonter un thème par défaut vieux de plusieurs années sous une version PHP récente est un exercice ciblé : activer le journal d’erreurs, isoler les fichiers concernés, corriger localement chaque accès non sécurisé, puis verrouiller avec un test de non-régression léger. Ce chantier n’a rien à voir avec une réécriture complète du thème, qui n’était de toute façon pas dans le périmètre demandé par le client.