pixelshaped/flat-mapper-bundle
Symfony bundle for the Flat Mapper library, enabling fast mapping between flat arrays and PHP objects. Configure mappings with attributes or PHP, then hydrate DTOs from database rows, forms, or API payloads and flatten objects back with minimal boilerplate.
The package in question is pixelshaped/flat-mapper-bundle, the Symfony integration for the framework-agnostic pixelshaped/flat-mapper library. In a Laravel codebase you will almost always want the core library, not the bundle — install with composer require pixelshaped/flat-mapper. Pull the bundle in only if you are also maintaining a Symfony service that shares mapping definitions.
2.4.0 is an additive release (one PR: YAML mapping). Nothing is deprecated and nothing breaks for 2.3.x users, so pinning ^2.4 is safe.
Where to look first:
FlatMapper entry point and its map() signature — that is the whole API surface you will touch day to day.target.property => source.key pairs, plus optional transformers.First use case: hydrating DTOs from a joined query. DB::select() gives you flat rows like order_id, order_total, customer_name, customer_city; the mapper turns each row into Order with a nested Customer object, with no manual new Customer(...) plumbing in the repository.
$orders = collect(DB::select($sql))
->map(fn (array $row) => $flatMapper->map($row, Order::class, $mapping));
Mapping-driven repositories. Keep mapping arrays in dedicated classes (App\Mapping\OrderMapping) and inject/return them from a static method. DTOs stay dumb; mapping stays testable without a database — just feed it an array fixture.
Dot notation for nesting. Keys like customer.address.city build nested objects automatically. This is the main reason to reach for the package over hand-written hydrators: joined result sets with three or four levels of nesting stop being a chore.
YAML mapping (new in 2.4.0). The bundle now accepts mapping definitions in YAML. In Laravel there is no bundle config loader, so treat this as a format, not a feature: parse the YAML once at boot (Symfony\Component\Yaml\Yaml::parseFile(), or yaml_parse_file() if the extension is present), cache the resulting array, and pass it to map(). Use it when non-PHP stakeholders (analysts, ops) need to adjust field mappings without touching PHP — that is the real win of 2.4.0.
Transformers as the extension seam. Anything the flat-to-object walk cannot express goes in a transformer: casting '1' to true, exploding a comma-joined column into an array, resolving an ID into an enum case, defaulting a missing key. Transformers should be stateless and constructor-free so they can be resolved from the container cheaply.
Collections and chunking. Because the input is flat rows, streaming works naturally: ->chunk(1000) or LazyCollection::make() over a cursor, mapping each row as it arrives. Avoid materialising a 500k-row result set just to map it.
Testing. Unit-test mappings against array fixtures — no DB, no factories. Assert the resulting object graph with assertEquals, not identity.
config/flat-mapper.php. Anything the bundle does (YAML discovery, DI wiring, caching) you must reproduce by hand in AppServiceProvider.Yaml::parseFile() inside a request is a per-request disk hit and parse. Cache the parsed array (Cache::rememberForever, or commit a generated PHP array file) and bust it on deploy.Arr::dot() first or you will get silent nulls.id, name, and created_at. Alias every column (customer_name, order_created_at) or you will silently hydrate the wrong property.'12.50' and '1'. Declared float/bool/enum properties will blow up (or, with strict types off, silently misbehave). Cast in transformers and make the cast explicit in the mapping.null or an empty object, and encode that decision in a transformer rather than relying on default behaviour.How can I help you explore Laravel packages today?