PHPackages                             frankvanhest/value-objects - 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. frankvanhest/value-objects

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

frankvanhest/value-objects
==========================

Value Objects interfaces and abstracts to create value objects

v5.0.0(4mo ago)0354MITPHPPHP ~8.4.0 || ~8.5.0CI passing

Since Nov 6Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/frankvanhest/value-objects)[ Packagist](https://packagist.org/packages/frankvanhest/value-objects)[ GitHub Sponsors](https://github.com/frankvanhest)[ RSS](/packages/frankvanhest-value-objects/feed)WikiDiscussions v5.x Synced 1w ago

READMEChangelog (10)Dependencies (5)Versions (24)Used By (0)

Value Objects
=============

[](#value-objects)

This package provides abstracts classes and interface to create Value Objects based on the four scalar type supported by PHP.

- [Installation](#installation)
- [What is a Value Object](#what-is-a-value-object)
- [Purpose](#purpose)
- [Installation](#installation)
- [Usage](#usage)
- [Contribution](#contribution)
- [License](#license)

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

[](#installation)

```
composer require frankvanhest/value-objects

```

What is a Value Object
----------------------

[](#what-is-a-value-object)

A Value Object is a wrapper for primitive types such as a string. It usually has specific domain knowledge, and it will make sure that the value is asserted accordingly to that domain knowledge. The characteristics of a Value Object are:

- it is immutable
- it wraps primitive data
- it represents domain specific knowledge
- it has a name which give it a meaningful purpose
- it is equals to another instance when the value is the same, but the instance itself is not

Whenever an instance of a Value Object is passed around your application, you can be sure that the value inside is what you expect it to be. For example, if you have a Value Object Email, you can be sure that the value is a correctly formatted string according to what an e-mail address should be.

Purpose
-------

[](#purpose)

The purpose of this package is to provide a set of interfaces, abstracts and factories to get you started with value objects. It should not be considered as a silver bullet. You should always be use the best tools for your application. That being said, what could be reasons to use this package. Like stated before, if you are new to value objects this package will get you started and provide a learning opportunity to get a better understanding of value objects. Another reason is that you'll don't need to write the same basic code for your value objects, but again do not use it as a silver bullet. When you encounter a value object that cannot or cannot easily be created by using this package, do not try to do so. Write the complete implementation yourself. When you are more experienced with value objects and programming in general, this package is probably not for you. That is of course that is entirely up to you.

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

[](#installation-1)

A most of the packages for PHP, the installation is done by using [Composer](https://getcomposer.org).

```
composer require frankvanhest/value-objects
```

Usage
-----

[](#usage)

This package only provided the means to create your own Value Objects. The four main primitives types string, integer, float and boolean are included. Each one has its own interface, abstract and factory (except for boolean) available. With each factory you can add a corresponding value modifier. For instance, you want to create a Value Object for Money. You can use the interface [`FloatValueObject`](src/Interfaces/FloatValueObject.php) and implement according to your own need. To simplify things, you can also use the abstract class [`FloatValueObject`](src/Abstracts/FloatValueObject.php). See the following example.

```
use FrankVanHest\ValueObjects\Abstracts\FloatValueObject;

final readonly class Money extends FloatValueObject
{
    protected function assert(float $value): void
    {
        if ($value < 0) {
            throw new \InvalidArgumentException('Only a value greater than zero is allowed');
        }
    }
}
```

As you can see, you only have to implement the assertion for your Value Object according to your domain knowledge. In this case the only constraint is that the value should be greater than zero.

We got convenient methods like `fromFloat`, `toFloat` and `equals` available.

What if I want to be able to initialize `Money` from a string. Just implement the interface [`StringValueObject`](src/Interfaces/StringValueObject.php) and we get:

```
use FrankVanHest\ValueObjects\Abstracts\FloatValueObject;
use FrankVanHest\ValueObjects\Interfaces\StringValueObject;

final readonly class Money extends FloatValueObject implements StringValueObject
{
    protected function assert(float $value): void
    {
        if ($value < 0) {
            throw new \InvalidArgumentException('Only a value greater than zero is allowed');
        }
    }

    public function toString(): string
    {
        return sprintf('The value of Money is %f', $this->asFloat());
    }

    public static function fromString(string $value): static
    {
        if (!is_numeric($value)) {
            throw new \InvalidArgumentException('Only numeric values are allowed');
        }

        return new static((float)$value);
    }
}
```

If you want to modify the value before the value object is created you can provide a value modified when using the factory to create the Money object.

```
use FrankVanHest\ValueObjects\Interfaces\FloatValueModifier;

final readonly class DivideBy implements FloatValueModifier
{
    public function __construct(private float $divideBy)
    {
    }

    public function modify(float $value): float
    {
        return $value / $this->divideBy;
    }
}
```

```
use FrankVanHest\ValueObjects\Factories\FloatValueObjectFactory;

$money = FloatValueObjectFactory::create(Money::class, 100.50, new DivideBy(10));
```

As stated before when it comes to comparing two instances of Value Objects it only compares the value itself, not if the Value Objects are the same instance. To clarify this, look at the following examples based the `Money` class.

```
$moneyA = Money::fromFloat(10.25);
$moneyB = Money::fromFloat(10.25);
$moneyC = Money::fromFloat(1.50);

$moneyA->equals($moneyA); // Returns true
$moneyA->equals($moneyB); // Returns true
$moneyA->equals($moneyC); // Returns false
$moneyA->equals(null); // Returns false
```

Contribution
------------

[](#contribution)

Feel free to submit an issue of pull request. When it comes to a pull request I'm curious of how it improves this packages of which problem it may solve.

There are some requirements:

- Use PSR-12 for code styling
- Write a test for every meaningful change

License
-------

[](#license)

See [LICENCE](LICENSE.md)

###  Health Score

47

—

FairBetter than 94% of packages

Maintenance75

Regular maintenance activity

Popularity12

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity77

Established project with proven stability

 Bus Factor1

Top contributor holds 97.9% 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 ~66 days

Recently: every ~176 days

Total

24

Last Release

139d ago

Major Versions

v0.12.0 → v3.0.02023-03-23

v1.0.0 → v4.0.02024-01-26

v1.1.0 → v3.1.02024-01-26

v2.1.0 → v4.1.02025-12-30

v4.x-dev → v5.0.02025-12-30

PHP version history (10 changes)v0.1.0PHP ~8.0.0 | ~8.1.0

v0.2.0PHP ~8.1.0

v0.32.0PHP ~8.2.0

v0.22.0PHP ~8.1.0 | ~8.2.0

v0.12.0PHP ~8.0.0 | ~8.1.0 | ~8.2.0

v2.0.0PHP ~8.1.0 || ~8.2.0

v1.0.0PHP ~8.0.0 || ~8.1.0 || ~8.2.0

v4.0.0PHP ~8.2.0 || ~8.3.0

v4.1.0PHP ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0

v5.0.0PHP ~8.4.0 || ~8.5.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2206481?v=4)[Frank van Hest](/maintainers/FrankVanHest)[@frankvanhest](https://github.com/frankvanhest)

---

Top Contributors

[![frankvanhest](https://avatars.githubusercontent.com/u/2206481?v=4)](https://github.com/frankvanhest "frankvanhest (46 commits)")[![mend-bolt-for-github[bot]](https://avatars.githubusercontent.com/in/16809?v=4)](https://github.com/mend-bolt-for-github[bot] "mend-bolt-for-github[bot] (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/frankvanhest-value-objects/health.svg)

```
[![Health](https://phpackages.com/badges/frankvanhest-value-objects/health.svg)](https://phpackages.com/packages/frankvanhest-value-objects)
```

###  Alternatives

[sulu/form-bundle

Bundle for creating forms in Sulu.

87287.3k7](/packages/sulu-form-bundle)

PHPackages © 2026

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