aubes / openfeature-bundle
Symfony bundle for OpenFeature PHP SDK
Package info
github.com/aubes/openfeature-bundle
Type:symfony-bundle
pkg:composer/aubes/openfeature-bundle
Requires
- php: >=8.2
- open-feature/sdk: ^2.0
- symfony/config: ^6.4|^7.4|^8.0
- symfony/dependency-injection: ^6.4|^7.4|^8.0
- symfony/http-kernel: ^6.4|^7.4|^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^11.0|^12.0
- rector/rector: ^2.4
- symfony/framework-bundle: ^6.4|^7.0|^8.0
- symfony/security-core: ^6.4|^7.0|^8.0
- twig/twig: ^3.24
Suggests
- symfony/security-core: Required for auto-populating the targeting key from the authenticated user and for AccessDeniedException support
- twig/twig: Required for the feature() Twig function
This package is auto-updated.
Last update: 2026-04-25 08:13:45 UTC
README
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) - Hooks autoconfigured: implement
Hookfor logging, tracing, validation - Evaluation context autoconfigured: implement
EvaluationContextProviderInterfaceto feed targeting attributes - 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
Requirements
- PHP 8.2+
- Symfony 6.4, 7.x or 8.x
open-feature/sdk^2.0 (implements OpenFeature spec v0.5.1)
Quick start
composer require aubes/openfeature-bundle
Register 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: 10
Use 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) }}
Providers
The bundle works with any OpenFeature provider.
Use a real provider in production
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, ...)
Built-in providers (bootstrap only)
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 |
Documentation
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
License
MIT. See LICENSE.