vendredi 25 septembre 2026

À propos

Contact

Extensions

Feature flags dans une extension : livrer une fonctionnalité progressivement

Plutôt que de basculer une nouveauté pour tous les sites d'un coup, un simple système d'options booléennes permet de l'activer site par site et de reculer sans redéploiement.

Par Clément Hadrot • 23 novembre 2021 • 5 min de lecture • Aucun commentaire
Feature flags dans une extension : livrer une fonctionnalité progressivement

Une extension de réservation de salles, utilisée par une trentaine d’établissements, doit recevoir un nouveau moteur de calcul de disponibilité, plus rapide mais dont le comportement diffère légèrement de l’ancien sur les cas de réservations qui se chevauchent partiellement. L’équipe qui maintient l’extension ne veut pas basculer les trente établissements en même temps : elle veut l’activer d’abord sur deux sites pilotes, observer une semaine, puis étendre progressivement.

Plutôt que de maintenir deux branches de code séparées ou de livrer deux versions différentes de l’extension selon le client, la solution retenue est un système de feature flags simple, piloté par une option, qui permet d’activer ou de désactiver le nouveau moteur sans toucher au code ni redéployer quoi que ce soit.

Le principe

Un feature flag n’est rien de plus qu’une valeur booléenne consultée à un point précis du code, qui détermine quel chemin d’exécution suivre. Sa force ne vient pas de sa complexité technique, mais de la discipline avec laquelle on l’installe : jamais codé en dur dans une condition if perdue au milieu d’une fonction, toujours centralisé derrière une fonction d’accès dédiée.

function moteur_disponibilite_v2_actif(): bool {
    /**
     * Filtre le statut du nouveau moteur de calcul de disponibilité.
     *
     * @param bool $actif Vrai si le nouveau moteur doit être utilisé.
     */
    return (bool) apply_filters(
        'reservation_moteur_v2_actif',
        get_option( 'reservation_moteur_v2_actif', false )
    );
}

Ce choix de passer par apply_filters() en plus de get_option() offre deux niveaux de contrôle : l’option en base pour un pilotage simple depuis l’administration, et le filtre pour un pilotage programmatique, utile par exemple pour forcer l’activation sur un site précis identifié par son home_url(), sans même toucher à l’interface d’administration.

Utilisation dans le code métier

L'essentiel à retenir : Un flag se pilote comme un réglage, pas comme une variable codée en dur ; Séparer le flag de la logique métier garde le code lisible dans le temps ; Un flag oublié devient une dette : prévoir sa date de retrait dès sa création
function calculer_disponibilite_salle( int $salle_id, string $date_debut, string $date_fin ) {
    if ( moteur_disponibilite_v2_actif() ) {
        return calculer_disponibilite_v2( $salle_id, $date_debut, $date_fin );
    }

    return calculer_disponibilite_v1( $salle_id, $date_debut, $date_fin );
}

Le point clé de cette architecture : la fonction métier ne connaît qu’un seul point de décision, clairement identifié, jamais dispersé dans plusieurs fichiers. Un développeur qui reprend ce code six mois plus tard comprend immédiatement où se trouve la bascule, sans avoir à parcourir l’ensemble du plugin à la recherche de conditions éparses.

Piloter le flag depuis l’administration

add_action( 'admin_init', function() {
    register_setting( 'reservation_options', 'reservation_moteur_v2_actif', array(
        'type'              => 'boolean',
        'sanitize_callback' => 'rest_sanitize_boolean',
        'default'           => false,
    ) );
} );

Un simple champ à cocher dans l’écran de réglages, accessible uniquement aux administrateurs, suffit à faire basculer un site d’un moteur à l’autre en quelques secondes, sans intervention d’un développeur ni redéploiement de code.

Étendre le contrôle : par pourcentage ou par identifiant

Pour une extension distribuée à un grand nombre de sites via un réseau multisite ou un service centralisé, un simple booléen peut être complété par un tirage pondéré, utile pour un déploiement progressif par pourcentage plutôt que site par site :

function moteur_disponibilite_v2_actif_pourcentage( int $pourcentage_cible ): bool {
    $graine = crc32( home_url() );
    $tirage = $graine % 100;

    return $tirage < $pourcentage_cible;
}

Cette variante garde un comportement stable pour un même site d'une requête à l'autre, puisque le tirage dépend d'une valeur fixe propre au site, home_url(), plutôt que d'un nombre aléatoire qui changerait à chaque appel.

Le piège du flag qu'on oublie de retirer

Le principal défaut d'un système de feature flags mal géré n'est pas technique, il est organisationnel : une fois la migration terminée sur l'ensemble du parc, personne ne pense à retirer le code de l'ancien moteur ni le flag lui-même, qui traînent alors pendant des années comme une branche morte jamais élaguée. Chaque flag créé doit donc être accompagné, dès sa création, d'un ticket de suivi explicite pour son retrait une fois la bascule généralisée et validée.

  • Noter dans le code un commentaire daté indiquant depuis quand le flag existe et pourquoi.
  • Fixer, même de façon informelle, une date cible de retrait du chemin de code obsolète.
  • Éviter d'empiler plus de deux ou trois flags actifs simultanément sur la même fonctionnalité, sous peine de rendre les combinaisons possibles impossibles à tester exhaustivement.

Un flag qui vit plus longtemps que la fonctionnalité qu'il devait accompagner temporairement n'est plus un outil de livraison progressive, c'est une dette technique déguisée en réglage.

En résumé

Un système de feature flags basé sur une option et un filtre, sans bibliothèque externe ni infrastructure dédiée, suffit largement à la majorité des extensions WordPress qui veulent livrer une fonctionnalité sensible de façon progressive. La discipline qui entoure sa mise en place et surtout son retrait compte bien plus que sa sophistication technique.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi