PHPackages                             yorcreative/argonaut-dto - 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. [Validation &amp; Sanitization](/categories/validation)
4. /
5. yorcreative/argonaut-dto

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

yorcreative/argonaut-dto
========================

A framework-agnostic PHP DTO package that provides nested casting, recursive serialization, validation, assemblers, and immutable DTO support out of the box.

v1.0.0(today)066↑2809.1%MITPHPPHP ^8.3CI passing

Since Jul 30Pushed todayCompare

[ Source](https://github.com/YorCreative/Argonaut-DTO)[ Packagist](https://packagist.org/packages/yorcreative/argonaut-dto)[ Docs](https://github.com/YorCreative/Argonaut-DTO)[ GitHub Sponsors](https://github.com/sponsors/YorCreative)[ RSS](/packages/yorcreative-argonaut-dto/feed)WikiDiscussions main Synced today

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

 [ ![Logo](content/argonaut-dto.png) ](https://github.com/YorCreative)

### Argonaut DTO

[](#argonaut-dto)

[![GitHub license](https://camo.githubusercontent.com/981be19424da332b05adfbe2a0ae4b14369b70f61c3b0db8c92c1b93156c7cdb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f596f7243726561746976652f4172676f6e6175742d44544f)](https://github.com/YorCreative/Argonaut-DTO/blob/main/LICENSE)[![GitHub stars](https://camo.githubusercontent.com/d053f28fdf0b83e13fe8311d431e045d385ac97c150129f411e95c0fe21fda1d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f596f7243726561746976652f4172676f6e6175742d44544f3f6c6162656c3d5265706f2532305374617273)](https://github.com/YorCreative/Argonaut-DTO/stargazers)[![GitHub Org's stars](https://camo.githubusercontent.com/c3aef82ca684110e373af0e3676f82fd43ae79ae081691bd87c7e713f993435e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f596f7243726561746976653f7374796c653d736f6369616c266c6162656c3d596f7243726561746976652532305374617273266c696e6b3d68747470732533412532462532466769746875622e636f6d253246596f724372656174697665)](https://camo.githubusercontent.com/c3aef82ca684110e373af0e3676f82fd43ae79ae081691bd87c7e713f993435e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f596f7243726561746976653f7374796c653d736f6369616c266c6162656c3d596f7243726561746976652532305374617273266c696e6b3d68747470732533412532462532466769746875622e636f6d253246596f724372656174697665)[![GitHub issues](https://camo.githubusercontent.com/a0f50876fc86038374ba45c266f5950510db4758605a843987b2b4a804f9384b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f596f7243726561746976652f4172676f6e6175742d44544f)](https://github.com/YorCreative/Argonaut-DTO/issues)[![GitHub forks](https://camo.githubusercontent.com/e599e553157c87c265f15009b482a776dc93cd32408191ecd8219134427fc16d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f596f7243726561746976652f4172676f6e6175742d44544f)](https://github.com/YorCreative/Argonaut-DTO/network)[![Packagist Downloads](https://camo.githubusercontent.com/7ddc22853590b2fc19e9616a94f36b33e45a39444474da04d3bb3aa3e82dd709/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f796f7263726561746976652f6172676f6e6175742d64746f3f636f6c6f723d677265656e)](https://camo.githubusercontent.com/7ddc22853590b2fc19e9616a94f36b33e45a39444474da04d3bb3aa3e82dd709/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f796f7263726561746976652f6172676f6e6175742d64746f3f636f6c6f723d677265656e)[![Tests](https://github.com/YorCreative/Argonaut-DTO/actions/workflows/tests.yml/badge.svg)](https://github.com/YorCreative/Argonaut-DTO/actions/workflows/tests.yml)[![Security](https://github.com/YorCreative/Argonaut-DTO/actions/workflows/security.yml/badge.svg)](https://github.com/YorCreative/Argonaut-DTO/actions/workflows/security.yml)

Framework-agnostic Data Transfer Objects for PHP 8.3+. Argonaut DTO provides the useful parts of Laravel Argonaut DTO without requiring Laravel: nested DTO and enum casting, recursive serialization, mutable and immutable DTOs, convention-based assemblers, and lightweight validation.

Requirements
------------

[](#requirements)

- PHP 8.3, 8.4, or 8.5

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

[](#installation)

Install via Composer:

```
composer require yorcreative/argonaut-dto
```

Basic DTO
---------

[](#basic-dto)

```
use YorCreative\ArgonautDTO\ArgonautDTO;

final class UserDTO extends ArgonautDTO
{
    public string $name;
    public string $email;

    protected array $casts = [
        'name' => 'string',
        'email' => 'string',
    ];

    public function rules(): array
    {
        return [
            'name' => ['required', 'string'],
            'email' => ['required', 'email'],
        ];
    }
}

$user = new UserDTO(['name' => 'Jane', 'email' => 'jane@example.com']);
$user->merge(['name' => 'Jane Doe']);

$user->toArray();
$user->toJson();
$user->isValid();
```

Unknown input keys are ignored. A setter named `set` takes precedence over direct property assignment. Declare `$prioritizedAttributes` when setters must run before the remaining input attributes.

Nested casts
------------

[](#nested-casts)

```
use YorCreative\ArgonautDTO\ArgonautDTO;
use YorCreative\ArgonautDTO\Collection;

final class OrderDTO extends ArgonautDTO
{
    public array $items;
    public Collection $history;
    public ?UserDTO $customer = null;

    protected array $casts = [
        'items' => [OrderItemDTO::class],
        'history' => Collection::class.':'.OrderEventDTO::class,
        'customer' => UserDTO::class,
    ];
}
```

Array casts use `[SomeDTO::class]`. Collection casts use `Collection::class . ':' . SomeDTO::class` (the shorthand `collection:SomeDTO` is also supported). Arrays, traversables, and the package `Collection` can be used as input.

Backed enums and `DateTimeInterface` implementations can be cast directly:

```
protected array $casts = [
    'status' => OrderStatus::class,
    'createdAt' => DateTimeImmutable::class,
];
```

Nested DTOs and backed enums serialize recursively; enums serialize to their backing values.

Serialization depth
-------------------

[](#serialization-depth)

`toArray()`, `toJson()`, and `jsonSerialize()` walk the whole DTO graph:

```
$dto->toArray();          // full graph
$dto->toArray(2);         // two levels of nested DTOs
$dto->toJson(depth: 2);   // same limit, JSON encoded
```

`$depth` counts DTO nesting levels and defaults to `ArgonautDTO::DEFAULT_MAX_DEPTH` (512). Exceeding it throws a `RuntimeException` rather than silently emitting an empty array, so truncation can never be mistaken for missing data.

Circular references are detected directly, not inferred from the depth limit, and raise `YorCreative\ArgonautDTO\CircularReferenceException` (a `RuntimeException`) naming the instance involved. The same DTO appearing in two sibling branches is a shared reference rather than a cycle and serializes normally.

`toJson()` also accounts for PHP's own `json_encode()` depth limit. Because each array or collection of DTOs adds a level of its own, a graph well inside `$depth` can still exceed the encoder's 512 levels; `toJson()` raises the encoder limit to fit whatever the walk produced. Note that `json_decode()` has the same 512 default, so decoding very deep payloads needs an explicit depth.

Immutable DTOs
--------------

[](#immutable-dtos)

Declare DTO properties as `readonly` and extend `ArgonautImmutableDTO`:

```
final class UserSnapshotDTO extends ArgonautImmutableDTO
{
    public readonly string $id;
    public readonly string $name;
}
```

Readonly properties are initialized once during construction. Missing required properties remain uninitialized, allowing PHP's normal typed-property error to identify an incomplete snapshot.

Assemblers
----------

[](#assemblers)

Assemblers resolve `to` first, then `from`:

```
final class UserAssembler extends ArgonautAssembler
{
    public static function toUserDTO(object $input): UserDTO
    {
        return new UserDTO([
            'name' => $input->display_name,
            'email' => $input->email,
        ]);
    }
}

$user = UserAssembler::assemble($payload, UserDTO::class);
$users = UserAssembler::fromArray($payloads, UserDTO::class);
```

`fromArray()` and `fromCollection()` return the package's dependency-free `Collection`, which supports iteration, array access, `count()`, `first()`, `all()`, `map()`, and `filter()`.

Instance assembler methods are supported through `assembleInstance()` or by passing an assembler instance to `assemble()`.

Validation
----------

[](#validation)

`rules()` uses [YorCreative DataValidation](https://packagist.org/packages/yorcreative/data-validation), including its complete rule set, nested paths, wildcards, and custom closures. Argonaut preserves the convenient `int`, `bool`, `collection`, and `sometimes` aliases: collections are arrays after serialization, and `sometimes` omits the rule set when the field is absent.

Custom closures use DataValidation's signature: `function (string $field, mixed $value, callable $fail, array $data): bool`.

```
$errors = $user->validate(throw: false);
// ['email' => ['The email field failed the email rule.']]
```

Calling `validate()` without `throw: false` raises `YorCreative\ArgonautDTO\ValidationException`.

`isValid()` returns `false` only for validation failure. A missing or broken `rules()` method is a programming error and surfaces as an exception rather than being reported as invalid data. Pass `isValid(throw: true)` to raise `ValidationException` instead of returning `false`.

Relationship to the Laravel package
-----------------------------------

[](#relationship-to-the-laravel-package)

`yorcreative/argonaut-dto` contains no Illuminate dependency. The Laravel package can provide Laravel-specific adapters and continue to expose its existing API while sharing this framework-neutral behavior. Laravel applications that need Laravel's validator or collection implementation can remain on `yorcreative/laravel-argonaut-dto`.

Testing
-------

[](#testing)

Run the test suite:

```
composer test
```

Run tests with coverage report:

```
composer coverage
```

Run static analysis (PHPStan):

```
composer phpstan
```

Run code style fixer (Pint):

```
composer lint
```

Continuous integration runs the suite on PHP 8.3, 8.4, and 8.5 against locked, lowest, and highest dependency sets, alongside PHPStan, Pint, Composer validation, dependency audits, and scheduled Composer security audits.

Credits
-------

[](#credits)

- [Yorda](https://github.com/yordadev)
- [All Contributors](../../contributors)

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance100

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/51f87d3b079a2d52ebbc2c1b71c65fe3d29717a0122436ef17f55e687ccaa1f4?d=identicon)[yordadev](/maintainers/yordadev)

---

Top Contributors

[![yordadev](https://avatars.githubusercontent.com/u/28032848?v=4)](https://github.com/yordadev "yordadev (1 commits)")

---

Tags

assemblerdata-transfer-objectdtoframework-agnosticimmutable-dtonested-dtophpphp-dtoserializationvalidationvalue-objectsphpvalidationserializationdata-transfer-objectvalue objectsdtoassemblerphp-dtonested-dtoimmutable-dto

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/yorcreative-argonaut-dto/health.svg)

```
[![Health](https://phpackages.com/badges/yorcreative-argonaut-dto/health.svg)](https://phpackages.com/packages/yorcreative-argonaut-dto)
```

###  Alternatives

[yorcreative/laravel-argonaut-dto

Argonaut is a lightweight Data Transfer Object (DTO) package for Laravel that supports nested casting, recursive serialization, and validation out of the box. Ideal for service layers, APIs, and clean architecture workflows.

1053.4k2](/packages/yorcreative-laravel-argonaut-dto)[wendelladriel/laravel-validated-dto

Data Transfer Objects with validation for Laravel applications

772649.9k18](/packages/wendelladriel-laravel-validated-dto)[fab2s/dt0

Immutable DTOs with bidirectional casting. No framework required. 8x faster than the alternative.

102.3k1](/packages/fab2s-dt0)[friendsofhyperf/validated-dto

The Data Transfer Objects with validation for Hyperf.

1514.8k](/packages/friendsofhyperf-validated-dto)[event4u/data-helpers

Framework-agnostic PHP library for data mapping, DTOs and utilities. Includes DataMapper, SimpleDto/LiteDto, DataAccessor/Mutator/Filter and helper classes (MathHelper, EnvHelper, etc.). Works with Laravel, Symfony/Doctrine or standalone PHP.

1431.1k](/packages/event4u-data-helpers)

PHPackages © 2026

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