<?php
declare(strict_types=1);
namespace App\Domain\ValueObjects;
use InvalidArgumentException;
readonly class Money
{
public function __construct(
public int $amountInCents,
public string $currency = 'KES'
) {
if ($this->amountInCents < 0) {
throw new InvalidArgumentException("Amount cannot be negative.");
}
}
public static function fromDecimal(float $amount, string $currency = 'KES'): self {
return new self((int)round($amount * 100), $currency);
}
public function toDecimal(): float {
return $this->amountInCents / 100;
}
}
Enforcing True Domain Safety with Native Readonly Classes in PHP 8.2+
PHP 8.2 introduced native readonly class declarations, ensuring that every property cannot be modified after constructor initialization.
- Domain Validation: A Money object cannot exist in an invalid state.
- Thread-Safe: Immutable objects can be passed across jobs and events without unexpected side-effects.
Accelerate Your Engineering Career
Get monthly masterclasses, exclusive code snippets, and direct architectural reviews.
Become a Supporter • KES 500 / Month