Le WordPress d'aujourd'hui, décodé pour les développeurs

Extensions

Un plantage à l’activation quand deux extensions incluent le même code tiers

Un composant PHP partagé, inclus par deux extensions sans espace de noms distinct, provoque un conflit de classes à l'activation croisée.

Par WordPress Développement • 30 décembre 2021 • 4 min de lecture • Aucun commentaire
Un plantage à l'activation quand deux extensions incluent le même code tiers

Fatal error: Cannot declare class ParsedownExtra, because the name is already in use — ce message, ou une variante très proche selon la bibliothèque en cause, apparaît généralement au moment le plus inopportun : juste après l’activation d’une seconde extension sur un site qui fonctionnait très bien jusque-là.

Symptôme

Le site affiche une page blanche, ou un écran d’erreur générique de l’administration, immédiatement après l’activation d’une nouvelle extension. Les journaux d’erreurs PHP montrent une erreur fatale de type « impossible de déclarer la classe », suivie du nom d’une classe qui ne semble appartenir directement ni à la nouvelle extension, ni à celle qui fonctionnait déjà. Le nom en question évoque souvent une bibliothèque tierce connue : un analyseur Markdown, une bibliothèque de journalisation, un client HTTP.

L'essentiel à retenir : Une classe déjà déclarée provoque une erreur fatale immédiate ; Deux extensions embarquant la même bibliothèque sans namespace en sont souvent la cause ; L'isolement par namespace ou par Composer résout durablement le conflit

Diagnostic

Le motif du conflit est presque toujours le même : deux extensions différentes embarquent, chacune de leur côté, une copie de la même bibliothèque PHP tierce, sans l’isoler dans un espace de noms qui leur soit propre. Tant qu’une seule des deux extensions est active, PHP ne déclare la classe qu’une fois, sans problème. Dès que la seconde extension est activée à son tour, son fichier tente de déclarer une classe portant exactement le même nom, dans le même espace de noms global (ou l’absence d’espace de noms), ce que PHP refuse catégoriquement.

Pour confirmer ce diagnostic, il suffit de rechercher, dans les deux extensions, un fichier contenant la déclaration de la classe mentionnée dans l’erreur :

grep -rn "class ParsedownExtra" wp-content/plugins/

Si cette recherche retourne deux résultats, dans deux dossiers d’extensions différents, le diagnostic est confirmé : les deux extensions ont inclus indépendamment la même bibliothèque, probablement à des versions différentes, sans jamais anticiper qu’elles pourraient un jour cohabiter sur le même site.

Correctif

La solution durable consiste à isoler chaque bibliothèque tierce dans un espace de noms propre à l’extension qui l’utilise. Un outil comme Composer, combiné à une déclaration d’espace de noms cohérente, permet d’éviter ce genre de collision :

namespace MonExtension\Vendor;

require_once __DIR__ . '/vendor/parsedown/ParsedownExtra.php';

Quand la bibliothèque tierce elle-même ne déclare pas d’espace de noms (ce qui est fréquent pour des bibliothèques PHP plus anciennes), la solution la plus fiable consiste à utiliser un outil de préfixage automatique de dépendances, qui réécrit physiquement les noms de classes de la bibliothèque embarquée avec un préfixe propre à chaque extension avant publication. Cette étape s’intègre dans le processus de build de l’extension, pas dans son code d’exécution.

En attendant une refonte plus profonde, une correction immédiate et temporaire consiste à vérifier l’existence de la classe avant de l’inclure :

if ( ! class_exists( 'ParsedownExtra' ) ) {
    require_once __DIR__ . '/vendor/parsedown/ParsedownExtra.php';
}

Cette vérification évite le plantage immédiat, mais elle a un effet secondaire à surveiller : la première extension activée impose sa version de la bibliothèque à la seconde, ce qui peut provoquer un comportement inattendu si les deux versions diffèrent sur un point de fonctionnement utilisé par la seconde extension.

Prévention

  • Toujours isoler les bibliothèques tierces embarquées dans un espace de noms propre à l’extension, jamais dans l’espace de noms global.
  • Privilégier un outil de préfixage de dépendances lors de la construction d’une extension destinée à un public large.
  • Documenter, dans le fichier principal de l’extension, la liste des bibliothèques tierces embarquées et leur version, pour faciliter le diagnostic en cas de conflit signalé par un client.
  • Tester systématiquement l’activation croisée avec les extensions les plus courantes du même écosystème métier avant publication.

Un conflit de classes ne se révèle jamais en développement isolé — il n’apparaît qu’au moment précis où deux mondes indépendants se rencontrent sur le même site.

En résumé

Une erreur fatale de classe déjà déclarée, à l’activation croisée de deux extensions, pointe presque toujours vers une bibliothèque tierce partagée sans isolement. L’espace de noms — ou, à défaut, un préfixage automatique des dépendances — reste la protection la plus fiable contre ce type de conflit, bien plus robuste qu’une simple vérification d’existence de classe posée après coup.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi