magicsunday/jsonmapper

Map JSON to PHP

Maintainers

Package info

github.com/magicsunday/jsonmapper

pkg:composer/magicsunday/jsonmapper

Fund package maintenance!

paypal.me/magicsunday

Statistics

Installs: 8 725

Dependents: 2

Suggesters: 0

Stars: 2

Open Issues: 0

3.0.4 2026-03-03 08:12 UTC

README

Map JSON data to strongly-typed PHP classes using Symfony's PropertyInfo and PropertyAccess components.

CI

PHPStan Max Level PHPUnit 12 Rector 2.0 PSR-12

PHP Version

Latest version License

📌 Overview

JsonMapper is a PHP library that maps JSON data to strongly-typed PHP classes (DTOs, value objects, entities) using reflection and PHPDoc annotations. It leverages Symfony's PropertyInfo and PropertyAccess components to provide flexible, extensible JSON-to-PHP object mapping.

Key Value
Package magicsunday/jsonmapper
PHP ^8.3
Main API MagicSunday\JsonMapper
Output Mapped PHP objects + optional MappingReport

❓ What is this?

JsonMapper takes decoded JSON (via json_decode) and hydrates typed PHP objects, including nested objects, collections, enums, DateTime values, and custom types. It supports both lenient and strict mapping modes with detailed error reporting.

🎯 Why does this exist?

Mapping API responses or configuration payloads to typed PHP classes is a common task that involves repetitive boilerplate. JsonMapper automates this with a clean, extensible architecture based on Symfony components, supporting advanced scenarios like polymorphic APIs, custom name conversion, and recursive collection handling.

🚀 Usage

composer require magicsunday/jsonmapper

Quick start

namespace App\Dto;

use ArrayObject;

final class Comment
{
    public string $message;
}

/**
 * @extends ArrayObject<int, Comment>
 */
final class CommentCollection extends ArrayObject
{
}

/**
 * @extends ArrayObject<int, Article>
 */
final class ArticleCollection extends ArrayObject
{
}

final class Article
{
    public string $title;

    /**
     * @var CommentCollection<int, Comment>
     */
    public CommentCollection $comments;
}
require __DIR__ . '/vendor/autoload.php';

use App\Dto\Article;
use App\Dto\ArticleCollection;
use MagicSunday\JsonMapper;

$single = json_decode('{"title":"Hello world","comments":[{"message":"First!"}]}', associative: false, flags: JSON_THROW_ON_ERROR);
$list = json_decode('[{"title":"Hello world","comments":[{"message":"First!"}]},{"title":"Second","comments":[]}]', associative: false, flags: JSON_THROW_ON_ERROR);

$mapper = JsonMapper::createWithDefaults();

$article = $mapper->map($single, Article::class);
$articles = $mapper->map($list, Article::class, ArticleCollection::class);

JsonMapper::createWithDefaults() wires the default Symfony PropertyInfoExtractor (reflection + PhpDoc) and a PropertyAccessor. For custom extractors, caching, or a specialised accessor see Manual instantiation.

PHP classes

Annotate all properties with the requested type. For collections, use the phpDocumentor collection annotation type:

/** @var SomeCollection<DateTime> $dates */
/** @var SomeCollection<string> $labels */
/** @var Collection\\SomeCollection<App\\Entity\\SomeEntity> $entities */

📚 Documentation

🛠️ Development

Prerequisites:

  • PHP ^8.3
  • Extensions: json

Install dependencies:

composer install

Run the mandatory quality gate:

composer ci:test

ci:test includes:

  • Linting (phplint)
  • Unit tests (phpunit)
  • Static analysis (phpstan)
  • Refactoring dry-run (rector --dry-run)
  • Coding standards dry-run (php-cs-fixer --dry-run)
  • Copy/paste detection (jscpd)

🤝 Contributing

See CONTRIBUTING.md for contributor workflow and minimal setup.

If contributions are prepared or modified by an LLM/agent, follow AGENTS.md.