PHPackages                             alephtools/ddd - 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. alephtools/ddd

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

alephtools/ddd
==============

Helpful instruments for Domain Driven Design.

v2.2.3(7mo ago)926.5k↓25%101MITPHPPHP &gt;=8.1

Since Nov 12Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/AlephTav/ddd-php)[ Packagist](https://packagist.org/packages/alephtools/ddd)[ RSS](/packages/alephtools-ddd/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (4)Versions (171)Used By (1)

DDD Tools
=========

[](#ddd-tools)

Collection of classes that can be useful to build applications according to Domain Driven Design (DDD).

Table of Contents
-----------------

[](#table-of-contents)

- [Infrastructure Layers](#infrastructure)
    - [Base Domain Classes](#base_classes)
        - [DTO](#dto)
        - [DomainObject](#DomainObject)
        - [ValueObject](#ValueObject)
    - [Enums](#enums)
    - [Helpers](#helpers)
    - [SQL Builder](#sql_builder)
        - [MySQL](#mysql)
            - [Select Queries](#mysql_select)
        - [PostgreSQL](#postgresql)
- [Model Layer](#model)
    - [Entity Identities](#identities)
    - [Common Value Objects](#value_objects)
    - [Common Domain Exceptions](#exceptions)
    - [Common Domain Events](#events)
- [Application Layers](#application)
    - [Base Application Service](#application_service)
    - [Base Query Service](#query_service)
    - [Domain Event Subscribers](#event_subscribers)

### Base Domain Classes

[](#base-domain-classes)

#### DTO

[](#dto)

The base class of all domain objects is `DTO`. DTO allows to embed properties (as in JAVA, C# and some other strictly-typed program languages) in our classes. A class property consists of three elements:

1. Private or protected class field.
2. Property description according to PHPDoc (@property) at the class comment.
3. Optional setter or getter.

`DTO` is an abstract class. There are two child classes of it: `StrictDto` and `WeakDto`. The difference between them is that the first one throws `NonExistentPropertyException` during class initialization if a property does not exist and the second one isn't.

DTO usage example:

```
/**
 * @property string $prop1
 * @property-read DateTime $prop2
 * @property-write int $prop3
 */
class Data extends StrictDto
{
    private $prop1;
    private DateTime $prop2;
    protected int $prop3 = 0;

    public function setProp1(string $value): void
    {
        $this->prop1 = $value;
    }

    protected function setProp2(?DateTime $value): void
    {
        $this->prop2 = $value;
    }

    public function getProp2(): array
    {
        return $this->prop2 ?: new DateTime();
    }
}

$dto = new Data([
    'prop1' => 'abc',
    'prop2' => null,
    'prop3' => 10,
    'prop4' => 1 // causes NonExistentPropertyException for StrictDto but not for WeakDto.
]);

$val1 = $dto->prop1; // abc
$val2 = $dto->prop2; // current time object
$dto->prop3 = 100;
$val3 = $dto->prop3  // throws RuntimeException
$dto->prop4 = 1      // throws NonExistentPropertyException

$dtoAsArray = $dto->toArray(); // you can use toNestedArray() if some properties are DTO themselves.
$dtoAsJson = json_encode($dto); // or use $dto->toJson()
$dtoAsString = (string)$dto // or use $dto->toString()
```

There are some rules to get properties work properly:

- The property type in PHPDoc comment does not matter. To restrict property by type you need to specify type hinting for property setter, getter or field. If assigned value does not match property type `InvalidArgumentException` is thrown.
- Getters of read-only or regular properties must be public.
- Setters of write-only or regular properties must be public.
- Private and protected setters are automatically invoked during the class initialization.
- If you want to inherit a property its field and setter must not be private.

#### DomainObject

[](#domainobject)

`DomainObject` is a base class for all domain object. It is inherited from `StrictDto`. All domain objects contains sone useful methods:

1. `equals()` to compare domain objects with others.
2. `copy()` to create a copy of the domain object.
3. `copyWith()` to create a copy of the domain object with the given property values.
4. `hash()` to get unique domain object hash.
5. `domainName()` to get name of the domain object (it equals class name by default).

#### ValueObject

[](#valueobject)

`ValueObject` is a base class for all domain value objects. It has the same methods as `DomainObject`.

### SQL Builder

[](#sql-builder)

SQL Builder is a simple wrapper that allows to build SQL query string for some particular RDBMS (MySQL and PostgreSQL are currently only supported). You can use it to be independent of any PHP framework. See the table below to figure out how to use SQL Builder.

#### MySQL

[](#mysql)

##### Select Queries

[](#select-queries)

PHP Expression:

```
$row = (new SelectQuery($queryExecutor))
    ->from('users', 'u')
    ->where('u.id', '=', 10)
    ->row();

// $row is a single record (associative array) or empty array.
```

Executed SQL Query:

```
SELECT * FROM users u
WHERE u.id = 10
```

PHP Expression:

```
$rows = (new SelectQuery($queryExecutor))
    ->from('users')
    ->select([
        'id',
        'firstName',
        'lastName',
        'email'
    ])
    ->where('email', 'LIKE', '%gmail.com')
    ->rows();

// $rows is a record set (array of associative arrays) or empty array.
```

Executed SQL Query:

```
SELECT id, firstName, lastName, email FROM users
WHERE email LIKE '%gmail.com'
```

PHP Expression:

```
$rows = (new SelectQuery($queryExecutor))
    ->from([
        'users' => 'u,
        'contacts' => 'c'
    ])
    ->select([
        'u.id' => 'user_id',
        'c.id' => 'contact_id'
    ])
    ->where('c.user_id = u.id')
    ->limit(10)
    ->offset(50)
    ->rows();

// $rows is a record set (array of associative arrays) or empty array.
```

Executed SQL Query:

```
SELECT u.id user_id, c.id contact_id FROM users u, contacts c
WHERE c.user_id = u.id
LIMIT 10 OFFSET 50
```

PHP Expression:

```
$rows = (new SelectQuery($queryExecutor))
    ->from('users', 'u)
    ->from('contacts', 'c')
    ->select('u.id', 'user_id')
    ->select('c.id', 'contact_id')
    ->where('c.user_id = u.id')
    ->rows();

// $rows is a record set (array of associative arrays) or empty array.
```

Executed SQL Query:

```
SELECT u.id user_id, c.id contact_id FROM users u, contacts c
WHERE c.user_id = u.id
```

PHP Expression:

```
$rows = (new SelectQuery($queryExecutor))
    ->from('users')
    ->orderBy('email', 'DESC')
    ->orderBy('id', 'ASC')
    ->rows();

// $rows is a record set (array of associative arrays) or empty array.
```

Executed SQL Query:

```
SELECT * FROM users
ORDER BY email DESC, id ASC
```

PHP Expression:

```
$count = (new SelectQuery($queryExecutor))
    ->from('users u')
    ->leftJoin('contacts c', 'c.user_id = u.id')
    ->where('u.id', '=', 5)
    ->count('DISTINCT c.name');

// $count is an integer value.
```

Executed SQL Query:

```
SELECT COUNT(DISTINCT c.name) FROM users u
LEFT JOIN contacts c ON c.user_id = u.id
WHERE u.id = 5
```

PHP Expression:

```
$count = (new SelectQuery($queryExecutor))
    ->from('users u')
    ->innerJoin('contacts c', 'c.user_id = u.id')
    ->select([
        'u.id',
        'u.email'
    ])
    ->select('COUNT(c.id)', 'contact_number')
    ->groupBy('u.id')
    ->rows();

// $rows is a record set (array of associative arrays) or empty array.
```

Executed SQL Query:

```
SELECT i.id, u.email, COUNT(c.id) contact_number FROM users u
INNER JOIN contacts c ON c.user_id = u.id
GROUP BY u.id
```

#### PostgreSQL

[](#postgresql)

###  Health Score

59

—

FairBetter than 99% of packages

Maintenance78

Regular maintenance activity

Popularity34

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity89

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 81.2% 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 ~16 days

Recently: every ~115 days

Total

169

Last Release

60d ago

Major Versions

v1.8.12 → v2.0.02022-03-09

v1.10.4 → v2.0.32022-06-22

v1.10.5 → v2.0.42022-09-19

PHP version history (3 changes)v1.0.0PHP &gt;=7.2.0

v1.7.0PHP &gt;=7.4

v2.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/b131f4aa7fff971c0eababb754da0246e2886d32f95956ec353c0d706f3e7a2c?d=identicon)[AlephTav](/maintainers/AlephTav)

---

Top Contributors

[![AlephTav](https://avatars.githubusercontent.com/u/1460449?v=4)](https://github.com/AlephTav "AlephTav (164 commits)")[![spyric](https://avatars.githubusercontent.com/u/2044754?v=4)](https://github.com/spyric "spyric (20 commits)")[![alikabir-kydyrmembekov](https://avatars.githubusercontent.com/u/126063135?v=4)](https://github.com/alikabir-kydyrmembekov "alikabir-kydyrmembekov (12 commits)")[![chamav](https://avatars.githubusercontent.com/u/5631601?v=4)](https://github.com/chamav "chamav (2 commits)")[![a-stankeev](https://avatars.githubusercontent.com/u/5457853?v=4)](https://github.com/a-stankeev "a-stankeev (2 commits)")[![nikvl](https://avatars.githubusercontent.com/u/19389461?v=4)](https://github.com/nikvl "nikvl (1 commits)")[![tyliooo](https://avatars.githubusercontent.com/u/62645431?v=4)](https://github.com/tyliooo "tyliooo (1 commits)")

---

Tags

dddAlephclean architecture

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/alephtools-ddd/health.svg)

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

###  Alternatives

[prooph/service-bus

PHP Enterprise Service Bus Implementation supporting CQRS and DDD

4421.4M32](/packages/prooph-service-bus)[ecotone/ecotone

Supporting you in building DDD, CQRS, Event Sourcing applications with ease.

558549.8k17](/packages/ecotone-ecotone)[prooph/event-sourcing

PHP EventSourcing library

267808.5k18](/packages/prooph-event-sourcing)[phpmentors/domain-kata

Kata for domain models

73426.9k9](/packages/phpmentors-domain-kata)[aura/payload

A Domain Payload implementation.

56370.4k9](/packages/aura-payload)[aura/payload-interface

An interface package for Domain Payload implementations.

13392.7k4](/packages/aura-payload-interface)

PHPackages © 2026

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