Feature flags en PHP : activez des fonctionnalités sans déploiement ni prières
\n\nImaginez : vous déployez une nouvelle fonctionnalité et tout s'effondre. Le site plante, les clients paniquent, les devs se grattent la tête. Ça vous parle ? Et si vous pouviez activer cette fonctionnalité pour seulement 5% des utilisateurs, observer les métriques, et si quelque chose cloche, simplement basculer un interrupteur pour revenir en arrière. Sans déploiement, sans commit, sans douleur. Ce n'est pas de la magie, ce sont les feature flags en PHP.
\n\nLes feature flags (aussi appelés feature toggles) sont une technique qui permet d'activer ou de désactiver des fonctionnalités d'une application sans modifier le code ni redéployer. Ça ressemble à un super-pouvoir ? C'est exactement ça. Dans cet article, nous allons voir comment implémenter la gestion de fonctionnalités en PHP dans des projets réels : du simple fichier de configuration à l'intégration avec Symfony et Laravel. C'est parti !
\n\nPourquoi utiliser les feature flags dans vos projets PHP ?
\n\nPrenons un exemple : vous développez une boutique en ligne en PHP. Le client vous demande d'ajouter une nouvelle passerelle de paiement. Vous écrivez le code, vous testez en local, mais en production — surprise : la passerelle fonctionne de manière instable. Habituellement, cela signifie : correctif urgent, déploiement de nuit, chef d'équipe stressé. Avec les feature flags, c'est tout différent. Vous désactivez simplement le flag, et l'ancienne passerelle continue de fonctionner pendant que vous corrigez le bug tranquillement.
\n\nQuand les feature flags sont-ils particulièrement utiles ?
\n- \n
- Canary releases (déploiements canaris) — activez la fonctionnalité pour 1% des utilisateurs, puis 10%, puis tout le monde. \n
- Tests A/B — montrez différentes fonctionnalités à différents groupes et comparez les taux de conversion. \n
- Désactivation d'une fonctionnalité défaillante — un bug en production ? Désactivez le flag sans annuler tout le déploiement. \n
- Déploiement progressif — déployez une fonctionnalité progressivement pour ne pas surcharger les serveurs. \n
Et surtout : les feature flags en PHP réduisent le risque lié au déploiement. Vous n'avez plus peur de faire un commit le vendredi soir (enfin, presque).
\n\nImplémentation simple : le fichier de configuration
\n\nCommençons par les bases. La méthode la plus simple consiste à stocker les flags dans un fichier de configuration, par exemple sous forme de tableau PHP ou de JSON.
\n\n// config/features.php\nreturn [\n 'new_checkout' => false,\n 'dark_mode' => true,\n 'ai_recommendations' => false,\n];\n\n\nUtilisation dans le code :
\n\n// src/CheckoutService.php\n$features = require __DIR__ . '/config/features.php';\n\nif ($features['new_checkout']) {\n // Nouvelle logique de paiement\n $this->processWithNewGateway();\n} else {\n // Ancienne logique\n $this->processWithOldGateway();\n}\n\n\nL'inconvénient est évident : pour modifier un flag, vous devez éditer le fichier sur le serveur. Ce n'est ni pratique ni sécurisé. Mais pour les petits projets, cela suffit. L'essentiel est de comprendre le principe : les feature flags PHP sont simplement des conditions liées à un stockage externe.
\n\nNiveau avancé : stockage en base de données
\n\nQuand le projet grandit, le fichier de configuration devient un goulot d'étranglement. On souhaite gérer les flags via une interface d'administration. C'est là que la base de données entre en jeu.
\n\nCréons une table simple :
\n\nCREATE TABLE feature_flags (\n id INT AUTO_INCREMENT PRIMARY KEY,\n name VARCHAR(100) UNIQUE NOT NULL,\n enabled TINYINT(1) DEFAULT 0,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n\nEt écrivons un service simple pour gérer les flags :
\n\nclass FeatureFlagService\n{\n private PDO $pdo;\n private array $cache = [];\n\n public function __construct(PDO $pdo)\n {\n $this->pdo = $pdo;\n }\n\n public function isEnabled(string $flagName): bool\n {\n if (!isset($this->cache[$flagName])) {\n $stmt = $this->pdo->prepare(\n 'SELECT enabled FROM feature_flags WHERE name = ?'\n );\n $stmt->execute([$flagName]);\n $row = $stmt->fetch(PDO::FETCH_ASSOC);\n $this->cache[$flagName]