Feature flags, the Symfony way.
Symfony bundle for the OpenFeature PHP SDK — the CNCF standard for feature flags.
class CheckoutController
{
#[FeatureGate('new_checkout')]
public function checkout(
#[FeatureFlag('dark_mode')] bool $darkMode,
#[FeatureFlag('max_items')] int $maxItems,
): Response {
// values resolved from your feature flag provider
}
}#[FeatureGate]blocks access when a flag is off#[FeatureFlag]injects resolved values, fully typed- Twig helpers:
feature('flag'),feature_value('flag', default) - Symfony Profiler panel with evaluated flags, provider info, and context
- Any provider: basic built-ins (InMemory, EnvVar, Redis) for quick starts, or plug any real OpenFeature provider (Flagd, ConfigCat, Unleash, LaunchDarkly...)
- FrankenPHP worker mode safe out of the box
- PHP 8.2+
- Symfony 6.4, 7.x or 8.x
open-feature/sdk^2.0 (implements OpenFeature spec v0.5.1)
composer require aubes/openfeature-bundleRegister the bundle manually in
config/bundles.php:Aubes\OpenFeatureBundle\OpenFeatureBundle::class => ['all' => true],
# config/packages/open_feature.yaml
open_feature:
flags:
new_checkout: true
dark_mode: false
max_items: 10Use flags in controllers with attributes, in templates with Twig, or inject the Client directly:
use OpenFeature\interfaces\flags\Client;
class MyService
{
public function __construct(private readonly Client $client) {}
public function checkout(): void
{
if ($this->client->getBooleanValue('new_checkout', false)) {
// new flow
}
}
}{% if feature('new_checkout') %}
{# new checkout #}
{% endif %}
{{ feature_value('max_items', 10) }}The bundle works with any OpenFeature provider.
For anything beyond a quick demo (user targeting, percentage rollouts, A/B testing, remote flag management, audit log), use a dedicated provider:
aubes/openfeature-flagd-bundle: self-hosted Flagd backend from the OpenFeature projectaubes/openfeature-configcat-bundle: ConfigCat SaaS- Any other provider from open-feature/php-sdk-contrib (Unleash, LaunchDarkly, Split, GO Feature Flag, ...)
Warning: The three built-in providers are simple key/value stores. They ignore the
EvaluationContext(no targeting, no rollouts, no A/B testing) and are only meant to get you running without setting up infrastructure. Swap them out as soon as you need real feature flag semantics.
| Provider | Best for | Config key |
|---|---|---|
| InMemoryProvider (default) | Local development, tests | flags |
| EnvVarProvider | Kill switches via env vars | provider |
| RedisProvider | Shared on/off toggles via Redis | provider + redis |
Full documentation lives in the docs/ folder:
- Getting started
- Configuration reference
- Providers (Flagd, ConfigCat, built-ins for bootstrap)
- Features (#[FeatureFlag], #[FeatureGate], Twig, EvaluationContext, Hooks)
- Profiler & Debug
MIT. See LICENSE.