PHPackages                             michaelalexeevweb/openapi-php-dto-generator - 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. [API Development](/categories/api)
4. /
5. michaelalexeevweb/openapi-php-dto-generator

ActiveLibrary[API Development](/categories/api)

michaelalexeevweb/openapi-php-dto-generator
===========================================

Generate immutable PHP DTO classes from OpenAPI schemas with request and response validation.

1.2.3(1mo ago)427↓100%MITPHPPHP ^8.3CI passing

Since Mar 9Pushed 1mo agoCompare

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

READMEChangelog (10)Dependencies (8)Versions (20)Used By (0)

OpenAPI PHP DTO Generator
=========================

[](#openapi-php-dto-generator)

[![MIT License](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](LICENSE)[![CI](https://github.com/michaelalexeevweb/openapi-php-dto-generator/actions/workflows/ci.yml/badge.svg)](https://github.com/michaelalexeevweb/openapi-php-dto-generator/actions/workflows/ci.yml)

Generate immutable PHP DTO classes from OpenAPI `components.schemas`.

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

[](#installation)

```
composer require michaelalexeevweb/openapi-php-dto-generator:^1.2.2
```

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

[](#requirements)

- PHP 8.3+

Version
-------

[](#version)

\*\*Version 1.2.2 - Supports **OpenAPI 3.0.\*** and **OpenAPI 3.1.\***.

### OpenAPI 3.1 features supported

[](#openapi-31-features-supported)

FeatureNotes`type: [string, null]`Nullable scalar via array-type syntax`type: [string, integer]`Multi-type union → `string|int` property`exclusiveMinimum: 5` / `exclusiveMaximum: 100`Numeric bounds (not the OAS 3.0 boolean flag)`oneOf: [{$ref: …}, {type: null}]`Nullable `$ref` via the recommended 3.1 pattern`type: null` variant inside `oneOf` / `anyOf`Treated as nullableSibling keywords alongside `$ref``description` placed next to `$ref` is preserved in the docblockThe OAS 3.0 `nullable: true` shorthand is still accepted for backwards compatibility.

Usage
-----

[](#usage)

### Add script in your project `composer.json`

[](#add-script-in-your-project-composerjson)

```
{
  "scripts": {
    "openapi:generate-dto": "php vendor/michaelalexeevweb/openapi-php-dto-generator/bin/console openapi:generate-dto"
  }
}
```

### Generate DTO classes

[](#generate-dto-classes)

Run command with flags:

```
composer openapi:generate-dto -- --file=OpenApiExamples/test.yaml --directory=generated/test
```

Provide explicit namespace (optional):

```
composer openapi:generate-dto -- --file=OpenApiExamples/test.yaml --directory=generated/test --namespace=Generated\\Test
```

Or with positional file argument:

```
composer openapi:generate-dto -- OpenApiExamples/test.yaml --directory=generated/test
```

If `--namespace` is not provided, namespace is derived from `--directory`.

### Using generated DTOs in your code

[](#using-generated-dtos-in-your-code)

Once you've generated your DTO classes, you can use them to validate and deserialize requests:

```
use OpenapiPhpDtoGenerator\Service\RequestValidationService;
use Symfony\Component\HttpFoundation\Request;
use YourApp\Generated\UserDto;

$validator = new RequestValidationService();

// Validate request and get result with validation info
$result = $validator->validate($request, UserDto::class);

if ($result->isValid()) {
    $dto = $result->getDto();
    echo "User ID: " . $dto->getId();
} else {
    $errors = $result->getErrors();
    echo "Validation failed: " . $result->getFirstError();
}
```

Or throw an exception on validation failure:

```
use OpenapiPhpDtoGenerator\Service\RequestValidationService;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;

$validator = new RequestValidationService();

try {
    $dto = $validator->validateOrThrow($request, UserDto::class);
    // Use $dto here
} catch (BadRequestException $e) {
    echo "Validation error: " . $e->getMessage();
}
```

You can also customize validation error texts:

```
use OpenapiPhpDtoGenerator\Service\RequestValidationService;
use OpenapiPhpDtoGenerator\Service\ValidationMessageKey;

$validator = new RequestValidationService(messageOverrides: [
    ValidationMessageKey::PARAM_EXPECTS_TYPE->value => 'Field "{paramPath}" must be {expectedType}, got {actualType}',
]);
```

You can also register custom OpenAPI `format` handlers (validation + deserialization):

```
use OpenapiPhpDtoGenerator\Contract\OpenApiFormatHandlerInterface;
use OpenapiPhpDtoGenerator\Service\OpenApiFormatRegistry;
use OpenapiPhpDtoGenerator\Service\RequestValidationService;

$registry = new OpenApiFormatRegistry([
    'upper-code' => new class implements OpenApiFormatHandlerInterface {
        public function validate(string $subject, mixed $value): ?string
        {
            if (!is_string($value) || preg_match('/^[A-Z0-9\-]+$/', $value) !== 1) {
                return sprintf('%s must match custom format upper-code', $subject);
            }

            return null;
        }

        public function deserialize(mixed $value, string $typeName, string $paramPath, bool $allowsNull): mixed
        {
            return is_string($value) ? strtoupper($value) : $value;
        }
    },
]);

$validator = new RequestValidationService(formatRegistry: $registry);
```

CLI commands
------------

[](#cli-commands)

- `openapi:generate-dto` - generate DTO classes from OpenAPI schemas
- `yaml:echo-properties` - print YAML as nested PHP array syntax

Features
--------

[](#features)

- Generate DTO classes from `components.schemas`
- Generate enums from schema `enum` (string and int backed)
- Support nested object schemas and nested enums
- Support `allOf` (inheritance or property merge)
- Support `oneOf` and `anyOf` (interface unions)
- Support `discriminator` with `propertyName` / `mapping`
- Generate DTOs for inline request/response schemas without a named `$ref`
- Handle path and query parameter schemas (with `isInPath` / `isInQuery` helpers)
- Preserve schema `description` as PHPDoc comments
- Preserve `default` values
- Preserve OpenAPI constraints (`minimum`, `maximum`, `exclusiveMinimum`, `exclusiveMaximum`, `minLength`, `maxLength`, `pattern`, `minItems`, `maxItems`, `uniqueItems`, `format`) via `getOpenApiConstraints()`
- Validate and deserialize incoming Symfony `Request` objects against generated DTOs
- Custom validation error messages
- Custom `format` handlers (validation + deserialization)
- Support for external `$ref` across multiple YAML files
- **OpenAPI 3.1**: `type: [string, null]`, multi-type unions, numeric `exclusiveMinimum` / `exclusiveMaximum`, `oneOf` + `{type: null}` nullable references, sibling keywords alongside `$ref`

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance97

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity57

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 ~0 days

Total

19

Last Release

48d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/09ca088fdfe3b6be48755e620884b445563e33347498e381a436a257068e5ff8?d=identicon)[michaelalexeevweb](/maintainers/michaelalexeevweb)

---

Top Contributors

[![michaelalexeevweb](https://avatars.githubusercontent.com/u/39598000?v=4)](https://github.com/michaelalexeevweb "michaelalexeevweb (15 commits)")

---

Tags

phpopenapigeneratordto

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/michaelalexeevweb-openapi-php-dto-generator/health.svg)

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

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M647](/packages/sylius-sylius)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

19462.3M1.3k](/packages/drupal-core)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M151](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6939.5M340](/packages/drupal-core-recommended)

PHPackages © 2026

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