PHPackages                             baraja-core/serializer - 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. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. baraja-core/serializer

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

baraja-core/serializer
======================

Simple serializer any PHP type or structure to simple scalar array.

v1.0.1(3y ago)128.0k1PHPPHP ^8.0CI failing

Since Jul 25Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/baraja-core/serializer)[ Packagist](https://packagist.org/packages/baraja-core/serializer)[ Docs](https://github.com/baraja-core/serializer)[ RSS](/packages/baraja-core-serializer/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (11)Versions (3)Used By (1)

PHP Serializer
==============

[](#php-serializer)

A simple, secure, and flexible serializer that converts any PHP object or data structure into a simple scalar array, ready to be sent via REST API.

The serializer automatically handles backward and forward compatibility, security concerns, and supports a wide range of PHP types including DTOs, entities, enums, DateTime objects, and more.

💡 Key Principles
----------------

[](#bulb-key-principles)

- **Zero dependencies** - Works standalone without any required external packages
- **Security-first** - Automatically hides sensitive data (passwords, credit cards, PINs)
- **Type-safe** - Full support for PHP 8.0+ typed properties and modern features
- **Recursion protection** - Detects and prevents infinite loops in object graphs
- **Depth limiting** - Protects against overly deep nested structures (max 32 levels)
- **Convention-based** - Configurable behavior through the convention system
- **Bridge interfaces** - Extensible architecture for custom type handling

🏗️ Architecture
---------------

[](#building_construction-architecture)

The package follows a simple yet powerful architecture with clear separation of concerns:

```
┌───────────────────────────────────────────────────────────┐
│                        Serializer                         │
│  (Main entry point - singleton or instance-based usage)   │
├───────────────────────────────────────────────────────────┤
│                   SerializerConvention                    │
│  (Configuration: date format, null handling, hidden keys) │
├───────────────────────────────────────────────────────────┤
│                    Bridge Interfaces                      │
│  ┌─────────────────────┐  ┌───────────────────────────┐  │
│  │ ItemsListInterface  │  │  StatusCountInterface     │  │
│  │ (List collections)  │  │  (Status with count)      │  │
│  └─────────────────────┘  └───────────────────────────┘  │
└───────────────────────────────────────────────────────────┘
                             │
                             ▼
┌───────────────────────────────────────────────────────────┐
│                     Supported Types                       │
│  - Scalars (string, int, float, bool, null)               │
│  - Arrays (indexed and associative)                       │
│  - Objects (DTOs, entities, stdClass)                     │
│  - DateTimeInterface                                      │
│  - UnitEnum (PHP 8.1+)                                    │
│  - Nette\Utils\Paginator                                  │
│  - Baraja\Localization\Translation                        │
│  - Baraja\EcommerceStandard\DTO\PriceInterface            │
│  - Objects with __toString() method                       │
└───────────────────────────────────────────────────────────┘

```

### ⚙️ Core Components

[](#gear-core-components)

#### Serializer

[](#serializer)

The main class responsible for converting PHP data structures to arrays. It can be used as a singleton via `Serializer::get()` or instantiated with a custom convention.

**Key features:**

- Processes objects using reflection to access all properties (including private)
- Automatically skips internal properties (those starting with `_`)
- Tracks object instances to detect circular references
- Enforces depth limit to prevent stack overflow

#### SerializerConvention

[](#serializerconvention)

Configuration class that controls serialization behavior:

PropertyDefaultDescription`dateTimeFormat``'Y-m-d H:i:s'`Format for DateTime serialization`rewriteTooStringMethod``true`Use `__toString()` for stringable objects`rewriteNullToUndefined``false`Remove null values from output`keysToHide``['password', 'passwd', ...]`Keys containing sensitive data#### Bridge Interfaces

[](#bridge-interfaces)

**ItemsListInterface** - For objects representing a collection of items:

```
interface ItemsListInterface
{
    /** @return array */
    public function getData(): array;
}
```

**StatusCountInterface** - For status objects with a count (useful for filters, tabs):

```
interface StatusCountInterface
{
    public function getKey(): string;
    public function getLabel(): string;
    public function getCount(): int;
}
```

📦 Installation
--------------

[](#package-installation)

It's best to use [Composer](https://getcomposer.org) for installation, and you can also find the package on [Packagist](https://packagist.org/packages/baraja-core/serializer) and [GitHub](https://github.com/baraja-core/serializer).

To install, simply use the command:

```
$ composer require baraja-core/serializer
```

You can use the package manually by creating an instance of the internal classes.

### Requirements

[](#requirements)

- PHP 8.0 or higher
- No required dependencies (optional integrations available)

🚀 Basic Usage
-------------

[](#rocket-basic-usage)

### Simple DTO Serialization

[](#simple-dto-serialization)

```
use Baraja\Serializer\Serializer;

class UserDTO
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {
    }
}

$serializer = Serializer::get();

$user = new UserDTO(
    name: 'Jan Barasek',
    email: 'jan@example.com',
    age: 30,
);

$result = $serializer->serialize($user);
// Result: ['name' => 'Jan Barasek', 'email' => 'jan@example.com', 'age' => 30]
```

### Nested Objects

[](#nested-objects)

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

class PersonDTO
{
    public function __construct(
        public string $name,
        public AddressDTO $address,
    ) {
    }
}

$person = new PersonDTO(
    name: 'Jan',
    address: new AddressDTO(street: 'Main St', city: 'Prague'),
);

$result = $serializer->serialize($person);
// Result: [
//     'name' => 'Jan',
//     'address' => ['street' => 'Main St', 'city' => 'Prague']
// ]
```

### Array Serialization

[](#array-serialization)

```
$data = [
    'users' => [
        new UserDTO('Alice', 'alice@example.com', 25),
        new UserDTO('Bob', 'bob@example.com', 30),
    ],
    'total' => 2,
];

$result = $serializer->serialize($data);
```

### DateTime Handling

[](#datetime-handling)

```
class EventDTO
{
    public function __construct(
        public string $title,
        public \DateTimeInterface $startDate,
    ) {
    }
}

$event = new EventDTO(
    title: 'Conference',
    startDate: new \DateTime('2024-06-15 10:00:00'),
);

$result = $serializer->serialize($event);
// Result: ['title' => 'Conference', 'startDate' => '2024-06-15 10:00:00']
```

### Enum Serialization (PHP 8.1+)

[](#enum-serialization-php-81)

```
enum Status: string
{
    case Active = 'active';
    case Inactive = 'inactive';
}

class ItemDTO
{
    public function __construct(
        public string $name,
        public Status $status,
    ) {
    }
}

$item = new ItemDTO(name: 'Product', status: Status::Active);

$result = $serializer->serialize($item);
// Result: ['name' => 'Product', 'status' => 'active']
```

🛡️ Security Features
--------------------

[](#shield-security-features)

### Automatic Password Protection

[](#automatic-password-protection)

The serializer automatically detects and hides sensitive keys. When a sensitive key is found, its value is replaced with `*****`:

```
class LoginDTO
{
    public function __construct(
        public string $username,
        public string $password,
    ) {
    }
}

$login = new LoginDTO(username: 'admin', password: 'secret123');

$result = $serializer->serialize($login);
// Result: ['username' => 'admin', 'password' => '*****']
```

**Default hidden keys:** `password`, `passwd`, `pass`, `pwd`, `creditcard`, `credit card`, `cc`, `pin`

**Exception:** BCrypt hashes (format `$2[ayb]$...`) are allowed through, as they are already securely hashed.

### Internal Property Protection

[](#internal-property-protection)

Properties starting with underscore (`_`) are automatically excluded from serialization:

```
class EntityDTO
{
    public function __construct(
        public string $name,
        public string $_internalId, // Will be excluded
    ) {
    }
}
```

### Recursion Detection

[](#recursion-detection)

The serializer tracks object instances and throws an exception if circular references are detected:

```
class Node
{
    public function __construct(
        public string $name,
        public ?Node $parent = null,
    ) {
    }
}

$node = new Node('A');
$node->parent = $node; // Circular reference

$serializer->serialize($node);
// Throws: InvalidArgumentException with recursion warning
```

🔧 Advanced Usage
----------------

[](#wrench-advanced-usage)

### Custom Convention

[](#custom-convention)

Create a custom convention by extending `SerializerConvention`:

```
use Baraja\Serializer\Serializer;
use Baraja\Serializer\SerializerConvention;

class CustomConvention extends SerializerConvention
{
    private string $dateTimeFormat = 'c'; // ISO 8601
    private bool $rewriteNullToUndefined = true;
}

$convention = new CustomConvention();
$serializer = new Serializer($convention);
```

### Using Bridge Interfaces

[](#using-bridge-interfaces)

#### ItemsListInterface

[](#itemslistinterface)

Implement this interface for paginated or list results:

```
use Baraja\Serializer\Bridge\ItemsListInterface;

class UserList implements ItemsListInterface
{
    /** @param UserDTO[] $users */
    public function __construct(
        private array $users,
    ) {
    }

    public function getData(): array
    {
        return array_map(
            fn(UserDTO $user) => [
                'name' => $user->name,
                'email' => $user->email,
            ],
            $this->users,
        );
    }
}
```

**Convention:** `ItemsListInterface` objects must be placed in a key named `items`.

#### StatusCountInterface

[](#statuscountinterface)

Useful for filter tabs or status counts:

```
use Baraja\Serializer\Bridge\StatusCountInterface;

class OrderStatus implements StatusCountInterface
{
    public function __construct(
        private string $key,
        private string $label,
        private int $count,
    ) {
    }

    public function getKey(): string
    {
        return $this->key;
    }

    public function getLabel(): string
    {
        return $this->label;
    }

    public function getCount(): int
    {
        return $this->count;
    }
}

$statuses = [
    new OrderStatus('pending', 'Pending', 5),
    new OrderStatus('completed', 'Completed', 42),
];

$result = $serializer->serialize($statuses);
// Result: [
//     ['key' => 'pending', 'label' => 'Pending', 'count' => 5],
//     ['key' => 'completed', 'label' => 'Completed', 'count' => 42],
// ]
```

### Nette Paginator Support

[](#nette-paginator-support)

If `nette/utils` is installed, Paginator objects are automatically serialized:

```
use Nette\Utils\Paginator;

$paginator = new Paginator();
$paginator->setItemCount(100);
$paginator->setItemsPerPage(10);
$paginator->setPage(3);

$result = $serializer->serialize(['paginator' => $paginator]);
// Result: [
//     'paginator' => [
//         'page' => 3,
//         'pageCount' => 10,
//         'itemCount' => 100,
//         'itemsPerPage' => 10,
//         'firstPage' => 1,
//         'lastPage' => 10,
//         'isFirstPage' => false,
//         'isLastPage' => false,
//     ]
// ]
```

**Convention:** Paginator objects must be placed in a key named `paginator`.

### Translation Support

[](#translation-support)

If `baraja-core/localization` is installed, Translation objects are converted to strings:

```
use Baraja\Localization\Translation;

$translation = new Translation(['en' => 'Hello', 'cs' => 'Ahoj']);

$result = $serializer->serialize(['greeting' => $translation]);
// Result: ['greeting' => 'Hello'] (based on current locale)
```

### Price Support

[](#price-support)

If `baraja-core/ecommerce-standard` is installed, PriceInterface objects are serialized:

```
// Assuming $price implements PriceInterface

$result = $serializer->serialize(['price' => $price]);
// Result: [
//     'price' => [
//         'value' => '199.00',
//         'currency' => 'USD',
//         'html' => '$199.00',
//         'isFree' => false,
//     ]
// ]
```

⚠️ Conventions and Constraints
------------------------------

[](#warning-conventions-and-constraints)

### Enforced Conventions

[](#enforced-conventions)

1. **ItemsListInterface** must be in key `items`
2. **Paginator** must be in key `paginator`
3. **Maximum depth** is 32 levels
4. **Properties starting with `_`** are excluded

### Error Handling

[](#error-handling)

The serializer throws exceptions for:

- **LogicException**: Structure depth exceeds 32 levels
- **InvalidArgumentException**: Circular reference detected
- **InvalidArgumentException**: ItemsListInterface not in `items` key
- **InvalidArgumentException**: Paginator not in `paginator` key
- **InvalidArgumentException**: Unsupported value type

⚠️ Security Logging
-------------------

[](#warning-security-logging)

When a sensitive key with a non-BCrypt value is detected, the serializer logs a critical warning via Tracy Debugger (if available):

```
Security warning: User password may have been compromised!
The Baraja API prevented passwords being passed through the API in a readable form.

```

This helps identify potential security issues during development.

👥 Author
--------

[](#busts_in_silhouette-author)

**Jan Barasek** -

📄 License
---------

[](#page_facing_up-license)

`baraja-core/serializer` is licensed under the MIT license. See the [LICENSE](https://github.com/baraja-core/serializer/blob/master/LICENSE) file for more details.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance52

Moderate activity, may be stable

Popularity24

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity53

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

Total

2

Last Release

1324d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3382204?v=4)[baraja](/maintainers/baraja)[@baraja](https://github.com/baraja)

---

Top Contributors

[![janbarasek](https://avatars.githubusercontent.com/u/4738758?v=4)](https://github.com/janbarasek "janbarasek (9 commits)")

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/baraja-core-serializer/health.svg)

```
[![Health](https://phpackages.com/badges/baraja-core-serializer/health.svg)](https://phpackages.com/packages/baraja-core-serializer)
```

###  Alternatives

[mtdowling/jmespath.php

Declaratively specify how to extract elements from a JSON document

2.0k472.8M135](/packages/mtdowling-jmespathphp)[opis/closure

A library that can be used to serialize closures (anonymous functions) and arbitrary data.

2.6k230.0M284](/packages/opis-closure)[masterminds/html5

An HTML5 parser and serializer.

1.8k242.8M229](/packages/masterminds-html5)[sabberworm/php-css-parser

Parser for CSS Files written in PHP

1.8k191.2M65](/packages/sabberworm-php-css-parser)[michelf/php-markdown

PHP Markdown

3.5k52.4M345](/packages/michelf-php-markdown)[jms/metadata

Class/method/property metadata management in PHP

1.8k152.8M88](/packages/jms-metadata)

PHPackages © 2026

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