Installation
composer require dknx01/feature-flag-bundle
Add to config/app.php under providers:
Dknx\FeatureFlagBundle\FeatureFlagBundle::class,
First Flag Definition
Define a flag in config/featureflags.php (auto-generated on first run):
return [
'flags' => [
'new_ui' => [
'enabled' => false,
'description' => 'Enable the new user interface',
],
],
];
First Usage
use Dknx\FeatureFlagBundle\FeatureFlagManager;
$flagManager = app(FeatureFlagManager::class);
if ($flagManager->isEnabled('new_ui')) {
// Show new UI
}
Environment-Specific Flags
Use featureflags_[env].php (e.g., featureflags_production.php) for environment overrides.
Flag Evaluation
// Basic check
$isEnabled = $flagManager->isEnabled('flag_name');
// With user context (if using user-based flags)
$isEnabled = $flagManager->isEnabled('flag_name', $user);
Dynamic Flag Updates
// Runtime updates (e.g., via admin panel)
$flagManager->setEnabled('flag_name', true);
Group-Based Flags
// Define in config:
'flags' => [
'premium_feature' => [
'enabled' => true,
'groups' => ['premium_users'],
],
],
// Check in code:
$flagManager->isEnabled('premium_feature', $user);
A/B Testing
// Define in config:
'flags' => [
'ab_test_variant' => [
'enabled' => true,
'variants' => ['A', 'B'],
'strategy' => 'random', // or 'user_hash', 'cookie'
],
],
// Get variant:
$variant = $flagManager->getVariant('ab_test_variant', $user);
Service Container Binding Bind the manager to your container for cleaner usage:
$this->app->bind('featureFlag', function ($app) {
return $app->make(FeatureFlagManager::class);
});
Then inject via constructor:
public function __construct(private FeatureFlagManager $flagManager) {}
Middleware for Route-Based Flags
public function handle($request, Closure $next)
{
if (!$this->flagManager->isEnabled('admin_panel')) {
abort(403);
}
return $next($request);
}
Event Listeners Listen for flag changes (e.g., log updates):
public function handle(FlagUpdatedEvent $event)
{
Log::info("Flag {$event->getFlagName()} updated to {$event->isEnabled()}");
}
Caching Issues
php artisan cache:clear
config/featureflags.php if needed:
'cache_enabled' => false,
User Context Overrides
isEnabled() implement getId() or getEmail() as required by the bundle.Configuration Merging
featureflags_[env].php) are merged after the base config. Overrides must be explicit.Variant Strategies
Dknx\FeatureFlagBundle\Strategy\VariantStrategyInterface. Default strategies (random, user_hash) may not suit all use cases.Enable Logging
Set debug to true in config/featureflags.php to log flag evaluations:
'debug' => env('APP_DEBUG', false),
Check Flag Existence
Use hasFlag() to avoid runtime errors:
if ($flagManager->hasFlag('non_existent_flag')) {
// Safe to check
}
Validate Config Run:
php artisan featureflag:validate
To catch config syntax errors early.
Custom Strategies Register a new variant strategy:
$flagManager->addVariantStrategy('custom', new CustomStrategy());
Flag Providers Extend functionality by creating a custom provider:
class DatabaseFlagProvider implements FlagProviderInterface
{
public function getFlag(string $name): ?array
{
// Fetch from DB
}
}
Register in config/featureflags.php:
'providers' => [
'database',
// Your custom provider
],
Event Customization
Extend or override events (e.g., FlagUpdatedEvent) to trigger custom logic.
API for Admin Panels Use the built-in API endpoints (if enabled) or create a custom controller to manage flags dynamically:
// Example route:
Route::post('/admin/flags/{name}', [FlagController::class, 'update']);
How can I help you explore Laravel packages today?