Skip to content

KaririCode-Framework/kariricode-serializer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KaririCode Serializer

PHP 8.4+ CI License: MIT PHPStan Level 9 Tests Encoders Zero Runtime Deps ARFA KaririCode Framework

Multi-format serialization for PHP 8.4+ — JSON, XML, CSV, QueryString, zero dependencies.

Installation · Quick Start · Attribute-Driven · All Encoders · Architecture


The Problem

Multi-format serialization for PHP always pulls in heavy dependencies or loses the data contract:

// symfony/serializer: 7+ packages, complex config, annotation magic
// league/fractal: transformer boilerplate, no attribute support
// json_encode/decode alone: no groups, no field renaming, no XML/CSV

// Switching from JSON to XML means rewriting your serialization layer entirely.

The Solution

use KaririCode\Serializer\Provider\SerializerServiceProvider;

$engine = (new SerializerServiceProvider())->createEngine();

// One API, four formats — swap format string to change output
$json = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'json');
$xml  = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'xml', ['root' => 'user']);
$csv  = $engine->serialize([['name' => 'Walmir', 'age' => 30]], 'csv');
$qs   = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'query_string');

// RFC 8259 (JSON) · RFC 4180 (CSV) · RFC 3986 (URL) — built-in compliance

Requirements

Requirement Version
PHP 8.4 or higher
ext-simplexml Built-in (required for XML)
kariricode/property-inspector ^2.0

Installation

composer require kariricode/serializer

Quick Start

<?php

require_once __DIR__ . '/vendor/autoload.php';

use KaririCode\Serializer\Provider\SerializerServiceProvider;

$engine = (new SerializerServiceProvider())->createEngine();

// Serialize array to JSON
$result = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'json');
echo $result->getPayload();  // '{"name":"Walmir","age":30}'

// Deserialize JSON to array
$data = $engine->deserialize('{"name":"Walmir"}', 'json');
// ['name' => 'Walmir']

// XML with custom root tag
$result = $engine->serialize(['name' => 'Walmir'], 'xml', ['root' => 'user']);
// <user><name>Walmir</name></user>

Attribute-Driven DTO Serialization

use KaririCode\Serializer\Attribute\Serialize;

class UserDto
{
    #[Serialize(name: 'user_id', groups: ['admin'])]
    public int $id = 42;

    #[Serialize(groups: ['public', 'admin'])]
    public string $name = 'Walmir Silva';

    #[Serialize(ignore: true)]
    public string $passwordHash = '...';
}

$provider   = new SerializerServiceProvider();
$serializer = $provider->createAttributeSerializer();

// Serialize to JSON (public group)
$json = $serializer->serialize(new UserDto(), 'json', ['public']);
// {"name":"Walmir Silva"}

// Serialize to JSON (admin group)
$json = $serializer->serialize(new UserDto(), 'json', ['admin']);
// {"user_id":42,"name":"Walmir Silva"}

// Deserialize from JSON
$dto = $serializer->deserialize('{"name":"Walmir"}', UserDto::class, 'json');

All 4 Encoders

Format Encoder MIME Type PHP Functions
json JsonEncoder application/json json_encode/decode with JSON_THROW_ON_ERROR
xml XmlEncoder application/xml SimpleXMLElement + DOMDocument
csv CsvEncoder text/csv fputcsv/str_getcsv via php://temp
query_string QueryStringEncoder application/x-www-form-urlencoded http_build_query/parse_str

Adding Custom Encoders

use KaririCode\Serializer\Contract\Encoder;

final readonly class YamlEncoder implements Encoder
{
    public function encode(array $data, SerializationContext $context): string { /* ... */ }
    public function decode(string $payload, SerializationContext $context): array { /* ... */ }
    public function supports(string $format): bool { return $format === 'yaml'; }
    public function getFormat(): string { return 'yaml'; }
}

$registry = $provider->createRegistry();
$registry->register(new YamlEncoder());

Engine API (Programmatic)

$engine = (new SerializerServiceProvider())->createEngine();

$result = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'json');
$result->getPayload();      // '{"name":"Walmir","age":30}'
$result->getFormat();       // 'json'
$result->getPayloadSize();  // byte count

$data = $engine->deserialize('{"name":"Walmir"}', 'json');
// ['name' => 'Walmir']

// CSV with custom separator
$result = $engine->serialize([['a' => 1, 'b' => 2]], 'csv', ['separator' => ';']);

Ecosystem Position

DPO Pipeline:     Input → Validator → Sanitizer → Transformer → Business Logic
Infra Pipeline:   Object ↔ Normalizer ↔ Array ↔ ★ Serializer ★ ↔ String
Cross-Layer:      Request DTO ↔ Mapper ↔ Domain Entity ↔ Mapper ↔ Response DTO

The Serializer converts already-normalized arrays into wire-format strings for transport. It is the last step in the infrastructure pipeline before the payload leaves the application.


Architecture

Source layout

src/
├── Attribute/       Serialize — name, groups, ignore annotation
├── Configuration/   SerializerConfiguration (immutable)
├── Contract/        Encoder · SerializationContext · SerializerEngine · EncoderRegistry
├── Core/            SerializerEngine · SerializationContextImpl · InMemoryEncoderRegistry
├── Encoder/         JsonEncoder · XmlEncoder · CsvEncoder · QueryStringEncoder
├── Exception/       SerializationException
└── Provider/        SerializerServiceProvider — factory for engine & attribute serializer

Key design decisions

Decision Rationale ADR
Format-agnostic engine Swap format string — no code changes ADR-001
Serialization groups Field visibility per consumer without multiple DTOs ADR-002
RFC compliance JSON 8259, CSV 4180, URL 3986 ADR-003
Property Inspector integration Attribute scanning delegated to kariricode/property-inspector ADR-004
Zero encoder dependencies All 4 encoders use only PHP built-ins ADR-005

Specifications

Spec Covers
SPEC-001 Encoder interface and registration
SPEC-002 #[Serialize] groups and field mapping
SPEC-003 SerializeAttributeHandler contract and invariants

Project Stats

Metric Value
PHP source files 20
Source lines ~810
Test files 13
Test lines ~700
External runtime dependencies 1 (kariricode/property-inspector)
Encoder classes 4
Supported formats JSON, XML, CSV, QueryString
PHPStan level 9
PHP version 8.4+
ARFA compliance 1.3

Contributing

git clone https://github.com/KaririCode-Framework/kariricode-serializer.git
cd kariricode-serializer
composer install
kcode init
kcode quality  # Must pass before opening a PR

License

MIT License © Walmir Silva


Part of the KaririCode Framework ecosystem.

kariricode.org · GitHub · Packagist · Issues

About

Multi-format serialization engine for PHP 8.4+ — JSON, XML, CSV, QueryString, #[Serialize] attributes, powered by kariricode/property-inspector. ARFA 1.3

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages