antfroger/progressive
Composer 安装命令:
composer require antfroger/progressive
包简介
The library to progressively, quickly and simply enables new features
README 文档
README
Progressive is a feature flag library (also called toggle, switch, ...).
Thanks to Progressive, you can progressively, quickly and simply enable new features.
(and just as quickly deactivate them in case of an emergency)
Installation
$ composer require antfroger/progressive
Usage
// From a file $config = \Symfony\Component\Yaml\Yaml::parseFile('/your-own-config-file.yaml'); // Content of /your-own-config-file.yaml // features: // dark-theme: true // call-center: false // homepage-v2: // enabled: true // Or from a PHP array $config = [ 'features' => [ 'dark-theme' => true, 'call-center' => false, 'homepage-v2' => [ 'enabled' => true ], ] ]; $progressive = new Progressive($config); $progressive->isEnabled('dark-theme'); // true $progressive->isEnabled('call-center'); // false $progressive->isEnabled('homepage-v2'); // true
Rules
Built-in
enabled: true|false
enabled enables (or disables) the feature for everyone, everywhere, all the time.
The value is meant to be a boolean, true|false.
// Short $config = [ 'features' => [ 'dark-theme' => true ] ]; // Verbose $config = [ 'features' => [ 'dark-theme' => [ 'enabled' => true ] ] ];
Custom
You will probably need many more rules that will fit your needs and stack.
Let's say you want to redesign your homepage and progressively displaying it to test if everything goes right.
You start by enabling it in dev, then preprod, then prod but only for developers, then admins, then 1% of the users...
How would you be able to achieve that?
With custom rules!
$config = [ 'features' => [ 'homepage-v123' => [ 'env' => ['DEV', 'PREPROD'] ] ] ]; $progressive = new Progressive($config); $progressive->addCustomRule('env', function (Context $context, array $envs) { return in_array(getenv('ENV'), $envs); }); $progressive->isEnabled('homepage-v123'); // Returns true if ENV is DEV or PREPROD, otherwise returns false
(this lambda can be improved thanks to the Context object - more about it here)
Strategies
Rules are great but sometimes one rule is not enough to decide if a feature must be enabled.
You may want to enable a feature in PROD only for admins but to everyone in DEV, TEST and PREPROD.
Or you may want to enable a feature to the admins AND a given percentage of users.
That's where strategies come into play!
(Strategies are simply another name for nested rules.
And as for rules, you can create your own strategies!)
Progressive comes with two built-in strategies:
unanimous: []
unanimous enables the feature if all the conditions are met.
The value is meant to be an array of rules.
$config = [ 'features' => [ 'translate-interface' => [ 'unanimous' => [ 'env' => ['DEV', 'PREPROD'], 'roles' => ['ROLE_ADMIN', 'ROLE_TRANSLATOR'] ] ] ] ];
In this example, the interface to translate the app will only be displayed in DEV and PREPROD environments to users having ROLE_ADMIN or ROLE_TRANSLATOR as roles.
This strategy can be defined as an AND.
partial: []
partial enables the feature if only one of the conditions is met.
Rules are evaluated one by one. The feature is enabled as soon as one rule is true.
The value is meant to be an array of rules.
$config = [ 'features' => [ 'translate-interface' => [ 'partial' => [ 'env' => ['DEV', 'PREPROD'], 'roles' => ['ROLE_ADMIN', 'ROLE_TRANSLATOR'] ] ] ] ];
In this example, the interface to translate the app will be displayed:
- in
DEVandPREPRODenvironments (for all users) - for users having a role
ROLE_ADMINorROLE_TRANSLATOR, regardless of the environment.
This strategy can be defined as an OR.
Context object
Progressive doesn't know anything of your application logic code (and doesn't want to know).
But you may want to use your logic inside custom rules.
In that case, the context object is your friend!
It's nothing more that an user-defined databag.
You can use it to improve our previous custom rule:
$context = new Context([ 'env' => getenv('ENV') ?: 'PROD' ]); $config = [ 'features' => [ 'homepage-v123' => [ 'env' => ['DEV', 'PREPROD'] ] ] ]; $progressive = new Progressive($config, $context); $progressive->addCustomRule('env', function (Context $context, array $envs) { return in_array($context->get('env'), $envs); });
Another common example is to store the current user in the context:
$context = new Context(['user' => $user]); $config = [ 'features' => [ 'homepage-v123' => [ 'roles' => ['ROLE_ADMIN'] ] ] ]; $progressive = new Progressive($config, $context); $progressive->addCustomRule('roles', function (Context $context, array $roles) { $userRoles = $context->get('user')->getRoles(); foreach ($roles as $role) { if (in_array($role, $userRoles) { return true; } } return false; });
Requesting a non-existing flag
Whenever you request an non-existing flag, isEnabled will return false.
The flag is considered disabled.
$config = [ 'features' => [] ]; $progressive = new Progressive($config); $progressive->isEnabled('dark-theme'); // false
Separate feature releases from code deploy
As Progressive takes an array of config, it makes it possible to decorrelate the release calendar from the code deployment.
In this example, we use the Symfony Yaml component to read the config from a YAML file.
use Symfony\Component\Yaml\Yaml; $config = Yaml::parseFile('/your-own-config-file.yaml'); // Content of /your-own-config-file.yaml // features: // new-feature: false $progressive = new Progressive($config); $progressive->isEnabled('new-feature'); // false
Imagine that you are able to deploy the config files independently from your code base, you could release a new feature without having to deploy all your code base, by redeploying only /your-own-config-file.yaml.
// Content of /your-own-config-file.yaml // features: // new-feature: true $progressive->isEnabled('new-feature'); // true
You may also want to store the configuration in a database and pass it as an array to Progressive.
Progressive in your projects
- Progressive is also available as a Symfony bundle
Inspired by Laurent Callarec's javascript feature-flag library Banderole
antfroger/progressive 适用场景与选型建议
antfroger/progressive 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3.14k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2020 年 12 月 18 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 antfroger/progressive 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 antfroger/progressive 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 3.14k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 10
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-12-18