PHPackages                             jungi/common - 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. jungi/common

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

jungi/common
============

A minimal library that defines primitive building blocks of PHP code.

v2.0.0(9mo ago)27208MITPHPPHP &gt;=8.4CI passing

Since Aug 20Pushed 7mo ago4 watchersCompare

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

READMEChangelog (9)Dependencies (1)Versions (11)Used By (0)

🌱 jungi/common
==============

[](#-jungicommon)

[![CI](https://github.com/jungi-php/common/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/jungi-php/common/actions/workflows/continuous-integration.yml)[![PHP](https://camo.githubusercontent.com/832e9351be98797529c3b5ae5716568e4a93e4c2f39998175f8744ba6cc40ff7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6a756e67692f636f6d6d6f6e)](https://camo.githubusercontent.com/832e9351be98797529c3b5ae5716568e4a93e4c2f39998175f8744ba6cc40ff7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6a756e67692f636f6d6d6f6e)

A minimal library that defines primitive building blocks of PHP code. It defines basic types and useful functions.

**Primitive types:**

- [`Equatable`](https://piku235.gitbook.io/jungi-common/equatable)
- [`Result`](https://piku235.gitbook.io/jungi-common/result)

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

[](#installation)

```
composer require jungi/common

```

Documentation
-------------

[](#documentation)

[GitBook](https://piku235.gitbook.io/jungi-common)

Quick insight
-------------

[](#quick-insight)

### Equatable

[](#equatable)

```
/** @implements Equatable */
class Phone implements Equatable
{
    public function __construct(private string $value) {}

    public function equals(self $other): bool
    {
        return $this->value === $other->value;
    }
}

assert(true === (new Phone('(321) 456-1234'))->equals(new Phone('(321) 456-1234')));
assert(false === (new Phone('(321) 456-1234'))->equals(new Phone('(454) 456-1234')));
```

### Result

[](#result)

```
final class Student
{
    public function __construct(
        public readonly StudentId $id,
        private(set) bool $active,
        private(set) string $name,
    ) {}
}

enum ClassEnrollmentError: string {
    case InactiveStudent = 'inactive_student';
    case StudentAlreadyEnrolled = 'student_already_enrolled';
    case NoSeatsAvailable = 'no_seats_available';
}

final class Class_
{
    public function __construct(
        public readonly ClassId $id,
        private(set) int $numberOfSeats,
        /** @var StudentId[] */
        private(set) array $students,
    ) {}

    /** @return Result */
    public function enroll(Student $student): Result
    {
        if (!$student->active) {
            return Result::error(ClassEnrollmentError::InactiveStudent);
        }
        if (in_iterable($student->id(), $this->students)) {
            return Result::error(ClassEnrollmentError::StudentAlreadyEnrolled);
        }
        if (count($this->students) >= $this->numberOfSeats) {
            return Result::error(ClassEnrollmentError::NoSeatsAvailable);
        }

        $this->students[] = $student->id();

        return Result::ok();
    }
}

class ClassController
{
    // PUT /classes/{classId}/students/{studentId}
    public function enrollToClass(string $classId, string $studentId)
    {
        // ... fetch the class and the student
        $r = $class->enroll($student);

        if ($r->isOk()) {
            return $this->created();
        }

        return match ($r->error) {
            ClassEnrollmentError::StudentAlreadyEnrolled => $this->noContent(),
            default => $this->conflict($error),
        };
    }
}
```

### Functions

[](#functions)

```
use function Jungi\Common\equals;
use function Jungi\Common\in_iterable;
use function Jungi\Common\iterable_unique;
use function Jungi\Common\array_equals;

/** @implements Equatable */
class ContactInformation implements Equatable
{
    public function __construct(
        private Phone $phone,
        private ?Phone $mobile = null
    ) {}

    public function equals(self $other): bool
    {
        return $this->phone->equals($other->phone)
            && equals($this->mobile, $other->mobile);
    }
}

// equals()

$a = new ContactInformation(new Phone('(321) 456-1234'), new Phone('(886) 456-6543'));
$b = new ContactInformation(new Phone('(321) 456-1234'), new Phone('(886) 456-6543'));
assert(true === equals($a, $b);

$a = new ContactInformation(new Phone('(321) 456-1234'));
$b = new ContactInformation(new Phone('(321) 456-1234'), new Phone('(886) 456-6543'));
assert(false === equals($a, $b);

// array_equals()

$a = [new Phone('(321) 456-1234'), new Phone('(465) 799-4566')];
$b = [new Phone('(321) 456-1234'), new Phone('(465) 799-4566')];
assert(true === array_equals($a, $b));

$a = [new Phone('(321) 456-1234'), new Phone('(465) 799-4566')];
$b = [new Phone('(321) 456-1234')];
assert(false === array_equals($a, $b));

// in_iterable()

$iterable = [new Phone('(656) 456-7765'), new Phone('(321) 456-1234')];
assert(true === in_iterable(new Phone('(321) 456-1234'), $iterable));
assert(false === in_iterable(new Phone('(232) 456-1234'), $iterable));

// iterable_unique()

$unique = iterable_unique([
    new Phone('(321) 456-1234'),
    new Phone('(465) 799-4566'),
    new Phone('(321) 456-1234'),
]);
$expected = [
    new Phone('(321) 456-1234'),
    new Phone('(465) 799-4566'),
];
assert(true === array_equals($expected, $unique));
```

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance61

Regular maintenance activity

Popularity20

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~166 days

Recently: every ~357 days

Total

10

Last Release

280d ago

Major Versions

v0.3.0 → v1.0.02021-09-04

1.2.x-dev → v2.0.02025-09-27

PHP version history (2 changes)v0.1.0PHP &gt;=7.4

v2.0.0PHP &gt;=8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/787c95c77f60d6026a4d95e28fe61b502cfa62b5e92a6c1b875c00b1e14b88ad?d=identicon)[piku235](/maintainers/piku235)

---

Top Contributors

[![piku235](https://avatars.githubusercontent.com/u/1687758?v=4)](https://github.com/piku235 "piku235 (102 commits)")

---

Tags

equatablephpresultequatable

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/jungi-common/health.svg)

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

PHPackages © 2026

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