PHPackages                             cjsaylor/libdomain - 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. cjsaylor/libdomain

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

cjsaylor/libdomain
==================

PHP classes and traits to facilitate domain driven design.

4.0.0(7y ago)291132[1 PRs](https://github.com/cjsaylor/libdomain/pulls)MITPHPPHP &gt;=7.1

Since May 10Pushed 6y agoCompare

[ Source](https://github.com/cjsaylor/libdomain)[ Packagist](https://packagist.org/packages/cjsaylor/libdomain)[ RSS](/packages/cjsaylor-libdomain/feed)WikiDiscussions master Synced today

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

libdomain
=========

[](#libdomain)

Libdomain is a php library to facilitate [domain driven development](http://en.wikipedia.org/wiki/Domain-driven_design).

[![Build Status](https://camo.githubusercontent.com/bb6c0c24aa88a4718d359fc5b210db9aab002e655bf4933506f1b7414b0009fe/68747470733a2f2f7472617669732d63692e6f72672f636a7361796c6f722f6c6962646f6d61696e2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/cjsaylor/libdomain)

Core concepts
-------------

[](#core-concepts)

This library contains the following abstract classes:

- `Entity` - An entity is an identifiable object.
- `ValueObject` - An object who's values are immutable.
- `Collection` - A collection of `Entity` objects.
- `CollectionEntity` - An entity object that also acts as a collection (an identifiable collection).

In cases where the abstract classes can't be extended, all functionality of the abstract classes are provided with traits. For example, if you wanted an existing entity to have the properties of a `ValueObject`, then you would use the `ReadAccessable` trait:

```
use Cjsaylor\Domain\ValueObject\ValueObjectInterface;
use Cjsaylor\Domain\Behavior\ReadAccessable;

class ConcreteEntity implements ValueObjectInterface {
  use ReadAccessable;
}
```

The `ConcreteEntity` would now be an immutable value object.

Examples
--------

[](#examples)

#### Entity Example

[](#entity-example)

The first example illustrates a user object that accepts an `email` attribute that must be an immutable email value object.

```
use \Cjsaylor\Domain\Entity;
use \Cjsaylor\Domain\ValueObject;

class Email extends ValueObject
{
  public function __construct(string $value) {
    // Validate an email address here
    $this['value'] = $value;
  }

  public function __toString() {
    return $this['value'];
  }
}

class User extends Entity
{
  public function offsetSet($offset, $value) : void
  {
    if ($offset === 'email' && !$value instanceof Email) {
      throw new \LogicException('Email must be an email value object!');
    }
    parent::offsetSet($offset, $value);
  }
}

$user = new User([
  'email' => new Email('user@somedomain.com')
]);
```

#### CollectionEntity example

[](#collectionentity-example)

This next example will illustrate a group of users where that group also has an identity. Here we will make use of the `CollectionEntity` which is both a `Collection` and an `Entity`. It will make use of the `User` entity defined in the first example.

```
use \Cjsaylor\Domain\CollectionEntity;

class UserGroup extends CollectionEntity
{
  // Here, we set the expectation that this collection can take only users
  public function __construct(array $data = [], User ...$users) {
    parent::__construct($data, ...$users);
  }

  // Here's a method to add additional users post-construction
  public function add(User $user) {
    $this->getItems()[] = $user;
  }
}

$users = [
  new User([
    'id' => 1,
    'email' => new Email('user@somedomain.com')
  ]),
  new User([
    'id' => 2,
    'email' => new Email('user2@somedomain.com')
  ])
];

$userGroup = new UserGroup([
  'id' => 1,
  ...$users
]);
```

#### Setter callback example

[](#setter-callback-example)

Let's modify the `User` object with some custom setter callbacks (available in `1.0.1`). This allows us to typehint (and do other custom set logic for the `Email` value object).

```
class User extends Entity {

  public function setEmail(Email $email) {
    $this->data['email'] = $email;
  }

}

// Would produce an error as `setEmail` would be called and would not match the type.
$user = new User(['email' => 'user@somedomain.com']);

// Valid
$user = new User(['email' => new Email('user@somedomain.com')]);
```

#### Concrete entities example

[](#concrete-entities-example)

In some instances, we don't want extra properties to be set on our entities. To limit the properties that can be set on an entity, the `PropertyLimitable` interface/trait can be implemented:

```
use Cjsaylor\Domain\Behavior\PropertyLimitable;
use Cjsaylor\Domain\Behavior\PropertyLimitTrait;

class User extends Entity implements PropertyLimitable {
  use PropertyLimitTrait;

  public function concreteAttributes() {
    return ['id', 'email'];
  }

}

$user = new User();
$user['id'] = 1; // OK!
$user['first_name'] = 'Chris'; // Has no affect and is not set.
```

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 93.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 ~191 days

Recently: every ~356 days

Total

9

Last Release

2901d ago

Major Versions

1.0.4 → 2.0.02014-08-28

2.1.0 → 3.0.02015-01-24

3.0.0 → 4.0.02018-07-23

PHP version history (2 changes)1.0.0PHP &gt;=5.4

4.0.0PHP &gt;=7.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/157755?v=4)[Chris Saylor](/maintainers/cjsaylor)[@cjsaylor](https://github.com/cjsaylor)

---

Top Contributors

[![cjsaylor](https://avatars.githubusercontent.com/u/157755?v=4)](https://github.com/cjsaylor "cjsaylor (42 commits)")[![dependabot-support](https://avatars.githubusercontent.com/u/112581971?v=4)](https://github.com/dependabot-support "dependabot-support (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/cjsaylor-libdomain/health.svg)

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

###  Alternatives

[cmixin/business-time

Carbon mixin to handle business days and opening hours

3201.5M1](/packages/cmixin-business-time)[wilianx7/php-recurring

PHP library for generating recurring dates, schedules, and repeated task recurrences.

1050.7k](/packages/wilianx7-php-recurring)[happyculture/combawa

Projects builder

1422.4k](/packages/happyculture-combawa)

PHPackages © 2026

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