🚩 A lightweight, customizable feature flags framework for PHP
You can customize:
- 🧠 How flags are evaluated, through Strategies.
- 💾 How flags are stored, through Storages.
- 📢 Who is notified about flag changes or removal, through Listeners.
PHP 7.4 or later. No external dependencies.
composer require phputil/flags
👉 You may also like to install some of the official extensions.
Official extensions:
phputil/flags-pdo
- a PDO-based storage.- ⏳ SOON -
phputil/flags-firebase
- a Firebase-based storage. phputil/flags-webhooks
a listener that works like a webhook, by notifying external APIs about flags' changes.
Third-party extensions:
- Create yours and open an Issue to be evaluated. It may appear here.
Basic flag checking:
require_once 'vendor/autoload.php';
use phputil\flags\FlagManager;
// By default, it uses a storage-based strategy with an in-memory storage
$flag = new FlagManager();
if ( $flag->isEnabled( 'my-cool-feature' ) ) {
echo 'Cool feature available!', PHP_EOL;
} else {
echo 'Not-so-cool feature here', PHP_EOL;
}
Customizing a certain verification:
// ...
use phputil\flags\FlagVerificationStrategy;
$flag = new FlagManager();
$myLuckBasedStrategy = new class implements FlagVerificationStrategy {
function isEnabled( string $flag ): bool {
return rand( 1, 100 ) >= 50; // 50% chance
}
};
if ( $flag->isEnabled( 'my-cool-feature', [ $myLuckBasedStrategy ] ) ) {
echo 'Cool feature available!', PHP_EOL;
} else {
echo 'Not-so-cool feature here', PHP_EOL;
}
Customizing all the verifications:
$flag = new FlagManager( null, [ $myLuckBasedStrategy ] );
if ( $flag->isEnabled( 'my-cool-feature' ) ) {
...
Setting a flag:
$flag->enable( 'my-cool-feature' );
$flag->disable( 'my-cool-feature' );
$flag->setEnable( 'my-cool-feature', true /* or false */ );
Removing a flag:
$flag->remove( 'my-cool-feature' );
Retrieving flag data:
$flagData = $flag->getStorage()->get( 'my-cool-feature' ); // null if not found
Adding a listener:
// ...
use phputil\flags\FlagListener;
use phputil\flags\FlagData;
$myListener = new class implements FlagListener {
public function notify( string $event, FlagData $flagData ): void {
if ( $event === 'change' ) {
echo 'Flag ', $flagData->key, ' is now ', $flagData->enabled ? 'enabled': 'disabled', PHP_EOL;
} else if ( $event === 'removal' ) {
echo 'Flag ', $flagData->key, ' was removed.', PHP_EOL;
}
}
};
$flag->addListener( $myListener ); // v0.5.0+
// or $flag->getListeners()->add( $myListener );
$flag->enable( 'my-cool-feature' ); // Notify the listener
Use a different flag storage by:
- Creating your own, extending
FlagStorage
; OR - Using an external storage extension.
How to configure it:
$storage = /* Create your storage here, e.g. new InMemoryStorage() */;
$flag = new FlagManager( $storage );
Storages available in the framework:
InMemoryStorage
, that store flags in memory.
Use a flag verification strategy by:
- Creating your own, extending
FlagVerificationStrategy
; OR - Using an external strategy extension.
How to configure it globally:
$strategies = [ /* pass your strategies here */ ];
$flag = new FlagManager( null, $strategies );
Strategies available in the framework:
StorageBasedVerificationStrategy
, that checks flags in a storage.EnvBasedVerificationStrategy
, that checks flags based on environment variables.
👉 A flag is considered enabled when all the strategies considered it enabled.
Define a listener by:
- Creating your own, extending
FlagListener
; OR - Using an external listener extension.
How to configure it:
$flag->addListener( $myListener ); // v0.5.0+
// or $flag->getListeners()->add( $myListener );
- Extensible library
- Official extensions:
- PDO-based storage
- Firebase-based storage
- Webhook-like listener
- REST API (external repository)
- Web-based control panel (external repository)