PHPackages                             reinder83/binary-flags - 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. [Database &amp; ORM](/categories/database)
4. /
5. reinder83/binary-flags

ActiveLibrary[Database &amp; ORM](/categories/database)

reinder83/binary-flags
======================

Useful class for binary operations

v3.0.0(1w ago)1375.9k↑16.5%3MITPHPPHP ^8.2CI passing

Since Oct 24Pushed 2w ago3 watchersCompare

[ Source](https://github.com/reinder83/binary-flags)[ Packagist](https://packagist.org/packages/reinder83/binary-flags)[ Docs](https://github.com/reinder83/binary-flags)[ GitHub Sponsors](https://github.com/reinder83)[ RSS](/packages/reinder83-binary-flags/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (10)Versions (19)Used By (0)

[![test](https://github.com/reinder83/binary-flags/actions/workflows/test.yml/badge.svg)](https://github.com/reinder83/binary-flags/actions/workflows/test.yml)

BinaryFlags
===========

[](#binaryflags)

With this class you can easily add flags to your projects.

The number of usable flags is limited by PHP's signed integer size: 31 flags on a 32-bit system or 63 flags on a 64-bit system. If you store 64-bit integer masks in a database, use a type that can hold signed 64-bit values, such as `BIGINT` in MySQL or the equivalent in your datastore.

This package also comes with a trait which you can use to implement binary flags directly in your own class.

### Trait naming

[](#trait-naming)

For new code, prefer `Reinder83\BinaryFlags\Traits\InteractsWithNumericFlags`. `Reinder83\BinaryFlags\Traits\BinaryFlags` remains available for backward compatibility. For enum-based usage, use `Reinder83\BinaryFlags\BinaryEnumFlags` (which uses `Traits\InteractsWithEnumFlags`).

Installing
----------

[](#installing)

To install this package simply run the following command in the root of your project.

```
composer require reinder83/binary-flags

```

v3.0.0 Breaking Changes
-----------------------

[](#v300-breaking-changes)

As of `v3.0.0`, masks and flags are `int`-only.

- Passing `float` values to numeric mask/flag methods from `strict_types=1` call sites now throws a `TypeError`.
- For non-strict callers, PHP scalar coercion can still convert `float` to `int` before the method is entered, so validate or cast external values before calling the API.
- `Bits::BIT_64` has been removed.

### BIT\_64 Notice

[](#bit_64-notice)

`Bits::BIT_64` was removed because PHP numbers for bitwise flags are signed. The 64th bit is the sign bit, so it cannot be used reliably as a normal flag.

Use `BIT_1` through `BIT_63` for portable numeric flags.

If you still receive mask values from loose legacy sources, cast them before using the API:

```
$flags->setMask((int) $maskFromLegacySource);
$flags->addFlag((int) $incomingFlag);
```

See [UPGRADE-v3.md](UPGRADE-v3.md) for migration details.

Methods
-------

[](#methods)

The following methods can be used:

##### setMask(int $mask)

[](#setmaskint-mask)

Overwrite the current mask. This can be passed as first argument in the constructor.

##### getMask(): int

[](#getmask-int)

Retrieve the current mask.

When using `BinaryEnumFlags`, `getMask()` returns a `Mask` object instead. Use `getMaskValue(): int` on enum-based flags if you need the numeric mask.

##### getMaskValue(): int

[](#getmaskvalue-int)

*Since: v2.1.0*
Returns the numeric mask value for storage/interoperability. This method is only available on enum-backed flags (`BinaryEnumFlags`).

##### setOnModifyCallback(callable $onModify)

[](#setonmodifycallbackcallable-onmodify)

Set a callback function which is called when the mask changes. This can be passed as second argument in the constructor.

##### getFlagNames(\[int $mask, \[bool $asArray=false\]\])

[](#getflagnamesint-mask-bool-asarrayfalse)

Give the name(s) for the given `$mask` or the current mask when omitted. When `$asArray` is `true` the method will return an array with the names, otherwise a comma separated string will be returned (default).

##### addFlag(int $flag)

[](#addflagint-flag)

Adds one or multiple flags to the current mask.

##### removeFlag(int $flag)

[](#removeflagint-flag)

Removes one or multiple flags from the current mask.

##### checkFlag(int $flag, \[bool $checkAll=true\]): bool

[](#checkflagint-flag-bool-checkalltrue-bool)

Check if given flag(s) are set in the current mask. By default, it will check all bits in the given flag. When you want to match any of the given flags set `$checkAll` to `false`.

##### checkAnyFlag(int $mask): bool

[](#checkanyflagint-mask-bool)

*Since: v1.0.1*
For your convenience I've added an alias to checkFlag with `$checkAll` set to `false`.

##### count(): int

[](#count-int)

*Since: v1.2.0*
Returns the number of flags that have been set.

##### jsonSerialize(): mixed

[](#jsonserialize-mixed)

*Since: v1.2.0*
Return a value that can be encoded by json\_encode() in the form of `["mask" => 7]`. You should not have to call this method directly, instead you can pass the BinaryFlags object to json\_encode which will convert it to '{"mask": 7}'.

Static Methods
--------------

[](#static-methods)

The following static methods can be used:

##### getAllFlags(): array

[](#getallflags-array)

*Since: v1.1.0*
Return all the flags with their names as an array, using their flag mask as key. This method can also be overloaded to return custom names for the flags, which will be used by the `getFlagNames` method.

##### getAllFlagsMask(): int

[](#getallflagsmask-int)

*Since: v1.1.0*
Return mask of all the flags together

Iteration
---------

[](#iteration)

*Since: v1.2.0*
You can treat a BinaryFlags object as an iterable, where each iteration will return the next bit value that has been set including its description (or the name of the constant representing the bit value).

Example usage
-------------

[](#example-usage)

Below is some example usage code

##### Create classes

[](#create-classes)

```
// example classes which the following examples will refer to
use Reinder83\BinaryFlags\BinaryFlags;
use Reinder83\BinaryFlags\Bits;

class ExampleFlags extends BinaryFlags
{
    const FOO = Bits::BIT_1;
    const BAR = Bits::BIT_2;
    const BAZ = Bits::BIT_3;
}
```

##### Simple usage

[](#simple-usage)

```
$exampleFlags = new ExampleFlags();

// add BAR flag
$exampleFlags->addFlag(ExampleFlags::BAR);

var_export($exampleFlags->checkFlag(ExampleFlags::FOO));
// false
var_export($exampleFlags->checkFlag(ExampleFlags::BAR));
// true

// remove BAR flag
$exampleFlags->removeFlag(ExampleFlags::BAR);

var_export($exampleFlags->checkFlag(ExampleFlags::BAR));
// false
```

##### Usage with multiple flags

[](#usage-with-multiple-flags)

```
$exampleFlags = new ExampleFlags();

// add FOO and BAR
$exampleFlags->addFlag(ExampleFlags::FOO | ExampleFlags::BAR);

var_export($exampleFlags->checkFlag(ExampleFlags::FOO));
// true

var_export($exampleFlags->checkFlag(ExampleFlags::FOO | ExampleFlags::BAZ));
// false because BAZ is not set

var_export($exampleFlags->checkFlag(ExampleFlags::FOO | ExampleFlags::BAR));
// true because both flags are set

var_export($exampleFlags->checkFlag(ExampleFlags::FOO | ExampleFlags::BAZ, false));
// true because one of the flags is set (FOO)

// alias of the above method
var_export($exampleFlags->checkAnyFlag(ExampleFlags::FOO | ExampleFlags::BAZ));
// true
```

##### Enum usage (optional)

[](#enum-usage-optional)

```
use Reinder83\BinaryFlags\BinaryEnumFlags;
use Reinder83\BinaryFlags\Mask;

enum Permission: int
{
    case CanView = Bits::BIT_1;
    case CanBook = Bits::BIT_2;
    case CanCancel = Bits::BIT_3;
}

class PermissionFlags extends BinaryEnumFlags
{
    protected static function getFlagEnumClass(): string
    {
        return Permission::class;
    }
}

$flags = new PermissionFlags(Permission::CanView);
$flags->addFlag(Permission::CanBook);
$flags->addFlag(Mask::forEnum(Permission::class, Permission::CanCancel));

var_export($flags->checkFlag(Permission::CanBook));
// true

var_export($flags->getFlagNames());
// 'Can View, Can Book, Can Cancel'
```

##### Migrating from numeric flags to enum flags

[](#migrating-from-numeric-flags-to-enum-flags)

```
// Before (numeric PermissionFlags)
use Reinder83\BinaryFlags\BinaryFlags;

class PermissionFlags extends BinaryFlags
{
    public const CAN_VIEW = Bits::BIT_1;
    public const CAN_BOOK = Bits::BIT_2;
}

$flags = new PermissionFlags($storedMask);
$flags->addFlag(PermissionFlags::CAN_VIEW | PermissionFlags::CAN_BOOK);
$storedMask = $flags->getMask(); // int

// After (enum PermissionFlags)
use Reinder83\BinaryFlags\BinaryEnumFlags;
use Reinder83\BinaryFlags\Mask;

enum Permission: int
{
    case CanView = Bits::BIT_1;
    case CanBook = Bits::BIT_2;
}

class PermissionFlags extends BinaryEnumFlags
{
    protected static function getFlagEnumClass(): string
    {
        return Permission::class;
    }
}

$flags = new PermissionFlags(Mask::fromInt($storedMask, Permission::class));
$flags->addFlag(Permission::CanView);
$flags->addFlag(Permission::CanBook);

// Save as integer for storage/interop
$storedMask = $flags->getMaskValue();
```

##### Flag names example

[](#flag-names-example)

*By default, the flag names are based on the constant names*

```
$exampleFlags = new ExampleFlags();

$exampleFlags->addFlag(ExampleFlags::FOO | ExampleFlags::BAR | ExampleFlags::BAZ);
var_export($exampleFlags->getFlagNames());
// 'Foo, Bar, Baz'

// null will force current mask
var_export($exampleFlags->getFlagNames(null, true));
/*
array (
  0 => 'Foo',
  1 => 'Bar',
  2 => 'Baz',
)
*/

// get flag names of given mask
var_export($exampleFlags->getFlagNames(ExampleFlags::FOO | ExampleFlags::BAR));
// 'Foo, Bar'
```

##### Custom flag names example

[](#custom-flag-names-example)

If you want custom flag names that are not equal to the constant names, you can override these with `getAllFlags()`

```
class ExampleFlagsWithNames extends BinaryFlags
{
    const FOO = Bits::BIT_1;
    const BAR = Bits::BIT_2;
    const BAZ = Bits::BIT_3;

    public static function getAllFlags()
    {
        return [
            static::FOO => 'My foo description',
            static::BAR => 'My bar description',
            static::BAZ => 'My baz description',
        ];
    }
}

$exampleFlags = new ExampleFlagsWithNames();

$exampleFlags->addFlag(ExampleFlags::FOO | ExampleFlags::BAR | ExampleFlags::BAZ);

// null will force current mask
var_export($exampleFlags->getFlagNames(null, true));
/*
array (
  0 => 'My foo description',
  1 => 'My bar description',
  2 => 'My baz description',
)
*/
```

##### Example usage with Eloquent models

[](#example-usage-with-eloquent-models)

```
use Illuminate\Database\Eloquent\Model;

class Test extends Model
{
    private $flagsObject;

    /**
     * Retrieve flags
     * @return ExampleFlags
     */
    public function getFlagsAttribute()
    {
        if ($this->flagsObject === null) {
            $this->flagsObject = new ExampleFlags(
                $this->attributes['flags'], // set current flags mask
                function (ExampleFlags $flags) { // set callback function
                    // update the flags in this model
                    $this->setAttribute('flags', $flags->getMask());
                }
            );
        }
        return $this->flagsObject;
    }
}

// retrieve object from DB
$test = Test::find(1);

// do binary operations on the flags class as described earlier
$test->flags->checkFlag(ExampleFlags::FOO);
```

Support
-------

[](#support)

For bugs or feature requests feel free to contact me or submit an issue or pull request. Or you can support me by buying me a coffee:

[![Buy me a coffee](https://camo.githubusercontent.com/9901f23294a5c837ea6ce024f43ea436c620666bbd88b42d9bdb431366c0ec4d/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f67756964656c696e65732f646f776e6c6f61642d6173736574732d736d2d322e737667)](https://www.buymeacoffee.com/reinder83)

###  Health Score

63

—

FairBetter than 99% of packages

Maintenance97

Actively maintained with recent releases

Popularity37

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 83.3% 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 ~252 days

Recently: every ~629 days

Total

15

Last Release

11d ago

Major Versions

v0.5 → v1.02017-06-12

v1.2.2 → v2.02023-06-06

v2.1.0 → v3.0.02026-06-23

PHP version history (3 changes)v2.0PHP ^8.0

v2.0.1PHP ^8.1

v2.1.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/4f607152c98d238fa8b4297ca99db0bb81b17dec2f468d822fc87c29198525dc?d=identicon)[reinder83](/maintainers/reinder83)

---

Top Contributors

[![reinder83](https://avatars.githubusercontent.com/u/3398061?v=4)](https://github.com/reinder83 "reinder83 (20 commits)")[![remenic](https://avatars.githubusercontent.com/u/771712?v=4)](https://github.com/remenic "remenic (3 commits)")[![ovgray](https://avatars.githubusercontent.com/u/2389376?v=4)](https://github.com/ovgray "ovgray (1 commits)")

---

Tags

binarybitwisebitwise-operatorsflagsphpphp-librarymodeleloquentclasstraitflagsbinaryoperationsbitwisebitwiser

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/reinder83-binary-flags/health.svg)

```
[![Health](https://phpackages.com/badges/reinder83-binary-flags/health.svg)](https://phpackages.com/packages/reinder83-binary-flags)
```

###  Alternatives

[esensi/model

The base model traits of Esensi

20167.0k1](/packages/esensi-model)[greabock/tentacles

Da epic tentacles for Eloquent

3634.5k](/packages/greabock-tentacles)

PHPackages © 2026

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