PHPackages                             pablojoan/feature - 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. pablojoan/feature

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

pablojoan/feature
=================

Feature flagging API used for operational rampups and A/B testing

8.0.2(2y ago)2832UnlicensePHPPHP &gt;=8.3CI passing

Since Sep 27Pushed 2y ago1 watchersCompare

[ Source](https://github.com/PabloJoan/feature)[ Packagist](https://packagist.org/packages/pablojoan/feature)[ RSS](/packages/pablojoan-feature/feed)WikiDiscussions master Synced yesterday

READMEChangelog (10)Dependencies (1)Versions (20)Used By (0)

[![GitHub license](https://camo.githubusercontent.com/1ba3a2b2d377b15c1645f50fd58b383dcf8b34e04d03566d60d9a9df67696eb5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f5061626c6f4a6f616e2f666561747572652e737667)](https://github.com/PabloJoan/feature/blob/master/LICENSE)

Requires PHP 8.3 and above.

Installation
============

[](#installation)

```
composer require pablojoan/feature
```

Basic Usage
===========

[](#basic-usage)

```
use PabloJoan\Feature\Features; // Import the namespace.

$featureConfigs = [
    'foo' => [
        'variants' => [
            'variant1' => 100, //100% chance this variable will be chosen
            'variant2' => 0    //0% chance this variable will be chosen
        ]
    ],
    'bar' => [
        'variants' => [
            'variant1' => 25, //25% chance this variable will be chosen
            'variant2' => 25, //25% chance this variable will be chosen
            'variant3' => 50 //50% chance this variable will be chosen
        ],
        'bucketing' => 'id' //same id string will always return the same variant
    ]
];

$features = new Features($featureConfigs);

$features->isEnabled(featureName: 'foo');         // true
$features->getEnabledVariant(featureName: 'foo'); // 'variant1'
```

For a quick summary and common use cases, please read the rest of this README.

Feature API
===========

[](#feature-api)

Feature flagging API used for operational rampups and A/B testing.

The Feature API is how we selectively enable and disable features at a very fine grain as well as enabling features for a percentage of users for operational ramp-ups and for A/B tests. A feature can be completely enabled, completely disabled, or something in between and can comprise a number of related variants.

The two main API entry points are:

```
    $features->isEnabled(featureName: 'my_feature')
```

which returns true when `my_feature` is enabled and, for multi-variant features:

```
    $features->getEnabledVariant(featureName: 'my_feature')
```

which returns the name of the particular variant which should be used.

The single argument to each of these methods is the name of the feature to test.

A typical use of `$features->isEnabled` for a single-variant feature would look something like this:

```
    if ($features->isEnabled(featureName: 'my_feature')) {
        // do stuff
    }
```

For a multi-variant feature, we can determine the appropriate code to run for each variant with something like this:

```
    switch ($features->getEnabledVariant(featureName: 'my_feature')) {
      case 'foo':
          // do stuff appropriate for the 'foo' variant
          break;
      case 'bar':
          // do stuff appropriate for the 'bar' variant
          break;
    }
```

If a feature is bucketed by id, then we pass the id string to `$features->isEnabled` and `$features->getEnabledVariant` as a second parameter

```
    $isMyFeatureEnabled = $features->isEnabled(
        featureName: 'my_feature',
        id: 'unique_id_string'
    );

    $variant = $features->getEnabledVariant(
        featureName: 'my_feature',
        id: 'unique_id_string'
    );
```

Configuration cookbook
----------------------

[](#configuration-cookbook)

There are a number of common configurations so before I explain the complete syntax of the feature configuration stanzas, here are some of the more common cases along with the most concise way to write the configuration.

### A totally enabled feature:

[](#a-totally-enabled-feature)

```
    $server_config['foo'] = ['variants' => ['enabled' => 100]];
```

### A totally disabled feature:

[](#a-totally-disabled-feature)

```
    $server_config['foo'] = ['variants' => ['enabled' => 0]];
```

### Feature with winning variant turned on for everyone

[](#feature-with-winning-variant-turned-on-for-everyone)

```
    $server_config['foo'] = ['variants' => ['blue_background' => 100]];
```

### Single-variant feature ramped up to 1% of users.

[](#single-variant-feature-ramped-up-to-1-of-users)

```
    $server_config['foo'] = ['variants' => ['enabled' => 1]];
```

### Multi-variant feature ramped up to 1% of users for each variant.

[](#multi-variant-feature-ramped-up-to-1-of-users-for-each-variant)

```
    $server_config['foo'] = [
       'variants' => [
           'blue_background'   => 1,
           'orange_background' => 1,
           'pink_background'   => 1,
       ],
    ];
```

### Enabled for 10% of regular users.

[](#enabled-for-10-of-regular-users)

```
    $server_config['foo'] = [
       'variants' => ['enabled' => 10]
    ];
```

### Feature ramped up to 1% of requests, bucketing at random rather than by id

[](#feature-ramped-up-to-1-of-requests-bucketing-at-random-rather-than-by-id)

```
    $server_config['foo'] = [
       'variants' => ['enabled' => 1],
       'bucketing' => 'random'
    ];
```

### Feature ramped up to 40% of requests, bucketing by id rather than at random

[](#feature-ramped-up-to-40-of-requests-bucketing-by-id-rather-than-at-random)

```
    $server_config['foo'] = [
       'variants' => ['enabled' => 40],
       'bucketing' => 'id'
    ];
```

### Single-variant feature in 50/50 A/B test

[](#single-variant-feature-in-5050-ab-test)

```
    $server_config['foo'] = ['variants' => ['enabled' => 50]];
```

### Multi-variant feature in A/B test with 20% of users seeing each variant (and 40% left in control group).

[](#multi-variant-feature-in-ab-test-with-20-of-users-seeing-each-variant-and-40-left-in-control-group)

```
    $server_config['foo'] = [
       'variants' => [
           'blue_background'   => 20,
           'orange_background' => 20,
           'pink_background'   => 20
       ],
    ];
```

Configuration details
---------------------

[](#configuration-details)

Each feature’s config stanza controls when the feature is enabled and what variant should be used when it is.

The value of a feature config stanza is an array with a number of special keys, the most important of which is `'variants'`.

The value of the `'variants'` property an array whose keys are names of variants and whose values are the percentage of requests that should see each variant.

The remaining feature config property is `'bucketing'`. Bucketing specifies how users are bucketed when a feature is enabled for only a percentage of users. The default value, `'random'`, causes each request to be bucketed independently, meaning that the same user will be in different buckets on different requests. This is typically used for features that should have no user-visible effects but where we want to ramp up something like the switch from master to shards or a new version of JS code.

The bucketing value `'id'`, causes bucketing to be based on the given id.

Errors
------

[](#errors)

There are a few ways to misuse the Feature API or misconfigure a feature that may be detected. (Some of these are not currently detected but may be in the future.)

1. Setting the percentage value of a variant in `'variants'` to a value less than 0 or greater than 100.
2. Setting `'variants'` such that the sum of the variant percentages is greater than 100.
3. Setting `'variants'` to a non-array value.
4. Setting `'bucketing'` to any value that is not `'id'` or `'random'`.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity87

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 97% of commits — single point of failure

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 ~145 days

Recently: every ~225 days

Total

19

Last Release

944d ago

Major Versions

3.2.0 → 4.0.02018-10-28

4.0.2 → 5.0.02018-10-29

5.0.1 → 6.0.02021-05-27

6.0.3 → 7.0.02023-04-12

7.0.0 → 8.0.02023-11-28

PHP version history (6 changes)v1.0.0PHP &gt;=5.3.3

3.0.0PHP &gt;=7.0

4.0.0PHP &gt;=7.2

6.0.0PHP &gt;=8.0

7.0.0PHP &gt;=8.2

8.0.0PHP &gt;=8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/9193314?v=4)[Pablo Joán Iglesias](/maintainers/PabloJoan)[@PabloJoan](https://github.com/PabloJoan)

---

Top Contributors

[![PabloJoan](https://avatars.githubusercontent.com/u/9193314?v=4)](https://github.com/PabloJoan "PabloJoan (64 commits)")[![gigamonkey](https://avatars.githubusercontent.com/u/250053?v=4)](https://github.com/gigamonkey "gigamonkey (1 commits)")[![quiiver](https://avatars.githubusercontent.com/u/69411?v=4)](https://github.com/quiiver "quiiver (1 commits)")

---

Tags

a-b-testa-b-testingab-testab-testingab-testsfeature-flaggingfeature-flagsfeature-togglefeature-togglestogglefeaturefeature togglefeature flaggingtogglea b testingfeature-flagsfeature-togglesab testab-testingab testsa-b-test

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[flagception/flagception-bundle

Feature toggle bundle on steroids.

324.0M](/packages/flagception-flagception-bundle)[flagception/flagception

Feature toggle on steroids.

154.5M6](/packages/flagception-flagception)[ajgarlag/feature-flag-bundle

Provides a feature flag mechanism

1419.9k](/packages/ajgarlag-feature-flag-bundle)

PHPackages © 2026

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