PHPackages                             fgremez/flagbag - 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. fgremez/flagbag

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

fgremez/flagbag
===============

Manipulate bitmask integers as typed PHP objects

v1.0.1(3mo ago)03MITPHPPHP &gt;=8.1

Since Mar 11Pushed 3mo agoCompare

[ Source](https://github.com/fgremez/flagbag)[ Packagist](https://packagist.org/packages/fgremez/flagbag)[ RSS](/packages/fgremez-flagbag/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (2)Versions (3)Used By (0)

FlagBag
=======

[](#flagbag)

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

No dependencies. No framework required.

Installation
------------

[](#installation)

```
composer require fgremez/flagbag
```

**Requirements:** PHP &gt;= 8.1

Concept
-------

[](#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
-----

[](#usage)

### 1. Define a FlagBag

[](#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

[](#2-hydrate-from-an-integer)

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

### 3. Read a flag

[](#3-read-a-flag)

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

### 4. Write a flag

[](#4-write-a-flag)

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

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

### 5. Chaining

[](#5-chaining)

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

### 6. Integrate with any class

[](#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
----------

[](#exceptions)

ExceptionThrown 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]` valueInteger limits
--------------

[](#integer-limits)

StorageSizeMax flagsMax valueTINYINT8 bits7127SMALLINT16 bits1532 767INT32 bits312 147 483 647BIGINT64 bits62~4.6×10¹⁸License
-------

[](#license)

MIT — see [LICENSE](LICENSE)

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance80

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

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

Total

2

Last Release

104d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8dc9b84ec56e0549f56da2fd47ba675112947fa874b7fc4dc5d81529bd844816?d=identicon)[fgremez](/maintainers/fgremez)

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/fgremez-flagbag/health.svg)

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

###  Alternatives

[kornrunner/ethereum-address

Pure PHP Ethereum Address Generator / Validator

42118.1k9](/packages/kornrunner-ethereum-address)[jawira/plantuml

Provides PlantUML executable and plantuml.jar

21387.4k8](/packages/jawira-plantuml)[attestto/solana-php-sdk

Solana PHP SDK for interacting with the Solana blockchain

5537.3k](/packages/attestto-solana-php-sdk)[interaction-design-foundation/laravel-geoip

Support for multiple Geographical Location services.

19253.0k3](/packages/interaction-design-foundation-laravel-geoip)

PHPackages © 2026

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