fgremez/flagbag

Manipulate bitmask integers as typed PHP objects

Maintainers

Package info

github.com/fgremez/flagbag

pkg:composer/fgremez/flagbag

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.1 2026-03-11 20:21 UTC

This package is auto-updated.

Last update: 2026-03-11 20:23:09 UTC


README

A lightweight PHP library to manipulate bitmask integers as typed objects.

No dependencies. No framework required.

Installation

composer require fgremez/flagbag

Requirements: PHP >= 8.1

Concept

Each flag is a power of 2. The stored value is the sum of active flags.

canRead   = 1   → 00000001
canWrite  = 2   → 00000010
canDelete = 4   → 00000100
isAdmin   = 8   → 00001000

canRead + canDelete + isAdmin = 13

This allows efficient storage (a single integer column) and native SQL filtering:

SELECT * FROM user WHERE permissions & 2 = 2  -- canWrite is active
SELECT * FROM user WHERE permissions & 9 = 9  -- canRead AND isAdmin are active

Usage

1. Define a FlagBag

Extend FlagBag and declare your boolean properties with #[FlagBit]. Each value must be a power of 2.

use FlagBag\FlagBag;
use FlagBag\Attribute\FlagBit;

class UserPermissions extends FlagBag
{
    #[FlagBit(1)]
    private bool $canRead = false;

    #[FlagBit(2)]
    private bool $canWrite = false;

    #[FlagBit(4)]
    private bool $canDelete = false;

    #[FlagBit(8)]
    private bool $isAdmin = false;
}

2. Hydrate from an integer

$permissions = UserPermissions::fromInt(9); // canRead (1) + isAdmin (8)

3. Read a flag

$permissions->get('canRead');  // true
$permissions->get('canWrite'); // false

4. Write a flag

$permissions->set('canWrite', true);

$permissions->toInt(); // 11 (1 + 2 + 8)

5. Chaining

$value = UserPermissions::fromInt(0)
    ->set('canRead', true)
    ->set('isAdmin', true)
    ->toInt(); // 9

6. Integrate with any class

The column stays a plain integer — no custom ORM type needed.

class User
{
    private int $permissions = 0;

    public function getPermissions(): UserPermissions
    {
        return UserPermissions::fromInt($this->permissions);
    }

    public function setPermissions(UserPermissions $bag): void
    {
        $this->permissions = $bag->toInt();
    }
}
$user->setPermissions(
    $user->getPermissions()->set('canWrite', true)
);

Exceptions

Exception Thrown when
UnknownFlagException get()/set() called with a flag name that does not exist
InvalidFlagBitValueException A #[FlagBit] value is not a power of 2
FlagBitCollisionException Two properties share the same #[FlagBit] value

Integer limits

Storage Size Max flags Max value
TINYINT 8 bits 7 127
SMALLINT 16 bits 15 32 767
INT 32 bits 31 2 147 483 647
BIGINT 64 bits 62 ~4.6×10¹⁸

License

MIT — see LICENSE