PHPackages                             bfg/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. [Templating &amp; Views](/categories/templating)
4. /
5. bfg/dto

ActiveLibrary[Templating &amp; Views](/categories/templating)

bfg/dto
=======

The data transfer object pattern for Laravel

v1.9.0(4mo ago)0589—8.3%1MITPHPPHP ^8.0

Since Dec 5Pushed 4mo ago2 watchersCompare

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

READMEChangelogDependencies (1)Versions (18)Used By (1)

Dto
===

[](#dto)

[![Latest Stable Version](https://camo.githubusercontent.com/bfae652ff4ecf5dc975009ce4806d5ac0be7027c4b94e7efa948f3f4355d1087/68747470733a2f2f706f7365722e707567782e6f72672f6266672f64746f2f76657273696f6e2e737667)](https://packagist.org/packages/bfg/dto)[![License](https://camo.githubusercontent.com/b6388db813f9c241b30d28cca15469862790d970fd94be4698eaef183e080608/68747470733a2f2f706f7365722e707567782e6f72672f6266672f64746f2f6c6963656e73652e737667)](https://packagist.org/packages/bfg/dto)[![Downloads](https://camo.githubusercontent.com/d8f53b949d59bb02364d9662217f8043de2ee731a4de702eb6e4b9252e1c84ab/68747470733a2f2f706f7365722e707567782e6f72672f6266672f64746f2f642f746f74616c2e737667)](https://packagist.org/packages/bfg/dto)

The data transfer object pattern

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

[](#installation)

```
composer require bfg/dto
```

after install your can create a new dto by use this command

```
php artisan make:dto UserDto
```

Usage
-----

[](#usage)

- [Introduction](#introduction)
- [First steps](#first-steps)
- [Constructors](#constructors)
    - [from](#from)
    - [fromEmpty](#fromempty)
    - [fromArray](#fromarray)
    - [fromDto](#fromdto)
    - [fromFluent](#fromfluent)
    - [fromUrl](#fromurl)
    - [fromGet](#fromget)
    - [fromPost](#frompost)
    - [fromHttp](#fromhttp)
    - [fromRequest](#fromrequest)
    - [fromJson](#fromjson)
    - [fromSerialize](#fromserialize)
    - [fromModel](#frommodel)
    - [fromStaticCache](#fromstaticcache)
    - [fromCollection](#fromcollection)
    - [fromCache](#fromcache)
    - [fromString](#fromstring)
- [Nested DTO calls](#nested-dto-calls)
- [Binding](#binding)
    - [Binding to the model](#binding-to-the-model)
    - [Binding to the Carbon](#binding-to-the-carbon)
- [Property extends](#property-extends)
- [Property casting](#property-casting)
- [Property hidden](#property-hidden)
- [Property rules](#property-rules)
- [Property encrypted](#property-encrypted)
- [Computed properties](#computed-properties)
- [Lazy properties](#lazy-properties)
- [Method property access](#method-property-access)
- [Collection hinting](#collection-hinting)
- [Property by method with](#property-by-method-with)
- [Property logsEnabled](#property-logsenabled)
- [Meta](#meta)
- [HasDtoTrait](#hasdtotrait)
- [Attributes](#attributes)
    - [DtoAuthenticatedUser](#dtoauthenticateduser)
    - [DtoCast](#dtocast)
    - [DtoClass](#dtoclass)
    - [DtoExceptProperty](#dtoexceptproperty)
    - [DtoFromCache](#dtofromcache)
    - [DtoFromConfig](#dtofromconfig)
    - [DtoFromRequest](#dtofromrequest)
    - [DtoFromRoute](#dtofromroute)
    - [DtoItem](#dtoitem)
    - [DtoMapApi](#dtomapapi)
    - [DtoMapFrom](#dtomapfrom)
    - [DtoMapTo](#dtomapto)
    - [DtoMutateFrom](#dtomutatefrom)
    - [DtoMutateTo](#dtomutateto)
    - [DtoToResource](#dtotoresource)
- [Events](#events)
    - [creating](#creating)
    - [created](#created)
    - [updating](#updating)
    - [updated](#updated)
    - [mutating](#mutating)
    - [mutated](#mutated)
    - [serialize](#serialize)
    - [unserialize](#unserialize)
    - [clone](#clone)
    - [fromModel](#fromModel)
    - [fromEmpty](#fromEmpty)
    - [fromArray](#fromArray)
    - [fromRequest](#fromRequest)
    - [fromJson](#fromJson)
    - [fromSerialize](#fromSerialize)
    - [prepareModel](#prepareModel)
    - [prepareSerialize](#prepareSerialize)
    - [prepareJson](#prepareJson)
    - [prepareRequest](#prepareRequest)
    - [prepareArray](#prepareArray)
- [Reflection](#reflection)
    - [explain](#explain)
    - [vars](#vars)
    - [getModifiedFields](#getmodifiedfields)
    - [getRelationNames](#getrelationnames)
    - [getPropertyNames](#getpropertynames)
    - [getNames](#getnames)
    - [getReflection](#getreflection)
- [Convert DTO to](#convert-dto-to)
    - [ToArray](#toarray)
    - [ToJson](#tojson)
    - [ToResponse](#toresponse)
    - [ToCollection](#tocollection)
    - [ToBase64](#tobase64)
    - [ToModel](#tomodel)
    - [ToSerialize](#toserialize)
    - [ToString](#tostring)
    - [ToFluent](#tofluent)
    - [ToImport](#toimport)
    - [ToUrl](#tourl)
- [DTO Collection](#dto-collection)
    - [insertToDatabase](#inserttodatabase)
    - [insertToModel](#inserttomodel)
- [Commands](#commands)
    - [make:dto-cast](#makedto-cast)
    - [make:enum](#makeenum)
    - [make:dto-docs](#makedto-docs)
- [Dto like model cast](#dtolikemodelcast)
- [Helpers](#helpers)
- [Customize http request](#customize-http-request)
- [Default Laravel Support](#default-laravel-support)

### Introduction

[](#introduction)

#### Variety of constructs for creating DTOs

[](#variety-of-constructs-for-creating-dtos)

The package provides a variety of methods for creating DTOs (Data Transfer Objects), which significantly improves flexibility. Methods such as fromArray, fromModel, fromRequest, fromJson, fromSerialize and others allow you to conveniently create DTOs from different data sources.

#### Support for nested DTOs

[](#support-for-nested-dtos)

The package supports nested DTOs with typing, which makes it easy to work with complex data, such as addresses or comments in the user example. This simplifies data processing in cases with dependencies between objects.

#### Rich customization of properties

[](#rich-customization-of-properties)

Support for data casting, such as datetime, bool, as well as property extension through methods and attributes, such as DtoMapFrom, DtoFromConfig, DtoFromRequest are useful and powerful tools that make DTOs even more versatile.

#### Diving into events

[](#diving-into-events)

The ability to handle various events (creating, created, mutating and others) provides greater flexibility in managing the state of the DTO. This can be useful for implementing validation logic or transforming data before or after it is used.

#### DTO Collections Support

[](#dto-collections-support)

Including support for DTO collections with methods for saving them to the database or models is a great addition that makes it easier to work with multiple objects.

#### Additional Features

[](#additional-features)

Convenient helpers for working with DTOs, such as validate, restore, cache, as well as methods for working with metadata and logs, make this package a great tool for organizing the data structure in large projects.

#### Ease of Use

[](#ease-of-use)

The ease of creating DTOs via the php artisan make:dto command and obvious typing of properties make the package developer-friendly, ensuring both clean code and good integration with the Laravel framework.

Overall, this package looks like a powerful tool for structuring data in Laravel, suitable for use in projects with large amounts of data and complex models. Everything looks logical and flexible, which allows you to quickly adapt it to various needs.

### First steps

[](#first-steps)

Before you can use the DTO, you need to create a new class that extends the `Bfg\Dto\Dto` class. All you dto properties must be public and have a type hint. Also you must use the constructor for the DTO. And you can use the dependency injection in the constructor.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected array $hidden = [
        'password'
    ];

    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}
}
```

After creating the DTO, you can use it in your code.

```
$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);
// Or
$dto = UserDto::new(
    name: 'John Doe',
    email: 'test@gmail.com',
    password: '123456'
);

echo $dto->name; // John Doe
```

### Constructors

[](#constructors)

#### from

[](#from)

You can create a new DTO from anything.

```
$dto = UserDto::from(['name' => 'John Doe', 'email' => 'test@gmail.com']);
$dto = UserDto::from([
    ['name' => 'John Doe', 'email' => 'test@gmail.com'],
    ['name' => 'John Doe', 'email' => 'test@gmail.com'],
]);
$dto = UserDto::from(\Illuminate\Foundation\Http\FormRequest::class);
$dto = UserDto::from('{"name":"John Doe","email":"test@gmail.com"}');
$dto = UserDto::from('C:8:"UserDto":23:{a:2:{s:4:"name";s:8:"John Doe";s:5:"email";s:13:"test@gmail.com";}}');
$dto = UserDto::from(User::find(1));
```

#### fromEmpty

[](#fromempty)

You can create a new DTO with empty properties.

```
$dto = UserDto::fromEmpty();
```

#### fromArray

[](#fromarray)

You can create a new DTO from an array.

```
$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
]);
```

#### fromDto

[](#fromdto)

You can create a new DTO from another DTO.

```
$firstDto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
]);

$secondDto = UserDto::fromDto($firstDto);
// Creates a new DTO with the same properties as the first DTO
```

#### fromFluent

[](#fromfluent)

You can create a new DTO from a fluent object.

```
$fluent = (new \Illuminate\Support\Fluent([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
]))->set('password', '123456');

$dto = UserDto::fromFluent($fluent);
```

#### fromUrl

[](#fromurl)

You can create a new DTO from the URL.

```
UserDto::fromUrl(string $url, array|string|null $query = null, array $headers = []);
UserDto::fromUrl('https://test.dev');
```

#### fromGet

[](#fromget)

You can create a new DTO from the get request.

```
$dto = UserDto::fromGet(string $url, array|string|null $query = null, array $headers = []);

UserDto::fromGet('https://test.dev', ['name' => 'John Doe', 'email' => 'test@gmail.com']);
```

#### fromPost

[](#frompost)

You can create a new DTO from the post request.

```
$dto = UserDto::fromPost(string $url, array $data = [], array $headers = []);

UserDto::fromPost('https://test.dev', ['name' => 'John Doe', 'email' => 'test@gmail.com']);
```

#### fromHttp

[](#fromhttp)

You can create a new DTO from the http request.

```
$dto = UserDto::fromHttp(string $method, string $url, array|string|null $data = [], array $headers = []): DtoCollection|static|null;

UserDto::fromHttp('get', 'https://test.dev', ['name' => 'John Doe', 'email' => 'test@gmail.com']);
```

#### fromRequest

[](#fromrequest)

You can create a new DTO from the request.

```
$dto = UserDto::fromRequest(\Illuminate\Foundation\Http\FormRequest::class);
```

#### fromJson

[](#fromjson)

You can create a new DTO from json.

```
$dto = UserDto::fromJson('{"name":"John Doe","email":"test@gmail.com"}');
```

#### fromSerialize

[](#fromserialize)

You can create a new DTO from serialize.

```
$dto = UserDto::fromSerialize('C:8:"UserDto":23:{a:2:{s:4:"name";s:8:"John Doe";s:5:"email";s:13:"test@gmail.com";}}');
```

#### fromModel

[](#frommodel)

You can create a new DTO from model.

```
$dto = UserDto::fromModel(User::find(1));
```

#### fromStaticCache

[](#fromstaticcache)

You can create a new DTO from static cache.

```
$dto = UserDto::fromStaticCache('user', function () {
    return UserDto::fromArray([
        'name' => 'John Doe',
        'email' => 'test@gmail.com',
    ]);
});
```

#### fromCollection

[](#fromcollection)

You can create a new DTO from collection.

```
$collection = UserDto::fromCollection([
    ['name' => 'John Doe', 'email' => 'test@gmail.com'],
    ['name' => 'Sam Doe', 'email' => 'test2@gmail.com'],
]);
```

#### fromCache

[](#fromcache)

You can create a new DTO from cache.

```
// You can cache dto before
$dto->cache();

$dto = UserDto::fromCache(function () {
    // If cache not found
    return UserDto::fromArray([
        'name' => 'John Doe',
        'email' => 'test@gmail.com',
    ]);
});
```

#### fromString

[](#fromstring)

You can create a new DTO from string.

```
$dto = UserDto::fromString('John Doe|test@gmail.com', '|');
```

#### fromSource

[](#fromsource)

You can create a new DTO from source.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}

    public static function sourceV1(...$arguments): array {

        // Do something

        return [
            'name' => 'John Doe',
            'email' => 'test@gmail.com',
            'password' => '123456',
        ];
    }
}
```

And after that you can create a new DTO from source.

```
$dto = UserDto::fromSource('v1', ...$arguments);
```

### Nested DTO calls

[](#nested-dto-calls)

For nested DTO calls, you can use type hinting.

```
use Bfg\Dto\Dto;

class AddressDto extends Dto
{
    public function __construct(
        public string $city,
        public string $street,
    ) {}
}

class CommentDto extends Dto
{
    public function __construct(
        public string $message,
    ) {}
}

class UserDto extends Dto
{
    protected array $hidden = [
        'password'
    ];

    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        public AddressDto $address,
        public CommentDto|array $comments,
    ) {}
}
```

Now you can use nested DTOs.

```
$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
    'address' => [
        'city' => 'New York',
        'street' => 'Wall Street',
    ],
    'comments' => [
        ['message' => 'The first comment'],
        ['message' => 'The second comment'],
    ]
]);

echo $dto->address->city; // New York
// And
foreach ($dto->comments as $comment) {
    echo $comment->message;
}
```

### Binding

[](#binding)

You can use binding for the DTO.

#### Binding to the model

[](#binding-to-the-model)

You can bind the DTO property to the model.

```
use Bfg\Dto\Dto;
use App\Models\User;
use Bfg\Dto\Attributes\DtoMapFrom;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        #[DtoMapFrom('user_id')]
        public ?User $user,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'user_id' => 1,
    // Or
    'user' => 1,
]);

dump($dto->user); // User model
// In Array you will get the id of the model
dump($dto->toArray()); // ['name' => 'John Doe', 'email' => 'test@gmail.com', 'user_id' => 1]
```

If model User with id `1` exists, it will be bound to the DTO property. If not, the property will be null.

#### Binding to the Carbon

[](#binding-to-the-carbon)

You can bind the DTO property to the Carbon. Default format for the Carbon is `Y-m-d H:i:s`. You can change the format using the `$dateFormat` property.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public \Carbon\Carbon $created_at,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'created_at' => '2025-01-01 00:00:00',
]);

dump($dto->created_at); // Carbon object
// In Array you will get the date in the format `Y-m-d H:i:s`
dump($dto->toArray()); // ['name' => 'John Doe', 'email' => 'test@gmail.com', 'created_at' => '2025-01-01 00:00:00']
```

### Property extends

[](#property-extends)

You can use property extends for extending the DTO.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $email,
        public ?string $password,
    ) {}
}
```

```
class SpecialUserDto extends UserDto
{
    protected static array $extends = [
        'name' => 'string|null',
        // Or
        'name' => ['string', 'null'],
    ];
}
```

This way you will expand the properties for DTO.

All properties have identical behavior to properties in the property promotion constructor.

### Property casting

[](#property-casting)

You can use property casting like in Laravel models.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected static array $casts = [
        'is_admin' => 'bool',
        'created_at' => 'datetime',
    ];

    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        public bool $is_admin,
        public \Carbon\Carbon $created_at,
    ) {}
}
```

Also, this casting support class casting. You can create a new class casting using the artisan command:

```
php artisan make:dto-cast UserNameCast
```

After creating the class casting, you can use it in the DTO.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected static array $casts = [
        'is_admin' => 'bool',
        'created_at' => 'datetime',
        'name' => UserNameCast::class,
    ];
}
```

And casting support enum casting. You can create a new enum casting using the artisan command:

```
php artisan make:enum UserStatusEnum
```

After creating the enum casting, you can use it in the DTO.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected static array $casts = [
        'is_admin' => 'bool',
        'created_at' => 'datetime',
        'name' => UserNameCast::class,
        'status' => UserStatusEnum::class,
    ];
}
```

### Property hidden

[](#property-hidden)

You can use property hidden like in Laravel models.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected array $hidden = [
        'password'
    ];

    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
]);

echo $dto->toArray(); // ['name' => 'John Doe', 'email' => 'test@gmail.com']
```

### Property rules

[](#property-rules)

You can use property rules like in Laravel requests.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected static array $rules = [
        'name' => 'required|string',
        'email' => 'required|email',
        'password' => 'required|string|min:6',
    ];

    protected static array $ruleMessages = [
        'name.required' => 'The name field is required.',
        'email.required' => 'The email field is required.',
        'password.required' => 'The password field is required.',
    ];

    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
]); // Throws an exception
```

### Property encrypted

[](#property-encrypted)

You can use property encrypted for getting encrypted data.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected array $encrypted = [
        'password'
    ];

    public function __construct(
        public string $name,
        public string $email,
        public string $password, // Data will be decrypted
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => \Illuminate\Support\Facades\Crypt::encrypt('123456'),
]);

echo $dto->password; // You will get decrypted password

dump($dto->toArray()); // ['name' => 'John Doe', 'email' => 'test@gmail.com', 'password' => 'encrypted data']
```

### Computed properties

[](#computed-properties)

You can use computed properties.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $lastName,
        public string $email,
        public ?string $password,
    ) {}

    public function fullName(): string
    {
        return $this->name . ' ' . $this->lastName;
    }
}
```

Now you can use computed properties.

```
$dto = UserDto::fromArray([
    'name' => 'John',
    'lastName' => 'Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->fullName; // John Doe
```

### Lazy properties

[](#lazy-properties)

You can use lazy like properties any property or computed property. If you add the prefix "lazy" before the name of a property or a computed property, you will get access to lazy execution. When you request a property, the value that this property receives is cached and all subsequent times the result for the lazy property is taken from the cache and if in DTO the property changes, then in Lazy it will remain the same since it is taken from the cache.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $lastName,
        public string $email,
        public ?string $password,
    ) {}

    public function fullName(): string
    {
        return $this->name . ' ' . $this->lastName;
    }
}

$dto = UserDto::fromArray([
    'name' => 'John',
    'lastName' => 'Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->lazyEmail; // test@gmail.com
echo $dto->lazyFullName; // John Doe, and it put in the cache
$dto->set('name', 'Sam');
echo $dto->lazyFullName; // John Doe, because it is taken from the cache
```

### Method property access

[](#method-property-access)

You can use the method property access.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
]);

echo $dto->name(); // John Doe
// The same as
echo $dto->get('name'); // John Doe
```

### Method default for field

[](#method-default-for-field)

You can use the `default` method for setting the default value for the field.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}

    public static function defaultName()
    {
        return 'Jon';
    }
}
```

After that, you can escape the name field when creating a DTO.

```
$dto = UserDto::fromArray([
    'email' => 'test@gmail.com',
    'password' => '123456',
]);

echo $dto->name; // Jon
```

### Collection hinting

[](#collection-hinting)

You can use collection hinting.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        public AddressDto|array $address,
        // Or
        public AddressDto|\Illuminate\Support\Collection $address,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
    'address' => [
        ['city' => 'New York', 'street' => 'Wall Street'],
        ['city' => 'Los Angeles', 'street' => 'Hollywood Street'],
    ]
]);

foreach ($dto->address as $address) {

    echo $address->city;
}
```

#### Property by method with

[](#property-by-method-with)

You can use the `with...` method for adding data to the DTO array.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $lastName,
        public string $email,
        public ?string $password,
    ) {}

    public function withFullName(): string
    {
        return $this->name . ' ' . $this->lastName;
    }
}

$dto = UserDto::fromArray([
    'name' => 'John',
    'lastName' => 'Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

dump($dto->toArray()); // ['name' => 'John', 'lastName' => 'Doe', 'email' => 'test@gmail.com', 'password' => '123456', 'fullName' => 'John Doe']
```

#### Property logsEnabled

[](#property-logsenabled)

You can use property logsEnabled for logging data in the DTO memory.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected static bool $logsEnabled = true;

    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
]);

$dto->set('name', 'Sam Doe');

dump($dto->logs()); // You will get logs DTO
```

You can write your own logs to the DTO memory using the `log` method.

```
$dto->log(string $message, array $context = []);
```

### Meta

[](#meta)

You can use meta.

```
$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
]);

$dto->setMeta(['key' => 'value']);
$dto->setMeta(['key2' => 'value2']);
echo $dto->getMeta('key'); // value
echo $dto->getMeta('key2'); // value2
// You can get all meta
dump($dto->getMeta()); // ['key' => 'value', 'key2' => 'value2']
// You can remove meta
$dto->unsetMeta('key');
```

### HasDtoTrait

[](#hasdtotrait)

You can use the `HasDtoTrait` trait in your model or request to use the DTO.

```
use Bfg\Dto\HasDtoTrait;
use Bfg\Dto\Attributes\DtoClass;

#[DtoClass(UserDto::class)]
class User extends Model
{
    /** @use HasDtoTrait */
    use HasDtoTrait;
}
```

After that, you can use the DTO in your model.

```
$user = User::find(1);
$dto = $user->getDto(); // UserDto object
```

### Attributes

[](#attributes)

You can use attributes.

#### DtoItem

[](#dtoitem)

You can set `DTO` for `Collection` property

```
class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        #[\Bfg\Dto\Attributes\DtoItem(UserContactDto::class)]
        public \Bfg\Dto\Collections\DtoCollection $contacts,
    ) {}
}
```

#### DtoMapApi

[](#dtomapapi)

You can use the `DtoMapApi` attribute for converting the DTO keys to the API camel case.

```
use Bfg\Dto\Dto;
use Bfg\Dto\Attributes\DtoMapApi;

class UserDto extends Dto
{
    public function __construct(
        #[DtoMapApi]
        public string $userName,
        #[DtoMapApi]
        public string $userEmail,
        public ?string $password,
    ) {}
}

$dto = UserDto::fromArray([
    'user_name' => 'John Doe',
    'user_email' => 'test@gmail.com',
    'password' => '123456',
]);

echo $dto->userName; // John Doe

$dto->toArray(); // ['user_name' => 'John Doe', 'user_email' => 'test@gmail.com', 'password' => '123456']
```

#### DtoAuthenticatedUser

[](#dtoauthenticateduser)

You can use the `DtoAuthenticatedUser` attribute to set the authenticated user for the DTO.

```
use Bfg\Dto\Dto;

class UserSettingsDto extends Dto
{
    public function __construct(
        #[\Bfg\Dto\Attributes\DtoAuthenticatedUser]
        public \App\Models\User $user,
        #[\Bfg\Dto\Attributes\DtoMapApi]
        public bool $receiveNotifications,
        #[\Bfg\Dto\Attributes\DtoMapApi]
        public bool $darkMode,
    ) {}
}

$dto = UserSettingsDto::fromAssoc([
    'receive_notifications' => true,
    'dark_mode' => false,
]);

$dto->user; // Will return the authenticated user model
```

#### DtoCast

[](#dtocast)

You can use the `DtoCast` attribute to set the DTO for the property.

```
use Bfg\Dto\Dto;
use Bfg\Dto\Attributes\DtoCast;

class UserPhoneDto extends Dto
{
    public function __construct(
        #[DtoCast('int')] public int $number,
    ) {}
}

UserPhoneDto::fromArray([
    'number' => '1234567890',
]);
```

> Attention! If you do not specify the property casting, then, when you try to assign a different type to the property, there will be a PHP error that will say that you are trying to assign a different type than expected.

#### DtoClass

[](#dtoclass)

You can use the `DtoClass` attribute to set the DTO for the class.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}
}

#[\Bfg\Dto\Attributes\DtoClass(UserDto::class)]
class User extends Model
{
    /** @use \Bfg\Dto\Traits\Support\HasDtoTrait */
    use \Bfg\Dto\Traits\Support\HasDtoTrait;
}

// Now you can use the DTO in the model
$user = User::find(1);
$dto = $user->getDto(); // UserDto object
```

#### DtoExceptProperty

[](#dtoexceptproperty)

You can use the `DtoExceptProperty` attribute to exclude the property from the DTO.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        #[\Bfg\Dto\Attributes\DtoExceptProperty]
        public ?string $password, // This property will be excluded from the DTO
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
]);

echo $dto->toArray(); // ['name' => 'John Doe', 'email' => 'test@gmail.com']
```

#### DtoItem

[](#dtoitem-1)

You can use the `DtoItem` attribute to set the DTO for the collection property.

```
use Bfg\Dto\Dto;
use Bfg\Dto\Attributes\DtoItem;
use Bfg\Dto\Collections\DtoCollection;

class UserContactDto extends Dto
{
    public function __construct(
        #[DtoItem(UserPhoneDto::class)] public DtoCollection $phones,
        #[DtoItem(UserEmailDto::class)] public DtoCollection $emails,
    ) {}
}
```

#### DtoMapFrom

[](#dtomapfrom)

You can use the `DtoMapFrom` attribute to add the name of the DTO.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        #[DtoMapFrom('user')]
        public string $name,
        #[DtoMapFrom('contacts.email'), DtoMapTo('contacts.email')]
        public string $email,
        public ?string $password,
    ) {}
}

$dto = UserDto::fromArray([
    'user' => 'John Doe',
    'contacts' => [
        'email' => 'test@gmail.com',
    ],
    'password' => '123456'
]);
// Or
$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->name; // John Doe
```

Here we have added a field name to the "name" field and we can now use two fields to insert data.

For property extends:

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    #[DtoMapFrom('user', 'name')]
    protected static array $extends = [
        'name' => 'string',
    ];

    public function __construct(
        public string $email,
        public ?string $password,
    ) {}
}
```

Since we cannot write an attribute to a separate element of the array, we need to specify the name of the field to which we need to assign an additional name as the second parameter.

#### DtoMapTo

[](#dtomapto)

You can use the `DtoMapTo` attribute to add the name of the DTO.

```
use Bfg\Dto\Dto;
class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        #[\Bfg\Dto\Attributes\DtoMapTo('user_emails.email1'), \Bfg\Dto\Attributes\DtoMapFrom('email')]
        public string $userEmail,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->userEmail;

$dto->toArray(); // ['name' => 'John Doe', 'email' => 'test@gmail.com', 'password' => '123456', 'user_emails' => ['email1' => 'test@gmail.com']]
```

#### DtoMutateFrom

[](#dtomutatefrom)

You can use the `DtoMutateFrom` attribute to mutate the property value from any to the DTO.

```
use Bfg\Dto\Dto;

class SettingsDto extends Dto
{
    public function __construct(
        #[\Bfg\Dto\Attributes\DtoMutateFrom('mutateStringBoolean')]
        public bool $receiveNotifications,
    ) {}

    public static function mutateStringBoolean(mixed $value): bool
    {
        return is_string($value)
            ? trim(strtolower($value)) === 'true'
            : (bool) $value;
    }
}

$dto = SettingsDto::fromArray([
    'receive_notifications' => 'true', // Will be mutated to true
]);

echo $dto->receiveNotifications; // true
```

#### DtoMutateTo

[](#dtomutateto)

You can use the `DtoMutateTo` attribute to mutate the property value to any type from the DTO.

```
use Bfg\Dto\Dto;

class SettingsDto extends Dto
{
    public function __construct(
        #[\Bfg\Dto\Attributes\DtoMutateTo('mutateBooleanString'), \Bfg\Dto\Attributes\DtoMapApi]
        public bool $receiveNotifications,
    ) {}

    public static function mutateBooleanString(mixed $value): string
    {
        return $value ? 'true' : 'false';
    }
}

$dto = SettingsDto::fromArray([
    'receive_notifications' => true,
]);

echo $dto->receiveNotifications; // true

$dto->toArray() // ['receive_notifications' => 'true']
```

#### DtoFromConfig

[](#dtofromconfig)

You can use the `DtoFromConfig` attribute to add the property value from the config.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        #[DtoFromConfig('app.name')]
        public string $appName,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->appName; // Laravel
```

#### DtoFromRequest

[](#dtofromrequest)

You can use the `DtoFromRequest` attribute to add the property value from the request.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        #[DtoFromRequest]
        public string $id,
    ) {}
}

// https://test.dev/?id=100

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->id; // 100
```

#### DtoFromRoute

[](#dtofromroute)

You can use the `DtoFromRoute` attribute to add the property value from the route.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        #[DtoFromRoute]
        public string $id,
    ) {}
}

// Route::get('/{id}', function ($id) {});

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->id; // 100
```

#### DtoFromCache

[](#dtofromcache)

You can use the `DtoFromCache` attribute to add the property value from the cache.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,

        #[DtoFromCache('user')]
        public string $userFromCache,
        // Or
        #[DtoFromCache]
        public string $user,
    ) {}
}

Cache::put('user', 'John Doe', 60);

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456'
]);

echo $dto->user; // John Doe
```

#### DtoToResource

[](#dtotoresource)

You can use the `DtoToResource` attribute to convert the property for adding to the array. Create a new resource:

```
php artisan make:resource UserAddressResource
```

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
        #[DtoToResource(UserAddressResource::class)]
        public AddressDto $address,
    ) {}
}

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
    'address' => [
        'city' => 'New York',
        'street' => 'Wall Street',
    ]
]);

echo $dto->toArray();
// ['name' => 'John Doe', 'email' => '...', 'password' => '...', 'address' => ['city' => 'New York', 'street' => 'Wall Street']]
```

Address will be converted to the array using the `UserAddressResource` resource.

### Events

[](#events)

You can use events.

#### creating

[](#creating)

You can use the `creating` event.

```
UserDto::on('creating', function (array $arguments) {
    $arguments['name'] = 'John Doe';
    return $arguments;
});
```

#### created

[](#created)

You can use the `created` event.

```
UserDto::on('created', function (UserDto $dto, array $arguments) {
    $dto->name = 'John Doe';
});
```

#### updating

[](#updating)

You can use the `updating` event.

```
UserDto::on(['updating', 'name'], function (mixed $value, UserDto $dto) {
    return strtoupper($value);
});
```

#### updated

[](#updated)

You can use the `updated` event.

```
UserDto::on(['updated', 'name'], function (UserDto $dto) {
    $dto->name = strtoupper($dto->name);
});
```

#### mutating

[](#mutating)

You can use the `mutating` event.

```
UserDto::on(['mutating', 'name'], function (mixed $value, UserDto $dto, array $arguments) {
    return strtoupper($value);
});
```

#### mutated

[](#mutated)

You can use the `mutated` event.

```
UserDto::on(['mutated', 'name'], function (mixed $value, UserDto $dto, array $arguments) {
    return strtoupper($value);
});
```

#### serialize

[](#serialize)

You can use the `serialize` event.

```
UserDto::on('serialize', function (array $arguments, UserDto $dto) {
    $arguments['name'] = strtoupper($arguments['name']);
    return $arguments;
});
```

#### unserialize

[](#unserialize)

You can use the `unserialize` event.

```
UserDto::on('unserialize', function (array $arguments, UserDto $dto) {
    $arguments['name'] = strtolower($arguments['name']);
    return $arguments;
});
```

#### clone

[](#clone)

You can use the `clone` event.

```
UserDto::on('clone', function (array $arguments, UserDto $dto) {
    $arguments['name'] = strtolower($arguments['name']);
    return $arguments;
});
```

#### fromModel

[](#frommodel-1)

You can use the `fromModel` event.

```
UserDto::on('fromModel', function (UserDto $dto, array $arguments) {
    // You can change the DTO data or something else
});
```

#### fromEmpty

[](#fromempty-1)

You can use the `fromEmpty` event.

```
UserDto::on('fromEmpty', function (UserDto $dto, array $arguments) {
    // You can change the DTO data or something else
});
```

#### fromArray

[](#fromarray-1)

You can use the `fromArray` event.

```
UserDto::on('fromArray', function (UserDto $dto, array $arguments) {
    // You can change the DTO data or something else
});
```

#### fromRequest

[](#fromrequest-1)

You can use the `fromRequest` event.

```
UserDto::on('fromRequest', function (UserDto $dto, array $arguments) {
    // You can change the DTO data or something else
});
```

#### fromJson

[](#fromjson-1)

You can use the `fromJson` event.

```
UserDto::on('fromJson', function (UserDto $dto, array $arguments) {
    // You can change the DTO data or something else
});
```

#### fromSerialize

[](#fromserialize-1)

You can use the `fromJson` event.

```
UserDto::on('fromJson', function (UserDto $dto) {
    // You can change the DTO data or something else
});
```

#### prepareModel

[](#preparemodel)

You can use the `prepareModel` event.

```
UserDto::on('prepareModel', function (array $arguments) {
    $arguments['name'] = 'John Doe';
    return $arguments;
});
```

#### prepareSerialize

[](#prepareserialize)

You can use the `prepareSerialize` event.

```
UserDto::on('prepareSerialize', function (string $serializedString) {
    // You can change the serialized string or something else
    return $serializedString;
});
```

#### prepareJson

[](#preparejson)

You can use the `prepareJson` event.

```
UserDto::on('prepareJson', function (array $arguments) {
    // You can change the json array or something else
    return $arguments;
});
```

#### prepareRequest

[](#preparerequest)

You can use the `prepareRequest` event.

```
UserDto::on('prepareRequest', function (array $arguments) {
    // You can change the request array or something else
    return $arguments;
});
```

#### prepareArray

[](#preparearray)

You can use the `prepareArray` event.

```
UserDto::on('prepareArray', function (array $arguments) {
    // You can change the array or something else
    return $arguments;
});
```

#### prepareEmpty

[](#prepareempty)

You can use the `prepareArray` event.

```
UserDto::on('prepareEmpty', function () {
    // You can create a new array or something else
    return [];
});
```

#### destruct

[](#destruct)

You can use the `destruct` event.

```
UserDto::on('destruct', function (UserDto $dto) {
    // You can do something with the DTO
});
```

### Reflection

[](#reflection)

You can use reflection.

#### explain

[](#explain)

You can use the `explain` method for getting the DTO information.

```
$dto->explain();
```

#### vars

[](#vars)

You can use the `vars` method for getting the DTO properties.

```
$dto->vars();
```

#### getModifiedFields

[](#getmodifiedfields)

You can use the `getModifiedFields` method for getting the modified fields.

```
$dto->getModifiedFields();
```

#### getRelationNames

[](#getrelationnames)

You can use the `getRelationNames` method for getting the relation names.

```
$dto->getRelationNames();
```

#### getPropertyNames

[](#getpropertynames)

You can use the `getPropertyNames` method for getting the property names.

```
$dto->getPropertyNames();
```

#### getNames

[](#getnames)

You can use the `getNames` method for getting the names.

```
$dto->getNames();
```

#### getReflection

[](#getreflection)

You can use the `getReflection` method for getting the reflection.

```
$dto->getReflection();
```

### Convert DTO to

[](#convert-dto-to)

#### ToArray

[](#toarray)

You can convert DTO to array.

```
$dto->toArray();
```

#### ToJson

[](#tojson)

You can convert DTO to json.

```
$dto->toJson($options = 0);
```

#### ToResponse

[](#toresponse)

You can convert DTO to response.

```
$dto->toResponse(int $status = 200, array $headers = [], int $options = 0);
```

#### ToCollection

[](#tocollection)

You can convert DTO to collection.

```
$dto->toCollection();
```

#### ToBase64

[](#tobase64)

You can convert DTO to base64.

```
$dto->toBase64();
```

#### ToModel

[](#tomodel)

You can convert DTO to model.

```
$dto->toModel(User::class);
```

#### ToSerialize

[](#toserialize)

You can convert DTO to serialize.

```
$dto->toSerialize();
```

#### ToApi

[](#toapi)

You can convert DTO to api.

```
$dto->toApi(string $url, string $method = 'post', array $headers = []);
```

#### ToString

[](#tostring)

You can convert DTO to string.

```
$dto->toString();
//Or
echo (string) $dto;
```

#### ToFluent

[](#tofluent)

You can convert DTO to fluent.

```
$dto->toFluent();
```

#### ToImport

[](#toimport)

You can convert DTO to import.

> Convert an object to the format string from which the object was created. Used for storing in a database. `json` by default.

```
$dto->toImport(string $fileName, string $sheetName = 'Sheet1', array $options = []);
```

#### ToUrl

[](#tourl)

You can convert DTO to url.

```
$dto->toUrl(string|null $baseUrl = null, array $exclude = [], array $only = [], array $query = []): string;

$dto = UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
]);
// Generate only url parameters
echo $dto->toUrl();
// ?name=John%20Doe&email=test%40gmail.com

// Or generate parameters with base url
echo $dto->toUrl('https://example.com');
// https://example.com?name=John%20Doe&email=test%40gmail.com

// Or generate parameters with base url but without email property
echo $dto->toUrl('https://example.com', exclude: ['email']);
// https://example.com?name=John%20Doe

// Or generate parameters with base url use only email property
echo $dto->toUrl('https://example.com', only: ['email']);
// https://example.com?email=test%40gmail.com

// Or generate parameters with base url and additional query parameters
echo $dto->toUrl('https://example.com', query: ['page' => 1]);
// https://example.com?name=John%20Doe&email=test%40gmail.com&page=1

// And you can use parameters like tags in the base url
echo $dto->toUrl('https://example.com/find/{name}/name');
// https://example.com/find/John%20Doe/name?email=test%40gmail.com

// And you can convert DTO to the route.
// For example, you can have a route named 'user.profile'.
// You can use the `toUrl` method to generate a URL for that route.
echo $dto->toUrl('user.profile');
// This will generate a URL like: https://example.com/user/profile?name=John%20Doe&email=test%40gmail.com
```

### DTO Collection

[](#dto-collection)

Dto collection have couple additional methods.

#### insertToDatabase

[](#inserttodatabase)

For save collection to database you can use `saveToDatabase` method.

```
$collection = UserDto::fromCollection([
    ['name' => 'John Doe', 'email' => 'test@gmail.com', 'password' => '123456'],
    ['name' => 'Sam Doe', 'email' => 'sam@gmail.com', 'password' => '123456'],
]);

$collection->insertToDatabase('users');
```

#### insertToModel

[](#inserttomodel)

For save collection to model you can use `saveToModel` method.

```
$collection = UserDto::fromCollection([
    ['name' => 'John Doe', 'email' => 'test@gmail.com', 'password' => '123456'],
    ['name' => 'Sam Doe', 'email' => 'sam@gmail.com', 'password' => '123456'],
]);

$collection->insertToModel(\App\Models\User::class);
```

### Commands

[](#commands)

You can use commands.

#### Make dto

[](#make-dto)

You can create a new DTO using the artisan command.

```
php artisan make:dto UserDto
```

#### Make dto cast

[](#make-dto-cast)

You can create a new DTO cast using the artisan command.

```
php artisan make:dto-cast UserNameCast
```

#### Make dto docs

[](#make-dto-docs)

You can build the DTO documentation for extended fields using the artisan command.

```
php artisan make:dto-docs
```

> Add this command to the `composer.json` file for auto-generating DTO documentation after the `composer update` and `composer dump-autoload` command.

```
"scripts": {
    "post-autoload-dump": [
        "@php artisan make:dto-docs"
    ],
}
```

### Dto like model cast

[](#dto-like-model-cast)

You can use the Dto class as a cast class for a model with a JSON or link field. Keep in mind that if the array is associative, it will return the Dto class, but if not, it will return a collection.

```
use Bfg\Dto\Dto;

/**
 * @extends Dto
 */
class UserSettingsDto extends Dto
{
    public function __construct(
        public string $theme,
        public bool $notificationsEnabled,
        public string $language,
    ) {}

    public function toDatabase(): string
    {
        return "$this->theme|$this->notificationsEnabled|$this->language";
    }

    /**
     * If you have a static method that ends with the same suffix as the envelope method "toDatabase".
     * That is, you must have the following inverse static method "fromDatabase".
     */
    public static function fromDatabase(string $data): array
    {
        $data = explode('|', $data);

        return [
            'theme' => $data[0],
            'notificationsEnabled' => (bool) $data[1],
            'language' => $data[2],
        ];
    }
}

use Illuminate\Database\Eloquent\Model;
use Bfg\Dto\Collections\DtoCollection;

class User extends Model
{
    protected $casts = [
        'settings' => UserSettingsDto::class, // Use the Dto class as a cast class
        // Or you can specify the Dto how to save the data in the database
        'settings' => UserSettingsDto::store()->toDatabase(), // Custom save.
        // Or you can use the DtoCollection class for a collection
        'settings' => DtoCollection::using(UserSettingsDto::class),
        // Or specify dto casting
        'settings' => DtoCollection::using(UserSettingsDto::store()->toDatabase()),
    ];
    protected $fillable = ['name', 'email', 'settings'];
    protected $hidden = ['password'];
}
```

### Helpers

[](#helpers)

You can use helpers.

#### new

[](#new)

You can use the `new` helper for creating a new DTO.

```
UserDto::new(
    name: 'John Doe',
    email: 'test@gmail.com',
    password: '123456',
);
```

#### version

[](#version)

You can use the `version` helper for getting the DTO version.

```
UserDto::version();
```

#### pipeline

[](#pipeline)

You can use the `pipeline` helper for creating a new DTO pipeline.

```
$dto->pipeline([
    SomeClassForPipeline::class,
]);
```

#### camelKeys

[](#camelkeys)

You can use the `camelKeys` helper for converting the DTO keys to camel case when converting to an array.

```
$dto->camelKeys()->toArray();
```

#### snakeKeys

[](#snakekeys)

You can use the `snakeKeys` helper for converting the DTO keys to snake case when converting to an array.

```
$dto->snakeKeys()->toArray();
```

#### cache

[](#cache)

You can use the `cache` helper for caching the DTO.

```
$dto->cache(\DateTimeInterface|\DateInterval|int|null $ttl = null);
```

#### cacheKey

[](#cachekey)

You can use the `cacheKey` helper for getting the cache key.

```
$dto->cacheKey('name');
```

#### getCachedKey

[](#getcachedkey)

You can use the `getCachedKey` helper for getting the cached key.

```
$dto->getCachedKey('name');
```

#### cacheKeyClear

[](#cachekeyclear)

You can use the `cacheKeyClear` helper for clearing the cache key.

```
$dto->cacheKeyClear('name');
```

#### validate

[](#validate)

You can use the `validate` helper for validating the DTO.

```
$dto->validate([
    'name' => 'required|string',
    'email' => 'required|email',
    'password' => 'required|string|min:6',
]); // bool
```

#### restore

[](#restore)

You can use the `restore` helper for restoring the DTO from the original data.

```
$dto->restore();
```

#### originals

[](#originals)

You can use the `originals` helper for getting the original data.

```
$dto->originals();
```

#### equals

[](#equals)

You can use the `equals` helper for comparing the DTOs.

```
$dto->equals(UserDto::fromArray([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
])); // bool
```

#### fill

[](#fill)

You can use the `fill` helper for filling the DTO.

```
$dto->fill([
    'name' => 'John Doe',
    'email' => 'test@gmail.com',
    'password' => '123456',
]);
```

#### length

[](#length)

You can use the `length` helper for getting the length of the DTO in bytes.

```
$dto->length();
// Or
$dto->length(\Bfg\Dto\Dto::GET_LENGTH_SERIALIZE); // You get the length of the DTO in bytes in serialized form

// And you can get the length of the DTO in bytes in json form
$dto->length(\Bfg\Dto\Dto::GET_LENGTH_JSON);
```

#### count

[](#count)

You can use the `count` helper for getting the count of the DTO.

```
$dto->count();
```

#### has

[](#has)

You can use the `has` helper for checking the property in the DTO.

```
$dto->has('name');
```

You also can use `isset` for checking the property in the DTO.

```
isset($dto['name']);
```

#### dataHash

[](#datahash)

You can use the `dataHash` helper for getting the data hash of the DTO.

```
$dto->dataHash();
```

#### hash

[](#hash)

You can use the `hash` helper for getting the hash of the DTO.

```
$dto->hash();
```

#### clone

[](#clone-1)

You can use the `clone` helper for cloning the DTO.

```
$dto->clone();
```

#### str

[](#str)

You can use the `str` helper for getting the string representation of the DTO.

```
$dto->str('name')->camel()->snake();
```

#### collect

[](#collect)

You can use the `collect` helper for wrapping the DTO properties in the collection.

```
$dto->collect('addresses')->map(function (UserAddressDto $address) {
    return $address->city;
});
```

#### boolable

[](#boolable)

You can use the `boolable` helper for inverting the boolean property in the DTO.

```
$dto->boolable('confirmed');
```

#### toggleBool

[](#togglebool)

You can use the `toggleBool` helper for toggling the boolean property in the DTO.

```
$dto->toggleBool('is_admin');
```

#### increment

[](#increment)

You can use the `increment` helper for incrementing the property in the DTO.

```
$dto->increment('count');
```

#### decrement

[](#decrement)

You can use the `decrement` helper for decrementing the property in the DTO.

```
$dto->decrement('count');
```

#### set

[](#set)

You can use the `set` helper for setting the property in the DTO.

```
$dto->set('name', 'John Doe');
```

#### get

[](#get)

You can use the `get` helper for getting the property in the DTO.

```
$dto->get('name');
```

#### map

[](#map)

You can use the `map` helper for mapping the DTO properties.

```
$dto->map(function (mixed $value, string $key) {
    return strtoupper($value);
});
```

#### isEmpty

[](#isempty)

You can use the `isEmpty` helper for checking the DTO is property empty.

```
$dto->isEmpty('name');
```

#### isNotEmpty

[](#isnotempty)

You can use the `isNotEmpty` helper for checking the DTO is property not empty.

```
$dto->isNotEmpty('name');
```

#### isNull

[](#isnull)

You can use the `isNull` helper for checking the DTO is property null.

```
$dto->isNull('name');
```

#### isNotNull

[](#isnotnull)

You can use the `isNotNull` helper for checking the DTO is property not null.

```
$dto->isNotNull('name');
```

#### isCanNull

[](#iscannull)

You can use the `isCanNull` helper for checking the DTO is property can be null.

```
$dto->isCanNull('name');
```

#### isTrue

[](#istrue)

You can use the `isTrue` helper for checking the DTO is property true.

```
$dto->isTrue('is_admin');
```

#### isFalse

[](#isfalse)

You can use the `isFalse` helper for checking the DTO is property false.

```
$dto->isFalse('is_admin');
```

#### isBool

[](#isbool)

You can use the `isBool` helper for checking the DTO is property bool.

```
$dto->isBool('is_admin');
```

#### isEquals

[](#isequals)

You can use the `isEquals` helper for checking the DTO is property equals.

```
$dto->isEquals('name', 'John Doe');
```

#### isNotEquals

[](#isnotequals)

You can use the `isNotEquals` helper for checking the DTO is property not equals.

```
$dto->isNotEquals('name', 'John Doe');
```

#### isInstanceOf

[](#isinstanceof)

You can use the `isInstanceOf` helper for checking the DTO is property instance of.

```
$dto->isInstanceOf('address', AddressDto::class);
```

#### isNotInstanceOf

[](#isnotinstanceof)

You can use the `isNotInstanceOf` helper for checking the DTO is property not instance of.

```
$dto->isNotInstanceOf('address', AddressDto::class);
```

#### isString

[](#isstring)

You can use the `isString` helper for checking the DTO is property string.

```
$dto->isString('name');
```

#### isNotString

[](#isnotstring)

You can use the `isNotString` helper for checking the DTO is property not string.

```
$dto->isNotString('name');
```

#### isInt

[](#isint)

You can use the `isInt` helper for checking the DTO is property int.

```
$dto->isInt('id');
```

#### isNotInt

[](#isnotint)

You can use the `isNotInt` helper for checking the DTO is property not int.

```
$dto->isNotInt('id');
```

#### isFloat

[](#isfloat)

You can use the `isFloat` helper for checking the DTO is property float.

```
$dto->isFloat('price');
```

#### isNotFloat

[](#isnotfloat)

You can use the `isNotFloat` helper for checking the DTO is property not float.

```
$dto->isNotFloat('price');
```

#### isArray

[](#isarray)

You can use the `isArray` helper for checking the DTO is property array.

```
$dto->isArray('addresses');
```

#### isNotArray

[](#isnotarray)

You can use the `isNotArray` helper for checking the DTO is property not array.

```
$dto->isNotArray('addresses');
```

#### isObject

[](#isobject)

You can use the `isObject` helper for checking the DTO is property object.

```
$dto->isObject('address');
```

#### isNotObject

[](#isnotobject)

You can use the `isNotObject` helper for checking the DTO is property not object.

```
$dto->isNotObject('address');
```

#### isInstanceOfArray

[](#isinstanceofarray)

You can use the `isInstanceOfArray` helper for checking the DTO is property instance of array.

```
$dto->isInstanceOfArray('addresses', AddressDto::class);
```

#### isNotInstanceOfArray

[](#isnotinstanceofarray)

You can use the `isNotInstanceOfArray` helper for checking the DTO is property not instance of array.

```
$dto->isNotInstanceOfArray('addresses', AddressDto::class);
```

### Customize http request

[](#customize-http-request)

You can customize the http request.

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}

    protected static function httpClient(): PendingRequest
    {
        return Http::withoutVerifying()
            ->withoutRedirecting()
            ->withCookies(['name' => 'value'])
            ->withHeaders(['Authorization' => 'Bearer ' . auth()->user()->token]);
    }
}
```

Or you can customize only headers:

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}

    protected static function httpHeaders(): array
    {
        return [
            'Authorization' => 'Bearer ' . auth()->user()->token,
        ];
    }
}
```

Also you can customize what `from` or `fromUrl` can be used for the request POST by default

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    protected static string $defaultHttpMethod = 'post';

    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}
}
```

And you can customize the parameters data for the request by default

```
use Bfg\Dto\Dto;

class UserDto extends Dto
{
    public function __construct(
        public string $name,
        public string $email,
        public ?string $password,
    ) {}

    protected static function httpData(array|string|null $data): array|string|null
    {
        // Do something with data
        return $data;
    }
}
```

### Default Laravel Support

[](#default-laravel-support)

DTO class use a famous Laravel support, such as `Illuminate\Support\Traits\Conditionable`, `Illuminate\Support\Traits\Dumpable`, `Illuminate\Support\Traits\Macroable` and `Illuminate\Support\Traits\Tappable`.

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Security
--------

[](#security)

Please see [SECURITY](SECURITY.md) for more information about security.

Credits
-------

[](#credits)

- [Xsaven](mailto:xsaven@gmail.com)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance74

Regular maintenance activity

Popularity18

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity52

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

Every ~23 days

Recently: every ~51 days

Total

17

Last Release

148d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/59b2d162a30938ac2c3c56340ebea07a6778a3e1c86cb70b5bc28b69a1c3f04d?d=identicon)[bfg](/maintainers/bfg)

---

Top Contributors

[![Xsaven](https://avatars.githubusercontent.com/u/1726771?v=4)](https://github.com/Xsaven "Xsaven (141 commits)")

---

Tags

phplaraveltemplate

### Embed Badge

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

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

###  Alternatives

[tomatophp/filament-wallet

Account Balance / Wallets Manager For FilamentPHP and Filament Account Builder

3528.5k2](/packages/tomatophp-filament-wallet)[tomatophp/filament-subscriptions

Manage subscriptions and feature access with customizable plans in FilamentPHP

628.1k](/packages/tomatophp-filament-subscriptions)[tomatophp/filament-plugins

Manage your modules as a plugin system with plugin generator

644.7k2](/packages/tomatophp-filament-plugins)[tomatophp/filament-docs

Manage your documents and contracts all in one place with template builder

422.6k](/packages/tomatophp-filament-docs)

PHPackages © 2026

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