magicsunday / jsonmapper
Map JSON to PHP
Fund package maintenance!
Requires
- php: ^8.3
- ext-json: *
- doctrine/inflector: ^2.0
- symfony/property-access: ^7.3 || ^8.0
- symfony/property-info: ^7.3 || ^8.0
- symfony/type-info: ^7.3 || ^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.65
- overtrue/phplint: ^9.0
- phpdocumentor/reflection-docblock: ^5.0 || ^6.0
- phpstan/phpstan: ^2.0
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^12.0
- rector/rector: ^2.0
Suggests
- phpdocumentor/reflection-docblock: In order to use the PhpDocExtractor this library is required too.
This package is auto-updated.
Last update: 2026-03-03 08:14:53 UTC
README
Map JSON data to strongly-typed PHP classes using Symfony's PropertyInfo and PropertyAccess components.
📌 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
- API reference
- Recipes
- Manual instantiation — custom extractors, name converters, class maps, collection mapping
- Type converters and custom class maps — custom type handlers, runtime class resolution
- Error handling strategies — strict vs. lenient mode, error collection
- Performance hints — PSR-6 type caching
- Using mapper attributes — ReplaceProperty, ReplaceNullWithDefaultValue
- Mapping JSON to PHP enums
- Mapping nested collections
- Using a custom name converter
🛠️ 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.