# Twenty Quinze sous PHP 7.4 : les correctifs qu’on applique en urgence

> Un hébergeur force la montée vers PHP 7.4 et un vieux Twenty Quinze se met à afficher des notices partout. Diagnostic et correctifs minimaux, sans réécrire le thème.

- Auteur : Clément Hadrot
- Publié le : 2020-07-09
- Mis à jour le : 2020-07-09
- Catégorie : Thèmes
- URL : https://wpmoderne.dev.wordpress-developpement.fr/themes/twenty-quinze-php74-correctifs-urgence/

## L’essentiel

- Les notices viennent surtout de tableaux et variables non initialisés
- array_key_exists évite la majorité des Undefined index
- Un correctif ciblé suffit, pas besoin de réécrire le thème

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;
```

> L'essentiel à retenir : Les notices viennent surtout de tableaux et variables non initialisés ; array_key_exists évite la majorité des Undefined index ; Un correctif ciblé suffit, pas besoin de réécrire le thème

## 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.
