PHPackages                             pluggit/feature-balancer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. pluggit/feature-balancer

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

pluggit/feature-balancer
========================

This PHP library will allow to switch on/off or balance with a percentage between features

4.0.0(1y ago)032.0k↓50%2[1 PRs](https://github.com/CMProductions/feature-balancer/pulls)proprietaryPHPPHP ^8.0

Since Jun 13Pushed 3mo ago11 watchersCompare

[ Source](https://github.com/CMProductions/feature-balancer)[ Packagist](https://packagist.org/packages/pluggit/feature-balancer)[ RSS](/packages/pluggit-feature-balancer/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (4)Versions (12)Used By (0)

Feature Balancer
================

[](#feature-balancer)

This PHP library will allow to switch on/off or balance with a percentage between features

[![Build Status](https://camo.githubusercontent.com/e66b91d8e0e0f8f72d517b5ac7e2da847ea489345b0ce5e19611de93b7828bd1/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f434d50726f64756374696f6e732f666561747572652d62616c616e6365722f6261646765732f6275696c642e706e673f623d6d617374657226733d39666537663661303134346564336265613332343638336364646137316336333839613532333764)](https://scrutinizer-ci.com/g/CMProductions/feature-balancer/build-status/master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/1eb9574c7f02f6a28061fc964fc2e71304b0fafef8707ccb687c408d8ab0859c/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f434d50726f64756374696f6e732f666561747572652d62616c616e6365722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d617374657226733d32313435613433386466656363626238306362343562663037616439316332646235343937343034)](https://scrutinizer-ci.com/g/CMProductions/feature-balancer/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/ba0313e0723c2d029e2481250f4471261479f1eeb6b6f5d5b12e249a64df9dcb/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f434d50726f64756374696f6e732f666561747572652d62616c616e6365722f6261646765732f636f7665726167652e706e673f623d6d617374657226733d62336562643438303438363230313434333062326366623733663032333361373836343137333730)](https://scrutinizer-ci.com/g/CMProductions/feature-balancer/?branch=master)

TLDR;
-----

[](#tldr)

```
$balancer = (new BalancerBuilder())
    ->withLogger($logger, LogLevel::INFO)
    ->withMonitor($monitor, "my_app.feature_balanced")
    ->create([
        "home_banner" => [
            "do_not_show"   => 20,
            "amazing_offer" => 80,
        ],
        "after_update_email" => [
            "normal"        => 60,
            "special_offer" => 30,
            "do_not_send"   => 10,
        ]
    ]);

/**
 * Random Non-deterministic balance
 * - 20% change to get "do_not_show", 80% chance to get "amazing_offer"
 */
$path = $balancer->get("home_banner");

/**
 * Deterministic balance, given a configuration and a valid seed,
 * you'll always get the same result
 *
 * Valid seeds are non-empty strings and unsigned numbers
 */
$path = $balancer->get("after_update_email", 78549612);
$path = $balancer->get("after_update_email", -4.75);
$path = $balancer->get("after_update_email", "my_user@example.com");
```

Building the balancer
---------------------

[](#building-the-balancer)

The library comes with a builder to ease the creation of the balancer.

```
$balancer = (new BalancerBuilder())->create();
```

### Adding logging

[](#adding-logging)

If you install the `Psr\Log` library you can add logging to every decision made by the balancer. You can choose the log level that will be use to record log entries

```
// Add a logger when building the balancer
$balancer = (new BalancerBuilder())->->withLogger($logger, LogLevel::DEBUG)->create($config);

/**
 * This will log: "Feature path returned from the balancer: home_banner -> amazing_offer"
 * Plus some context information:
 * - feature
 * - path
 * - seed
 */
$balancer->get("home_banner", 9874562);
```

### Adding monitoring

[](#adding-monitoring)

If you install the `pluggit\monitoring` library you can add monitoring to every decision made by the balancer.

You **have** to choose the metric name to increment

```
// Add a monitor when building the balancer
$balancer = (new BalancerBuilder())->->withMonitor($monitor, "balanced_feature")->create($config);

/**
 * This will increment the metric: "balanced_feature", plus some tags
 * - feature
 * - path
 * - seed: true/false
 */
$balancer->get("home_banner", 9874562);
```

### Hiding exceptions

[](#hiding-exceptions)

If you don't wan't the feature balancer to throw exceptions, you can silence it with the `ExceptionSilencerDecorator`. It will log the errors and return "" as path for the requested feature

```
// Add a monitor when building the balancer
$balancer = (new BalancerBuilder())->->withoutExceptions()->create($config);

/**
 * Requesting an unknown feature will return an empty string -> ""
 */
$balancer->get("unknown_feature");
```

Adding features to the balancer
-------------------------------

[](#adding-features-to-the-balancer)

You can always add features to the balancer trough the method `add`. The rules are:

- Every feature must have a non-empty unique string identifier, adding the same feature will overwrite the previous configuration
- Every feature must have at least one possible path
- Every feature path must have a non-empty unique string identifier for the given feature
- Every path has assigned a percentage
- The **percentage** for every path has to be an unsigned integer **between 0 and 100**
- All the path percentages **must sum exactly 100**

Any violation of the following rules will make the balancer throw a `Cmp\FeatureBalancer\Exception\InvalidArgumentException` exception

*Valid examples*

```
$balancer->add("my_super_feature",  [
    "do_not_show"   => 20,
    "amazing_offer" => 80,
]);

$balancer->add("my_super_feature",  [
    "do_not_show"   => 0,
    "amazing_offer" => 100,
]);

$balancer->add("my_super_feature",  [
    "amazing_offer" => 100,
]);
```

*Invalid examples*

```
// No paths defined
$balancer->add("my_super_feature",  []);

// Percentages sum 90
$balancer->add("my_super_feature",  [
    "do_not_show"   => 90,
]);

// Percentages sum 140
$balancer->add("my_super_feature",  [
    "do_not_show"   => 60,
    "amazing_offer" => 80,
]);

// Percentages is not a valid unsigned integer
$balancer->add("my_super_feature",  [
    "do_not_show"   => "60",
    "amazing_offer" => 40,
]);
```

Getting a path
--------------

[](#getting-a-path)

Once you have configured a feature, you can request a path to the balancer

### Random Non-deterministic retrieval

[](#random-non-deterministic-retrieval)

If you don't pass a seed, the path will be choosen randomly taking into account the defined percentages

```
$path = $balancer->get("home_banner");
```

### Seed based deterministic retrieval

[](#seed-based-deterministic-retrieval)

If you pass a seed, the path will be decided using a simple yet infallible algorithm so that for *every given configuration and seed, it will always choose the same path*

**NOTE** This means that the path can change if either the configuration or the seed changes

You can pass both signed numbers (integers and doubles) or non-empty strings as seed

```
$path = $balancer->get("after_update_email", 78549612);
$path = $balancer->get("after_update_email", -23.54);
$path = $balancer->get("after_update_email", "my_user@example.com");
```

###  Health Score

48

—

FairBetter than 95% of packages

Maintenance58

Moderate activity, may be stable

Popularity28

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~365 days

Recently: every ~595 days

Total

8

Last Release

706d ago

Major Versions

1.4.0 → 2.0.02017-12-06

2.0.0 → 3.0.02019-05-30

3.0.0 → 4.0.02024-06-12

PHP version history (2 changes)1.0.0PHP &gt;=5.5

4.0.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/2595584d57cbf851b56dc1935d9e34d96045fc7b4ca3c64058caa3ed5e3fb504?d=identicon)[techCMP](/maintainers/techCMP)

---

Top Contributors

[![armcmp](https://avatars.githubusercontent.com/u/16293257?v=4)](https://github.com/armcmp "armcmp (2 commits)")[![jmartinmad](https://avatars.githubusercontent.com/u/17850794?v=4)](https://github.com/jmartinmad "jmartinmad (2 commits)")[![marcmascarell-mad](https://avatars.githubusercontent.com/u/61700472?v=4)](https://github.com/marcmascarell-mad "marcmascarell-mad (2 commits)")[![AaronBernabeu](https://avatars.githubusercontent.com/u/3294776?v=4)](https://github.com/AaronBernabeu "AaronBernabeu (1 commits)")

---

Tags

orphan

### Embed Badge

![Health badge](/badges/pluggit-feature-balancer/health.svg)

```
[![Health](https://phpackages.com/badges/pluggit-feature-balancer/health.svg)](https://phpackages.com/packages/pluggit-feature-balancer)
```

###  Alternatives

[ecotone/ecotone

Supporting you in building DDD, CQRS, Event Sourcing applications with ease.

558549.8k17](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k20](/packages/civicrm-civicrm-core)[j0k3r/php-readability

Automatic article extraction from HTML

186808.8k6](/packages/j0k3r-php-readability)[symfony/ai-platform

PHP library for interacting with AI platform provider.

51927.7k136](/packages/symfony-ai-platform)[symfony/ai-agent

PHP library for building agentic applications.

30536.7k44](/packages/symfony-ai-agent)[spomky-labs/pwa-bundle

Progressive Web App Manifest Generator Bundle for Symfony.

6144.4k1](/packages/spomky-labs-pwa-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
