PHPackages                             lucifer07/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. lucifer07/php-dto

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

lucifer07/php-dto
=================

Swift and efficient PHP Data Transfer Object package with constructor-promoted properties, auto-mapping, and built-in serialization

00PHP

Since Feb 4Pushed 3mo agoCompare

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

READMEChangelogDependenciesVersions (1)Used By (0)

PHP DTO
=======

[](#php-dto)

Lightweight and efficient PHP Data Transfer Object package with constructor-promoted properties, auto-mapping, and built-in serialization.

Features
--------

[](#features)

- **Type-Safe**: Uses constructor-promoted properties with full type hints
- **Auto-Mapping**: Automatic mapping between snake\_case and camelCase
- **Nested DTOs**: Full support for nested DTO objects
- **Custom Mapping**: Use `MapFrom` attribute for custom field mappings
- **Type Casting**: Automatic type casting for int, float, bool, DateTime, array
- **Zero Dependencies**: No external dependencies
- **PHP 8.1+**: Modern PHP features
- **Fast**: ~25% faster than traditional reflection-based DTOs

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

[](#installation)

```
composer require lucifer07/php-dto
```

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

[](#requirements)

- PHP 8.1 or higher

Quick Start
-----------

[](#quick-start)

### Basic Usage

[](#basic-usage)

Define your DTO class by extending the base `DTO` class:

```
use SwiftDTO\DTO;

class UserDTO extends DTO
{
    public function __construct(
        public string $fullName,
        public int $age,
        public bool $isActive,
        public \DateTimeImmutable $createdAt
    ) {}
}
```

Create DTO from array (auto-mapping from snake\_case):

```
$user = UserDTO::fromArray([
    'full_name' => 'John Doe',
    'age' => 30,
    'is_active' => 'true',
    'created_at' => '2023-10-01 10:00:00'
]);

echo $user->fullName; // 'John Doe'
echo $user->age; // 30
echo $user->isActive; // true
```

### Convert to Array

[](#convert-to-array)

```
$array = $user->toArray();
// Returns: ['full_name' => 'John Doe', 'age' => 30, 'is_active' => true, 'created_at' => '2023-10-01T10:00:00+07:00']
```

### Convert to JSON

[](#convert-to-json)

```
$json = json_encode($user, JSON_PRETTY_PRINT);
// Returns: JSON object with snake_case keys
```

Features in Detail
------------------

[](#features-in-detail)

### Auto-Mapping

[](#auto-mapping)

The DTO automatically maps between snake\_case (array keys) and camelCase (property names):

```
// Both work the same
$user1 = UserDTO::fromArray(['full_name' => 'John']);
$user2 = UserDTO::fromArray(['fullName' => 'John']);
```

### Custom Mapping with MapFrom

[](#custom-mapping-with-mapfrom)

Use the `MapFrom` attribute for custom field mappings:

```
use SwiftDTO\DTO;
use SwiftDTO\MapFrom;

class UserDTO extends DTO
{
    public function __construct(
        #[MapFrom('user_id')]
        public readonly int $id,

        #[MapFrom('user_name')]
        public readonly string $username,

        public string $email
    ) {}
}

$user = UserDTO::fromArray([
    'user_id' => 123,
    'user_name' => 'johndoe',
    'email' => 'john@example.com'
]);

echo $user->id; // 123
echo $user->username; // 'johndoe'
```

### Type Casting

[](#type-casting)

The DTO automatically casts values to the correct type:

```
$user = UserDTO::fromArray([
    'full_name' => 'John Doe',
    'age' => '30',          // string to int
    'is_active' => 'yes',    // string to bool
    'created_at' => '2023-10-01 10:00:00'  // string to DateTimeImmutable
]);

assert(is_int($user->age)); // true
assert(is_bool($user->isActive)); // true
assert($user->createdAt instanceof \DateTimeImmutable); // true
```

### Nested DTOs

[](#nested-dtos)

Full support for nested DTOs:

```
class AddressDTO extends DTO
{
    public function __construct(
        public string $street,
        public string $city,
        public string $country
    ) {}
}

class UserDTO extends DTO
{
    public function __construct(
        public string $name,
        public string $email,
        public AddressDTO $address
    ) {}
}

$user = UserDTO::fromArray([
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'address' => [
        'street' => '123 Main St',
        'city' => 'New York',
        'country' => 'USA'
    ]
]);

echo $user->address->city; // 'New York'
```

### Optional Fields and Default Values

[](#optional-fields-and-default-values)

Define optional fields with default values:

```
class ProductDTO extends DTO
{
    public function __construct(
        public string $name,
        public float $price,
        public bool $inStock,
        public string $category = 'general',
        public int $stockLevel = 0
    ) {}
}

$product = ProductDTO::fromArray([
    'name' => 'Widget',
    'price' => 19.99,
    'in_stock' => true
]);

echo $product->category; // 'general' (default)
echo $product->stockLevel; // 0 (default)
```

### Nullable Fields

[](#nullable-fields)

Use nullable types for optional fields:

```
class UserDTO extends DTO
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $address = null
    ) {}
}

$user = UserDTO::fromArray([
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

echo $user->address; // null
```

### Read-Only Properties

[](#read-only-properties)

Use `readonly` for immutable properties:

```
class UserDTO extends DTO
{
    public function __construct(
        public readonly int $id,
        public string $name,
        public string $email
    ) {}
}

$user = UserDTO::fromArray([
    'id' => 123,
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

// $user->id = 456; // Error: Cannot modify readonly property
```

Examples
--------

[](#examples)

Complete examples are available in the `examples/` directory:

- `basic_usage.php` - Basic DTO creation and serialization
- `nested_dtos.php` - Working with nested data structures
- `validation.php` - Type safety and default values
- `map_from.php` - Custom field mapping
- `collections.php` - Working with arrays and collections
- `serialization.php` - Serialization methods

Run any example:

```
php examples/basic_usage.php
php examples/nested_dtos.php
php examples/index.php  # Show all examples
```

API Reference
-------------

[](#api-reference)

### Methods

[](#methods)

#### `static fromArray(array $data): static`

[](#static-fromarrayarray-data-static)

Create DTO instance from array.

```
$user = UserDTO::fromArray(['name' => 'John', 'age' => 30]);
```

#### `toArray(): array`

[](#toarray-array)

Convert DTO to array with snake\_case keys.

```
$array = $user->toArray();
```

#### `jsonSerialize(): array`

[](#jsonserialize-array)

Implements `JsonSerializable` interface for JSON encoding.

```
$json = json_encode($user);
```

Type Casting Rules
------------------

[](#type-casting-rules)

Target TypeSource ValueResult`int``'30'``30``float``'19.99'``19.99``bool``'true'`, `'yes'`, `'on'`, `'1'``true``bool``'false'`, `'no'`, `'off'`, `'0'`, `''``false``DateTimeImmutable``'2023-10-01 10:00:00'`DateTime object`array``'["a", "b"]'` (JSON string)`['a', 'b']`Validation
----------

[](#validation)

Required fields without default values must be provided:

```
class UserDTO extends DTO
{
    public function __construct(
        public string $name,  // Required
        public string $email  // Required
    ) {}
}

// This will throw InvalidArgumentException
$user = UserDTO::fromArray(['name' => 'John']);
// Missing required parameter: email
```

Performance
-----------

[](#performance)

Benchmark results (10,000 iterations, median):

OperationNEW DTOOLD DTOSpeedupsnake\_case creation19.07 μs23.90 μs1.25xcamelCase creation18.44 μs24.00 μs1.30xserialization6.88 μs6.33 μs0.92xfull cycle25.33 μs30.13 μs1.19xTesting
-------

[](#testing)

Run the test suite:

```
composer test
```

Or directly with PHPUnit:

```
./vendor/bin/phpunit
```

License
-------

[](#license)

MIT

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance54

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

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/d8bb74f9b8ca74edb590bc5c9f0673b1e2cfebe3b1bc3241e0ed489b7941d4f3?d=identicon)[Lucifer07](/maintainers/Lucifer07)

### Embed Badge

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

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

###  Alternatives

[harmonic/laravel-envcoder

:description

414.1k](/packages/harmonic-laravel-envcoder)

PHPackages © 2026

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