PHPackages                             rutek/dataclass - 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. rutek/dataclass

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

rutek/dataclass
===============

Library for validation of type-hinted classes

v0.1.3(4mo ago)2373.9k↑39.4%6[2 issues](https://github.com/rutek/dataclass/issues)LGPL-3.0-or-laterPHPPHP ^7.4 || ^8.0CI failing

Since Dec 9Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/rutek/dataclass)[ Packagist](https://packagist.org/packages/rutek/dataclass)[ RSS](/packages/rutek-dataclass/feed)WikiDiscussions master Synced yesterday

READMEChangelog (7)Dependencies (3)Versions (10)Used By (0)

PHP Dataclass library
=====================

[](#php-dataclass-library)

Dataclass allows you to quickly change your plain `array` to type-hinted PHP class with automatic denormalization of embeded objects and collections which normally requires much work if you use normalizers and denormalizers. Library is insipired by Python [pydantic](https://pydantic-docs.helpmanual.io/) module. It uses type-hinting power available since PHP 7.4.

Main goal of this package is to provide fast way for having strictly type-hinted classes for further usage, for example to map request payload to strictly typed class so you can use it instead of array which may or may not match your requirements. It won't replace your data validation but will make you sure that f.x. received JSON payload matches types which your backend operations expect to receive. It's something like mentioned above [pydantic `BaseModel`](https://pydantic-docs.helpmanual.io/) or [TypeScript interface](https://www.typescriptlang.org/docs/handbook/interfaces.html).

All you need is create class or two:

```
declare(strict_types=1);

class MyEmbededClass
{
    public float $number;
}

class MyClass
{
    public int $number;
    public ?string $optionalText = null;
    public MyEmbededClass $embeded;
}
```

As next step pass main class name and received data, for example from received JSON to `transform` method:

```
$data = '{
    "number": 1,
    "embeded": {
        "number": 1.23
    }
}';
$object = transform(MyClass::class, json_decode($data, true));
```

To quickly map received data to fully functional dataclass:

```
var_dump($object)
```

```
object(MyClass) {
  ["number"]=> int(1)
  ["optionalText"]=> NULL
  ["embeded"]=>
  object(MyEmbededClass) {
    ["number"]=>
    float(1.23)
  }
}
```

You don't have to worry about passing `null` from `json_decode`, it will throw `TransformException` for `root` field if it's detected.

You don't have to worry about missing fields and invalid types as library detects all type-hinted requirements and throws `TransformException` with errors (ready to be served as response) pointing to exact fields with simple reason message, for example:

```
echo json_encode($transformException, JSON_PRETTY_PRINT)
```

```
{
    "errors": [
        {
            "field": "optionalText",
            "reason": "Field must have value"
        },
        {
            "field": "embeded",
            "reason": "Field must have value"
        }
    ]
}
```

You can also use `Transform::to` method which is in fact called by `transform` helper function. Helper function will always use optimal settings for `Transform` objects (as soon as they appear).

```
$data = '{
    "number": 1,
    "embeded": {
        "number": 1.23
    }
}';
$transformer = new Transform();
$object = $transformer->to(MyClass::class, json_decode($data, true));
```

### Constructors

[](#constructors)

If you need to use constructor with type-hinted arguments you can do it, but in the limited way. The library only supports filling in constructor arguments with values from the payload. It means that constructor must use the same types and variable names as the class properties. For example:

```
class MyClass
{
    public float $number;
    public ?int $numberTwo = null;

    public function __construct(float $number)
    {
        $this->number = $number;
    }
}
```

Using different name or type for the constructor argument won't work. The goal is to support enforcing developer to fill in the properties.

Any constructor that contains any other parameter than the properties will throw `UnsupportedException`. Parameters must have the same type as properties. Order is irrelevant. If it's needed, only some subset of properties can exist in the constructor.

### More examples

[](#more-examples)

Please check out [docs/ directory](docs/) for more examples.

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

[](#installation)

As simple as

```
composer install rutek/dataclass

```

Supported type hints
--------------------

[](#supported-type-hints)

**Attention:** please be aware of using `array` type hints. They cannot be used (will throw `UnsupportedException` if detected) as PHP does not provide way to type-hint items of array. Please check *Collections* section below for further information.

### Scalars

[](#scalars)

All [four PHP scalars](https://www.php.net/manual/en/language.types.intro.php) are supported.

### Nullable fields

[](#nullable-fields)

Type-hinting nullability is supported. You can safely use for example `?string` to accept both `string` and `null`. Please be aware as using only `?string $field` does not mean that transformed array may not contain this field. It only means that this value accepts `null`.

### Default values

[](#default-values)

If you need to accept transformation of data which does not contain some fields you can use default values, for exmaple: `?string $field = null`. Dataclass library will detect that this property does not exist in payload and will use default value instead.

### Collections

[](#collections)

PHP does not support type-hinting `array` fields if you need to embed collection of objects or scalars you have to use `Collection` class. You need to extend it with constructor with type-hinted arguments deconstruction, for example:

```
class Tags extends Collection
{
    public function __construct(string ...$names)
    {
        $this->items = $names;
    }
}
```

Type-hinted arrays like `string[]` [were rejected in RFC](https://wiki.php.net/rfc/arrayof) so propably this behaviour will not change soon.

Library will check if provided values match type-hinting of constructor.

There is no possiblity to check minimum and maxiumum items but there may be such feature in next versions.

Please note that you can also use Collection as base class which you want to transform, for example:

```
$tags = transform(Tags::class, ['tag1', 'tag2']);
```

Exceptions
----------

[](#exceptions)

`TransformException` - data does not match your schema
------------------------------------------------------

[](#transformexception---data-does-not-match-your-schema)

This is base exception you can expect. Every time your data (payload) passed to function `transform(string $class, $data)` or `Transform::to` will not match your type-hinted classes, you will receive `TransformException` with `getErrors(): FieldError[]` method which describes what really happened.

Every `FieldError` contains both `field` describing which field failed type check and `reason` describing in simple words why it has been rejected. If there are nested objects you can expect to receive `field` values like `parentProperty.childrenProperty` (levels separated by dot).

Class supports JSON serialization and will always return something like:

```
{
    "errors": [
        {
            "field": "optionalText",
            "reason": "Field must have value"
        },
        {
            "field": "embeded",
            "reason": "Field must have value"
        }
    ]
}
```

Please note that `code` field may be added in future.

`UnsupportedException` - only if your type-hints are not supported
------------------------------------------------------------------

[](#unsupportedexception---only-if-your-type-hints-are-not-supported)

Library does not cover all scenarios as you can define type hints which would not have strict context. For example if you use `object` property, it would not be possible to validate it as any object will match your schema. In such cases you can expect `UnsupportedException`.

Unsupported (yet?)
------------------

[](#unsupported-yet)

### Intersection and union types

[](#intersection-and-union-types)

PHP 8.0 [union types](https://wiki.php.net/rfc/union_types_v2) and PHP 8.1 [intersection types](https://wiki.php.net/rfc/pure-intersection-types) are unsupported right now.

### Enums

[](#enums)

Native PHP 8.1 [enums](https://www.php.net/manual/en/language.types.enumerations.php) are unsupported right now.

### Private and protected properties

[](#private-and-protected-properties)

All type-hinted fields must be public as for now. Implementing such feature is questionable as you would have to create getters for such properties which is unwanted overhead. Library is meant to create possiblity to define internal schemas for data received from remote systems (APIs, queues/bus messages, browsers).

### Reflection cache

[](#reflection-cache)

All reflection checks are made every time `transform` or `Transform::to` function is called. You can expect caching functionality for better performance soon.

Remarks
-------

[](#remarks)

Please remember that goal of this package is not to fully validate data you receive but to create simple classes which makes your payloads fully type-hinted also when they have some complicated structure. You will not have to encode you classes in JSON with `class` fields as your type hints will tell your code what object or array should be created in place of some embeded values.

If you are creating API and you need enterprise-grade OpenAPI schema validation you should check [hkarlstrom/openapi-validation-middleware](https://github.com/hkarlstrom/openapi-validation-middleware) and afterwards you can map received payload to type-hinted classes using this library! :)

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance73

Regular maintenance activity

Popularity41

Moderate usage in the ecosystem

Community15

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 54.3% 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 ~376 days

Recently: every ~365 days

Total

7

Last Release

142d ago

PHP version history (2 changes)v0.0.1PHP ^7.4

v0.0.3PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/6c33cf4e40cbb46fc27154fa0801e689540ecdbda0326818c4bc6a45ecf0fa36?d=identicon)[lukasz\_rutkowski](/maintainers/lukasz_rutkowski)

---

Top Contributors

[![tc-rutek](https://avatars.githubusercontent.com/u/133372346?v=4)](https://github.com/tc-rutek "tc-rutek (19 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (7 commits)")[![rutek](https://avatars.githubusercontent.com/u/1064745?v=4)](https://github.com/rutek "rutek (7 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![glensc](https://avatars.githubusercontent.com/u/199095?v=4)](https://github.com/glensc "glensc (1 commits)")

---

Tags

phpphp-libraryphp7schema-validation

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/rutek-dataclass/health.svg)

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

###  Alternatives

[marcosh/php-validation-dsl

A DSL for validating data in a functional fashion

483.9k](/packages/marcosh-php-validation-dsl)

PHPackages © 2026

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