Skip to content

Repository files navigation

Value Object

CI PHP Version Packagist

Small, strictly typed value objects for PHP applications. The package provides immutable wrappers for common scalar, identifier, date/time, and person-domain values, with validation close to the data it protects.

Why value objects

A primitive like int or string says nothing about what it holds. A value object gives the value a name, validates it once, and makes illegal states unrepresentable - the core idea behind value objects in Domain-Driven Design.

// Primitive obsession: any int slips through, and it is easy to swap arguments.
function register(string $firstname, string $lastname, int $age): void {}
register('Lovelace', 'Ada', -5); // compiles, runs, corrupts data

// Value objects: the type system and constructors guard the domain rules.
function register(Name $name, Age $age): void {}
register(
    new Name(Firstname::fromString('Ada'), Lastname::fromString('Lovelace')),
    Age::fromInt(-5), // throws ValueObjectException before reaching the domain
);

Value objects are compared by value, not identity ($a->equals($b)), and never change after creation, so they can be passed around and shared safely.

Requirements

  • PHP 8.3, 8.4 or 8.5
  • ext-mbstring
  • Composer 2

Installation

composer require slpxxv/value-object

Usage

All value objects are immutable, implement Stringable, and expose their native value through value(). Invalid input throws Slpxxv\ValueObject\Exception\ValueObjectException or one of its subclasses.

Scalar values

use Slpxxv\ValueObject\Boolean;
use Slpxxv\ValueObject\Double;
use Slpxxv\ValueObject\NonNegativeInteger;
use Slpxxv\ValueObject\PositiveInteger;
use Slpxxv\ValueObject\StringLiteral;

$enabled = Boolean::fromString('yes');
$ratio = Double::fromFloat(1.5);
$offset = NonNegativeInteger::fromInt(0);
$page = PositiveInteger::fromInt(1);
$label = StringLiteral::fromString('Slpxxv');

$enabled->value(); // true
(string) $page;    // "1"
$label->length();  // 6

Boolean accepts 1, true, yes, y, and on, plus their false equivalents (0, false, no, n, off). String input is case-insensitive and surrounding whitespace is ignored. Double rejects NAN and infinite values.

UUID

use Slpxxv\ValueObject\Identifier\Uuid;

$id = Uuid::generate();
$sameId = Uuid::fromString($id->value());
$binary = $id->toBytes();

$id->equals($sameId);       // true
Uuid::fromBytes($binary);   // equivalent UUID

UUID strings are validated and normalized to their canonical lowercase representation.

Date and time

use Slpxxv\ValueObject\DateTime\DateTime;

$createdAt = DateTime::fromString('2026-08-12T12:00:00+00:00');
$expiresAt = $createdAt->modify('+30 days');

$createdAt->lessThan($expiresAt); // true
$createdAt->format();             // DateTimeInterface::ATOM by default

The wrapped value is a DateTimeImmutable; modifying it always creates a new value object.

Person values

use Slpxxv\ValueObject\Person\Age;
use Slpxxv\ValueObject\Person\Female;
use Slpxxv\ValueObject\Person\Firstname;
use Slpxxv\ValueObject\Person\Lastname;
use Slpxxv\ValueObject\Person\Name;

$name = new Name(
    Firstname::fromString('Ada'),
    Lastname::fromString('Lovelace'),
);

$age = Age::fromInt(36); // accepted range: 0..150
$gender = Female::create();

(string) $name; // "Ada Lovelace"

First names support up to 50 characters and last names up to 100 characters. Available gender values are created with Female::create(), Male::create(), and Unspecified::create().

Development

Install dependencies and run the complete quality suite:

composer install
composer check

Individual commands are also available:

composer test      # PHPUnit
composer analyse   # PHPStan and Psalm
composer cs-check  # coding-style check
composer cs-fix    # apply coding-style fixes

License

Released under the MIT License.

About

Strictly typed, immutable value objects for PHP 8.3+: scalars, UUID, date/time and person values, with validation at the boundary. PHPUnit, PHPStan, Psalm.

Topics

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages