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

Thèmes

Sécuriser l’appel d’une fonction de thème absente, avant une erreur fatale

Une extension qui présume la présence d'une fonction du thème sans la vérifier finit tôt ou tard par provoquer une erreur fatale. Voici comment un thème peut rester compatible sans rien casser.

Par WordPress Développement • 10 mars 2023 • 5 min de lecture • Aucun commentaire
Sécuriser l'appel d'une fonction de thème absente, avant une erreur fatale

« Fatal error: Uncaught Error: Call to undefined function woocommerce_breadcrumb() » : ce message, affiché en plein écran blanc à la place du site, apparaît généralement après la désactivation d’une extension que le thème avait discrètement pris l’habitude d’appeler sans jamais vérifier sa présence. La fonction fautive était présente hier, elle a disparu aujourd’hui, et rien dans le code du thème n’anticipait ce cas.

Un thème qui ajoute une fonctionnalité optionnelle liée à une extension — un fil d’Ariane WooCommerce, un champ ACF, un shortcode d’un plugin de formulaire — ne devrait jamais présumer que cette extension restera active indéfiniment. La sécurisation de ces appels ne demande que quelques lignes, mais elle change complètement la manière dont un site se comporte lorsqu’une pièce du puzzle vient à manquer.

Pourquoi une fonction absente casse tout le site, pas seulement une fonctionnalité

En PHP, appeler une fonction qui n’existe pas ne produit pas un simple avertissement récupérable : depuis PHP 7, cela lève une erreur fatale de type Error, qui interrompt immédiatement l’exécution du script en cours. Sur un thème WordPress, cela signifie que la page entière s’arrête au milieu de son rendu, souvent avant même que le pied de page ne s’affiche, laissant un écran blanc ou partiellement rendu à la place du site.

function_exists() : la protection la plus simple

La fonction native function_exists() vérifie qu’une fonction est bien déclarée avant de l’appeler, sans lever d’erreur si ce n’est pas le cas :

if ( function_exists( 'woocommerce_breadcrumb' ) ) {
    woocommerce_breadcrumb();
}
L'essentiel à retenir : function_exists() protège tout appel dépendant d'une extension tierce ; Une fonction non définie provoque une Fatal error, pas un simple avertissement ; Le pattern s'applique aussi bien aux fonctions qu'aux classes

Ce test coûte une fraction de milliseconde à l’exécution, et il transforme une erreur bloquante en simple absence d’affichage, ce qui est presque toujours préférable pour un visiteur du site.

Le même principe s’applique aux classes

Quand un thème dépend d’une classe fournie par une extension plutôt que d’une fonction, la vérification équivalente est class_exists() :

if ( class_exists( 'WooCommerce' ) ) {
    // Le thème peut afficher un lien vers le panier.
}

Cette vérification est particulièrement utile dans les fichiers chargés très tôt, par exemple lorsqu’un thème définit ses propres classes PHP qui étendent une classe fournie par une extension : sans ce test, l’extension d’une classe absente provoque également une erreur fatale, cette fois dès le chargement du fichier plutôt qu’au moment de l’appel.

Aller plus loin : dégrader gracieusement plutôt que masquer un vide

Cacher l’appel ne suffit pas toujours : un fil d’Ariane manquant peut laisser un trou visuel dans la mise en page. Il est souvent préférable de prévoir un remplacement, même minimal :

if ( function_exists( 'woocommerce_breadcrumb' ) ) {
    woocommerce_breadcrumb();
} elseif ( function_exists( 'the_title' ) ) {
    echo '<p class="fil-ariane-repli">';
    the_title();
    echo '</p>';
}

Ce repli garantit qu’un visiteur ne remarque presque rien, même si l’extension attendue vient à être désactivée temporairement pour une maintenance.

Documenter la dépendance plutôt que la cacher entièrement

Un thème qui masque silencieusement l’absence d’une extension peut aussi induire l’équipe en erreur : personne ne remarque qu’une fonctionnalité a disparu, jusqu’à ce qu’un client s’en aperçoive. Ajouter une notice discrète dans l’administration, visible uniquement par les rôles autorisés à gérer les extensions, permet de garder la visibilité sur la dépendance sans bloquer le rendu du site :

add_action( 'admin_notices', function () {
    if ( ! class_exists( 'WooCommerce' ) && current_user_can( 'activate_plugins' ) ) {
        echo '<div class="notice notice-warning"><p>';
        echo 'Ce thème attend WooCommerce pour afficher le fil d\'Ariane produit.';
        echo '</p></div>';
    }
} );

Un thème qui suppose la présence permanente d’une extension tierce transfère sa fragilité à toute personne qui gère le site ensuite, souvent sans qu’elle en soit informée avant l’incident.

Les endroits où cette vigilance compte le plus

  • Les fichiers de gabarit affichés en frontal (single.php, archive.php, header.php), où une erreur fatale bloque immédiatement l’affichage pour tous les visiteurs.
  • Les hooks exécutés très tôt, comme after_setup_theme, où l’ordre de chargement entre thème et extensions n’est pas garanti.
  • Toute fonction de compatibilité ajoutée « au cas où » pour une extension populaire, qui peut très bien ne jamais être installée sur un site donné.

En résumé

Une extension présente aujourd’hui peut disparaître demain, désactivée pour un diagnostic, retirée après un changement d’outil, ou simplement absente sur un nouveau site basé sur le même thème. function_exists() et class_exists() ne demandent qu’une ligne de code supplémentaire à chaque appel sensible, mais elles transforment une panne totale du site en simple absence d’un détail, ce qui reste, dans presque tous les cas, largement préférable.

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