PHPackages                             rahimi-ali/php-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. [Utility &amp; Helpers](/categories/utility)
4. /
5. rahimi-ali/php-dto

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

rahimi-ali/php-dto
==================

Data Transfer Objects for PHP

36PHP

Since Nov 7Pushed 2y ago1 watchersCompare

[ Source](https://github.com/rahimi-ali/php-dto)[ Packagist](https://packagist.org/packages/rahimi-ali/php-dto)[ RSS](/packages/rahimi-ali-php-dto/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

PHP-DTO
=======

[](#php-dto)

DTOs for PHP!
-------------

[](#dtos-for-php)

DTOs can be used to transform Incoming Psr7 server requests, json and random arrays to typed classes with validation built in.

Does not use reflection and handles everything with good old classes and methods!

### Install

[](#install)

```
composer require rahimi-ali/php-dto
```

### Types

[](#types)

- `int(bool $strict = false): IntType`
- `float(bool $strict = false): FloatType`
- `string(bool $strict = false): StringType`
- `bool(bool $strict = false): BoolType`
- `datetime(string $format = DateTimeInterface::ATOM, string|null $timezone = null, bool $immutable = true): DateTimeType`
- `embedded(string $class): EmbeddedType`
- `dynamicEmbedded(string|Closure $discriminator, array $types = []): DynamicEmbeddedType`
- `collection(TypeInterface $type): CollectionType`

### Rules

[](#rules)

- `int(bool $strict = false): IntRule` Automatically added when declaring a field with IntType
- `float(bool $strict = false): FloatRule` Automatically added when declaring a field with FloatType
- `string(bool $strict = false): StringRule` Automatically added when declaring a field with StringType
- `bool(bool $strict = false): BoolRule` Automatically added when declaring a field with BoolType
- `array(): ArrayRule` Should be an array with sequential int keys
- `object(): ObjectRule` Should be an object or an array with string keys or non-sequential int keys
- `min(int $min, bool $strict = false): MinRule`
- `max(int $max, bool $strict = false): MaxRule`
- `minLength(int $length, bool $strict = false): MinLengthRule`
- `maxLength(int $length, bool $strict = false): MaxLengthRule`
- `in(array $values, bool $strict = false): InRule`
- `notIn(array $values, bool $strict = false): NotInRule`
- `equals(mixed $value, bool $strict = false): EqualsRule`
- `notEqual(mixed $value, bool $strict = false): NotEqual`

### Example

[](#example)

```
class AddressDto extends Dto
{
    private string $city;
    private string $street;
    private int $number;

    public static function fields(array $data): array
    {
        return [
            'city' => new Field('city', Type::string(true), rules: [Rule::in(['London', 'Paris', 'New York'])]),
            'street' => new Field('street', Type::string(true), rules: [Rule::min(5)]),
            'number' => new Field('number', Type::int(true), rules: [Rule::min(1), Rule::max(100)]),
        ];
    }

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

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

    public function getNumber(): int
    {
        return $this->number;
    }
}

class UserDto extends Dto
{
    private string $name;
    private int $age;
    private AddressDto $address;

    public static function fields(array $data): array
    {
        return [
            'name' => new Field('name', Type::string(true), rules: [Rule::min(5)]),
            'age' => new Field('age', Type::int(true), rules: [Rule::min(18)]),
            'address' => new Field('address', Type::embedded(AddressDto::class)),
        ];
    }

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

    public function getAge(): int
    {
        return $this->age;
    }

    public function getAddress(): AddressDto
    {
        return $this->address;
    }
}
```

### Notes

[](#notes)

- Because reflection and magic methods were not used private and readonly properties cannot be used because the parent class cannot access them by default. If you really want private and readonly properties, override the `setProperty` method in you DTO:

```
protected function setProperty(string $property, mixed $value): void
{
    $this->{$property} = $value;
}
```

### Standards

[](#standards)

- Code Coverage: 100%
- PHPStan Level: 9
- Infection MSI: 94%

### License

[](#license)

MIT

###  Health Score

14

—

LowBetter than 2% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity20

Early-stage or recently created project

 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/42c1ae12253ddf22f4484465431c4066b57e307278fdfd189b3a6f1eea019b90?d=identicon)[ali-rahimi](/maintainers/ali-rahimi)

---

Top Contributors

[![rahimi-ali](https://avatars.githubusercontent.com/u/33478509?v=4)](https://github.com/rahimi-ali "rahimi-ali (12 commits)")

---

Tags

backendfoundationphp

### Embed Badge

![Health badge](/badges/rahimi-ali-php-dto/health.svg)

```
[![Health](https://phpackages.com/badges/rahimi-ali-php-dto/health.svg)](https://phpackages.com/packages/rahimi-ali-php-dto)
```

###  Alternatives

[lackhurt/laravel-apollo

Apollo agent for laravel.

135.1k](/packages/lackhurt-laravel-apollo)[elegantly/laravel-settings

Settings for your Laravel App

101.7k](/packages/elegantly-laravel-settings)

PHPackages © 2026

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