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

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

solidframe/ddd
==============

DDD building blocks: ValueObject, Entity, AggregateRoot, Specification for SolidFrame

v0.1.0(3mo ago)091MITPHP ^8.2

Since Apr 11Compare

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

READMEChangelog (1)Dependencies (1)Versions (2)Used By (1)

SolidFrame DDD
==============

[](#solidframe-ddd)

Domain-Driven Design building blocks: Entity, ValueObject, AggregateRoot, and Specification pattern.

Framework-agnostic. Use with any PHP 8.2+ project.

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

[](#installation)

```
composer require solidframe/ddd
```

Components
----------

[](#components)

### Entity

[](#entity)

Entities have identity and are compared by identity, not by value.

```
use SolidFrame\Ddd\Entity\AbstractEntity;
use SolidFrame\Core\Identity\UuidIdentity;

final readonly class UserId extends UuidIdentity {}

final class User extends AbstractEntity
{
    private string $name;

    public function __construct(UserId $id, string $name)
    {
        parent::__construct($id);
        $this->name = $name;
    }

    public function rename(string $name): void
    {
        $this->name = $name;
    }

    public function name(): string
    {
        return $this->name;
    }
}

$user = new User(UserId::generate(), 'Kadir');
$user->identity(); // UserId instance
$user->equals($otherUser); // compares by identity
```

### Aggregate Root

[](#aggregate-root)

Aggregate roots are entities that record domain events.

```
use SolidFrame\Ddd\Aggregate\AbstractAggregateRoot;

final class Order extends AbstractAggregateRoot
{
    private OrderStatus $status;

    public static function place(OrderId $id, CustomerId $customerId): self
    {
        $order = new self($id);
        $order->status = OrderStatus::Placed;
        $order->recordThat(new OrderPlaced($id, $customerId));

        return $order;
    }

    public function cancel(): void
    {
        $this->status = OrderStatus::Cancelled;
        $this->recordThat(new OrderCancelled($this->identity()));
    }
}

$order = Order::place(OrderId::generate(), $customerId);
$events = $order->releaseEvents(); // [OrderPlaced]
```

### Value Object

[](#value-object)

Immutable objects compared by value, not identity.

```
use SolidFrame\Ddd\ValueObject\StringValueObject;
use SolidFrame\Ddd\ValueObject\IntValueObject;
use SolidFrame\Ddd\ValueObject\BoolValueObject;

// String-based
final readonly class Email extends StringValueObject
{
    public static function from(string $value): static
    {
        filter_var($value, FILTER_VALIDATE_EMAIL) or throw new InvalidEmail($value);

        return parent::from($value);
    }
}

$email = Email::from('kadir@example.com');
$email->value();   // 'kadir@example.com'
$email->equals(Email::from('kadir@example.com')); // true
(string) $email;   // 'kadir@example.com'

// Integer-based
final readonly class Age extends IntValueObject
{
    public static function from(int $value): static
    {
        ($value >= 0) or throw InvalidAge::negative($value);

        return parent::from($value);
    }
}

// Boolean-based
final readonly class IsActive extends BoolValueObject {}

$active = IsActive::from(true);
$active->value(); // true
```

For composite value objects, implement `ValueObjectInterface` directly:

```
use SolidFrame\Ddd\ValueObject\ValueObjectInterface;

final readonly class Money implements ValueObjectInterface
{
    private function __construct(
        public int $amount,
        public string $currency,
    ) {}

    public static function from(int $amount, string $currency): self
    {
        return new self($amount, $currency);
    }

    public function add(self $other): self
    {
        ($this->currency === $other->currency)
            or throw InvalidMoney::currencyMismatch($this->currency, $other->currency);

        return new self($this->amount + $other->amount, $this->currency);
    }

    public function equals(ValueObjectInterface $other): bool
    {
        return $other instanceof self
            && $this->amount === $other->amount
            && $this->currency === $other->currency;
    }

    public function __toString(): string
    {
        return sprintf('%d %s', $this->amount, $this->currency);
    }
}
```

### Specification

[](#specification)

Composable business rules using the Specification pattern.

```
use SolidFrame\Ddd\Specification\AbstractSpecification;

final class IsAdult extends AbstractSpecification
{
    public function isSatisfiedBy(mixed $candidate): bool
    {
        return $candidate->age() >= 18;
    }
}

final class HasVerifiedEmail extends AbstractSpecification
{
    public function isSatisfiedBy(mixed $candidate): bool
    {
        return $candidate->isEmailVerified();
    }
}

// Compose specifications
$canPurchase = (new IsAdult())->and(new HasVerifiedEmail());
$canPurchase->isSatisfiedBy($user); // true/false

// Negate
$isMinor = (new IsAdult())->not();

// OR
$canAccess = (new IsAdult())->or(new HasParentalConsent());
```

API Reference
-------------

[](#api-reference)

Class / InterfacePurpose`EntityInterface`Contract for entities with identity`AbstractEntity`Base entity with identity and equality`AggregateRootInterface`Entity that records domain events`AbstractAggregateRoot`Base aggregate with `recordThat()` / `releaseEvents()``ValueObjectInterface`Contract for immutable value objects`StringValueObject`Base for string value objects`IntValueObject`Base for integer value objects`BoolValueObject`Base for boolean value objects`SpecificationInterface`Composable business rule contract`AbstractSpecification`Base specification with `and()` / `or()` / `not()``AndSpecification`Combines two specs with AND`OrSpecification`Combines two specs with OR`NotSpecification`Negates a specRelated Packages
----------------

[](#related-packages)

- [solidframe/core](../core) — Identity, DomainEventInterface, Bus interfaces
- [solidframe/cqrs](../cqrs) — Command/Query bus for use cases
- [solidframe/event-sourcing](../event-sourcing) — Event-sourced aggregates
- [solidframe/archtest](../archtest) — Enforce DDD rules in tests
- [solidframe/laravel](../laravel) — `make:entity`, `make:value-object`, `make:aggregate-root`
- [solidframe/symfony](../symfony) — Same generators for Symfony

Contributing
------------

[](#contributing)

This repository is a read-only split of the [solidframe/solidframe](https://github.com/solidframe/solidframe) monorepo, auto-synced on every push to `main`. Issues, pull requests, and discussions belong in the monorepo.

###  Health Score

33

—

LowBetter than 72% of packages

Maintenance80

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community5

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

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

Unknown

Total

1

Last Release

104d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/97de2a466719393a21a8ce5caef247a1afb8aec5a8974248da0583f4197765b2?d=identicon)[abdulkadir-posul](/maintainers/abdulkadir-posul)

### Embed Badge

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

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

PHPackages © 2026

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