FeatureFlagSelectorSet
The FeatureFlagSelectorSet class enables conditional execution based on multiple feature flag states. The handler
is executed only when ALL specified conditions are met (logical AND operation).
Basic Usage
use ByJG\FeatureFlag\FeatureFlags;
use ByJG\FeatureFlag\FeatureFlagDispatcher;
use ByJG\FeatureFlag\FeatureFlagSelectorSet;
use ByJG\FeatureFlag\FeatureFlagHandlerInterface;
// Define multiple flags
FeatureFlags::addFlag('premium-user', 'true');
FeatureFlags::addFlag('beta-access', 'enabled');
FeatureFlags::addFlag('region', 'US');
// Create handler
class PremiumBetaHandler implements FeatureFlagHandlerInterface
{
public function execute(mixed ...$args): mixed
{
echo "Premium beta feature unlocked!\n";
return null;
}
}
// Create a Dispatcher
$dispatcher = new FeatureFlagDispatcher();
// Create selector set - handler executes ONLY if ALL conditions match
$selectorSet = FeatureFlagSelectorSet::instance(new PremiumBetaHandler())
->whenFlagIs('premium-user', 'true')
->whenFlagIs('beta-access', 'enabled')
->whenFlagIsSet('region');
// Add to dispatcher
$dispatcher->add($selectorSet);
// Dispatch the request
$dispatcher->dispatch();
How It Works
The FeatureFlagSelectorSet uses a builder pattern to define multiple conditions:
- Start with
instance()providing the handler - Chain
whenFlagIs()and/orwhenFlagIsSet()for each condition - Add to the dispatcher
- The handler executes only if ALL conditions match
Factory Method
instance(FeatureFlagHandlerInterface $handler)
Creates a new selector set with the specified handler:
$set = FeatureFlagSelectorSet::instance($handler);
Condition Methods
whenFlagIs(string $flag, string $value)
Adds a condition requiring the flag to have a specific value:
$set->whenFlagIs('feature', 'enabled');
whenFlagIsSet(string $flag)
Adds a condition requiring the flag to exist with any value:
$set->whenFlagIsSet('debug-mode');
Method Chaining
All condition methods return $this, enabling fluent chaining:
$set = FeatureFlagSelectorSet::instance($handler)
->whenFlagIs('tier', 'premium')
->whenFlagIs('region', 'US')
->whenFlagIsSet('early-access');
Examples
A/B Testing with User Segments
FeatureFlags::addFlag('user-segment', 'beta');
FeatureFlags::addFlag('experiment-ui', 'variant-b');
$dispatcher->add(
FeatureFlagSelectorSet::instance($experimentalUIHandler)
->whenFlagIs('user-segment', 'beta')
->whenFlagIs('experiment-ui', 'variant-b')
);
// Handler only runs for beta users in variant-b
$dispatcher->dispatch();
Regional Feature Rollout
FeatureFlags::addFlag('feature-payments', 'enabled');
FeatureFlags::addFlag('region', 'EU');
FeatureFlags::addFlag('gdpr-compliant');
$dispatcher->add(
FeatureFlagSelectorSet::instance($euPaymentHandler)
->whenFlagIs('feature-payments', 'enabled')
->whenFlagIs('region', 'EU')
->whenFlagIsSet('gdpr-compliant')
);
// Handler only runs when all three conditions are met
$dispatcher->dispatch();
Feature with Multiple Prerequisites
FeatureFlags::addFlag('database-migrated', 'v2');
FeatureFlags::addFlag('cache-enabled');
FeatureFlags::addFlag('feature-advanced-analytics', 'beta');
$dispatcher->add(
FeatureFlagSelectorSet::instance($analyticsHandler)
->whenFlagIs('database-migrated', 'v2')
->whenFlagIsSet('cache-enabled')
->whenFlagIs('feature-advanced-analytics', 'beta')
);
Multiple Selector Sets
You can add multiple selector sets with different condition combinations:
// Enterprise users in US
$dispatcher->add(
FeatureFlagSelectorSet::instance($enterpriseUSHandler)
->whenFlagIs('tier', 'enterprise')
->whenFlagIs('region', 'US')
);
// Enterprise users in EU
$dispatcher->add(
FeatureFlagSelectorSet::instance($enterpriseEUHandler)
->whenFlagIs('tier', 'enterprise')
->whenFlagIs('region', 'EU')
);
// Premium users anywhere
$dispatcher->add(
FeatureFlagSelector::whenFlagIs('tier', 'premium', $premiumHandler)
);
Comparison: Selector vs SelectorSet
| Feature | FeatureFlagSelector | FeatureFlagSelectorSet |
|---|---|---|
| Conditions | Single flag | Multiple flags (ALL must match) |
| Logic | Simple check | Logical AND |
| Creation | Direct factory methods | Builder pattern |
| Use Case | Simple toggles | Complex multi-condition scenarios |
| Syntax | whenFlagIs($flag, $value, $handler) | instance($handler)->whenFlagIs(...)->whenFlagIs(...) |
When to Use SelectorSet
Use FeatureFlagSelectorSet when:
- ✅ A feature requires multiple conditions to be enabled
- ✅ You need logical AND behavior across flags
- ✅ Features depend on user attributes + feature state
- ✅ Implementing gradual rollouts with multiple criteria
Use FeatureFlagSelector when:
- ✅ A single flag controls the feature
- ✅ You need simple on/off toggles
- ✅ Independent feature flags
Combining with Regular Selectors
You can mix both selector types in the same dispatcher:
// Complex multi-condition
$dispatcher->add(
FeatureFlagSelectorSet::instance($complexHandler)
->whenFlagIs('tier', 'enterprise')
->whenFlagIs('feature-x', 'beta')
);
// Simple single condition
$dispatcher->add(
FeatureFlagSelector::whenFlagIsSet('logging', $loggingHandler)
);
Internal Behavior
When dispatched, the FeatureFlagSelectorSet:
- Checks each added condition in order
- All conditions must evaluate to
true - If all match, the handler executes
- If any condition fails, the handler is skipped
See Also
- FeatureFlagSelector - Single condition selectors
- Handler Interface - Creating custom handlers
- Search Order - Controlling execution order
- Passing Arguments - Passing data to handlers