unleash/symfony-client-bundle
Symfony bundle for integrating Unleash feature flags with the Unleash PHP SDK. Configure toggles through Symfony services and configuration, then check flags in your app to roll out features safely and gradually.
This is the Symfony integration for Unleash, not a Laravel-native package. In a Laravel app you have two realistic entry points:
unleash/unleash-client) — the least friction for Laravel. Install it, bind Unleash\Client\Unleash as a singleton in a service provider, pull it via the container, and toggle on isEnabled('flag', $context).Minimum viable path with the PHP SDK:
composer require unleash/unleash-client
// AppServiceProvider::register()
$this->app->singleton(Unleash::class, fn () => new Unleash(
new UnleaseBuilder()
->withUrl(config('services.unleash.url'))
->withInstanceId(config('services.unleash.instance_id'))
->withAppName(config('app.name'))
->withMetricsInterval(30000)
->build()
));
First use case: gate a single risky feature (new checkout, redesigned nav) behind $unleash->isEnabled('new-checkout', $context) and leave everything else untouched.
Look first at:
UnleashBuilder / configuration reference for connection and metrics options.config/services.php and a dedicated config/unleash.php for env-driven setup.Context object per request. Unleash's killer feature is contextual evaluation. Build a UnleashContext from the authenticated user (or session/device ID for anonymous traffic) in a middleware, and inject it wherever flags are checked:
$context = (new UnLeashContext())
->setUserId((string) $request->user()?->id)
->setSessionId($request->session()->getId())
->setCurrentTime(Carbon::now());
Wrap flag checks in a small service. Don't scatter isEnabled() calls across controllers. Create App\Features\Flags with typed methods (isNewCheckoutEnabled(User $user)), so flags are testable, greppable, and easy to swap. Fake it in tests with an in-memory implementation — you do not want unit tests hitting the Unleash API.
Kill-switch pattern for migrations. Wrap risky deployments behind a flag: ship code dark, flip the flag in Unleash, monitor, then remove the branch. This is the single highest-value workflow for day-to-day use.
Blade + middleware integration. Resolve flags in middleware and share them via View::share('flags', $flags) or a @feature('new-checkout') Blade directive. Keep the evaluation server-side; never call Unleash from JS.
Gradual rollout. Use percentage strategies keyed on userId (or a stable session ID) so users get a consistent experience across requests. Don't key on request ID or timestamp — you'll get flicker.
Metrics and health. Configure the metrics interval and enable the SDK's built-in health check ($unleash->isEnabled('x') returning a default on failure). Register /health to report Unleash reachability if you gate critical paths on flags.
Symfony 8 note (v0.12.285). This release only broadens the Symfony constraint to ^8.0. For Laravel apps it's a forward-compatibility update: Laravel 11/12 ship Symfony 7.x components, so nothing changes functionally today. It matters if you're on Symphony 8 or plan to be — the bundle won't fight your dependency resolver. No config, API, or behavior changes.
composer update.isEnabled() returns the default you passed. Set explicit, safe defaults per flag — don't rely on the SDK guessing.isEnabled() can hit the local cache but context building is your cost. Build context once per request; batch-evaluate.phpunit.xml to force the client off in CI so tests never touch the network. Explicit setEnabled(true/false) per test beats real API calls.0.12.285) or use ~0.12 and review the changelog on each bump.unleash/unleash-client + a thin Laravel service provider. The Symfony bundle's value is Symfony-native wiring, which Laravel doesn't give you out of the box.How can I help you explore Laravel packages today?