rasuvaeff/yii3-feature-flags
最新稳定版本:v2.0.0
Composer 安装命令:
composer require rasuvaeff/yii3-feature-flags
包简介
Feature flags, kill switches and percentage rollout for Yii3 applications
README 文档
README
Feature flags, kill switches and percentage rollout for Yii3 applications.
Stateless core — storage backends are separate packages. Deterministic rollout via SHA-256 hash. Works with Yii3 config-plugin or standalone.
Using an AI coding assistant? llms.txt has a compact API reference you can give to the LLM to help it work with this package.
Requirements
- PHP 8.3+
Installation
composer require rasuvaeff/yii3-feature-flags
Usage
Basic flag check
use Rasuvaeff\Yii3FeatureFlags\FeatureFlags; use Rasuvaeff\Yii3FeatureFlags\FlagContext; if ($featureFlags->isEnabled( flag: 'new-checkout', context: FlagContext::forUser(userId: $userId), )) { // New checkout flow. }
Configuration
In your application config (config/params.php):
return [ 'rasuvaeff/yii3-feature-flags' => [ 'flags' => [ 'new-checkout' => [ 'enabled' => true, 'salt' => 'new-checkout-v1', 'rollout' => 25, 'killSwitch' => false, 'environments' => ['production'], ], ], ], ];
Configuration options
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
bool |
true |
Master switch for the flag |
salt |
string |
flag name | Hash salt for deterministic rollout |
rollout |
int |
100 |
Percentage of subjects to include (0..100) |
killSwitch |
bool |
false |
Immediately disable the flag, overrides all rules |
environments |
list<string> |
[] |
Restrict to specific environments (empty = all) |
FlagContext
// By user ID $context = FlagContext::forUser(userId: 'user-42'); // By tenant ID $context = FlagContext::forTenant(tenantId: 'tenant-1'); // By environment $context = FlagContext::forEnvironment(environment: 'production'); // Combined $context = FlagContext::forUser(userId: 'user-42') ->withEnvironment(environment: 'production');
Forced values
Use forced values for QA/debug overrides on existing flags:
$context = FlagContext::forUser(userId: 'user-42') ->withForcedFlag(flag: 'new-checkout', enabled: true); $featureFlags->isEnabled(flag: 'new-checkout', context: $context);
A forced value never re-enables a flag that has its kill switch active — the kill switch wins.
Strict mode
Unknown flags return false by default. Enable strict mode to throw instead:
$featureFlags = new FeatureFlags( provider: $provider, strictMode: true, );
Evaluation result
Get detailed information about why a flag is enabled or disabled:
$result = $featureFlags->evaluate( flag: 'new-checkout', context: FlagContext::forUser(userId: $userId), ); $result->isEnabled(); // bool $result->isKillSwitchActive(); // bool $result->isRolloutExcluded(); // bool $result->isEnvironmentExcluded();// bool
Kill switch
Set killSwitch: true in config to immediately disable a flag, overriding all
targeting, rollout and forced-value rules.
Percentage rollout
Deterministic assignment using sha256(salt . ':' . subjectId):
- Same
salt+subjectIdalways produces the same result. - Changing
saltresets assignment (intentional re-randomization). - Changing weights shifts boundaries; some subjects may change variant.
Public API
| Class | Description |
|---|---|
FeatureFlags |
Facade service: isEnabled(), isDisabled(), evaluate(), has() |
Flag |
Immutable flag value object |
FlagConfig |
Config DTO for programmatic flag definitions |
FlagContext |
Evaluation context (userId, tenantId, environment) |
FlagProvider |
Interface for flag sources |
ConfigFlagProvider |
Provider from PHP config arrays |
FlagRegistry |
Named flag lookup |
FlagEvaluator |
Core evaluation logic |
PercentageRollout |
Deterministic percentage assignment |
EvaluationResult |
Detailed evaluation outcome |
Storage backends
The core wires only the FeatureFlags facade. The FlagProvider implementation
is supplied by exactly one provider — a storage backend or, for config-array
flags, the application itself. This keeps backends drop-in: install one and it is
wired automatically, with no Duplicate key config conflict.
| Package | Description |
|---|---|
rasuvaeff/yii3-feature-flags-db |
Database (yiisoft/db) with PSR-16 caching and migration |
rasuvaeff/yii3-feature-flags-redis |
Redis HASH via Predis, read-only |
Install a backend and you are done — it binds FlagProvider for you:
composer require rasuvaeff/yii3-feature-flags-db
Config-only setup
Without a storage backend, define flags in params.php and bind FlagProvider
to ConfigFlagProvider once in your application config (config/common/di/*.php):
use Rasuvaeff\Yii3FeatureFlags\ConfigFlagProvider; use Rasuvaeff\Yii3FeatureFlags\FlagProvider; /** @var array $params */ return [ FlagProvider::class => [ 'class' => ConfigFlagProvider::class, '__construct()' => [ 'flags' => $params['rasuvaeff/yii3-feature-flags']['flags'], ], ], ];
Bind FlagProvider from a single source — installing two backends (or a backend
plus a manual config binding) reintroduces the Duplicate key conflict.
Security
- Flag names validated by regex (
/^[a-z][a-z0-9._-]*$/). - Rollout percentage validated (0..100 range).
- No user data is logged or stored by the core package.
- Kill switch provides emergency shutoff capability.
Examples
See examples/ for runnable scripts. Examples are expected to execute without fatal errors and stay aligned with the documented public API.
Development
make install # composer install make build # full gate: validate + cs + psalm + test make cs-fix # fix code style make psalm # static analysis make test # run tests make test-coverage # run coverage make mutation # mutation testing make release-check # build + rector + bc-check + mutation
make test-coverage and make mutation bootstrap pcov inside the
composer:2 container because the base image has no coverage driver.
License
BSD-3-Clause. See LICENSE.md.
统计信息
- 总下载量: 152
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 2
- 推荐数: 0
其他信息
- 授权协议: BSD-3-Clause
- 更新时间: 2026-06-05