divineomega/array_undot
array_undot expands dot-notation keys back into nested PHP arrays, the inverse of Laravel’s array_dot helper. Turn ['user.name' => 'Jane'] into ['user' => ['name' => 'Jane']] for configs, form data, and validation. Lightweight with a simple API.
What the package is: array_undot performs the inverse of Laravel's array_dot / Arr::dot() helper — it takes a single-level array keyed with dot notation (['user.name' => 'Ada', 'user.roles.0' => 'admin']) and expands it into a nested multi-dimensional array. It is a single-purpose, pure-data transformation utility with no I/O, no persistence, no service dependencies, and no runtime configuration surface.
Architecture fit: Narrow but well-defined. It fits anywhere a configuration, form, or flatten/unflatten boundary exists — hydrating flat env/config payloads into nested structures, round-tripping data through a dot-keyed store, or translating between flat and nested representations at an API or persistence boundary. It is not an architectural component; it is a leaf utility. The correct mental model is "a function we happen to source from Composer," not "a dependency."
Integration feasibility: Trivially high on mechanics — one Composer require, near-zero configuration, no service provider needed in most cases (verify whether the package registers a global array_undot() function via autoload.files, which is the author's common pattern). The real feasibility question is necessity, not effort.
Primary technical risk — redundancy. Laravel shipped a native Arr::undot() in 5.8 (2019). If our stack is Laravel ≥ 5.8, this package duplicates first-party, framework-maintained behaviour and adds a third-party supply-chain link for zero functional gain. That single fact should dominate the decision.
Secondary technical risks:
'app.version' as a literal key vs. a nested path), empty segments ('a..b'), leading/trailing dots, and partial-path collisions ('a' => 'x' alongside 'a.b' => 'y') all require a defined policy. Silent last-write-wins overwrite is the likely behaviour and is the most dangerous failure mode, because it corrupts data without erroring. Must be verified against our inputs before adoption.'items.0.name' produces a list or a string-keyed array matters for downstream JSON serialization and consumers that distinguish [] from {}.Key questions:
Arr::undot() available? If yes, what does this package buy us?Stack fit: Excellent mechanical fit with Laravel/Composer; it is explicitly designed as the counterpart to a first-party Laravel helper. Poor strategic fit precisely because the framework already solved this. For Symfony, Slim, or vanilla PHP, it fits but competes against a small internal function with no license or supply-chain overhead.
Migration path — recommended order:
Arr::undot(). Zero new dependencies, first-party maintenance, identical intent. This is the default answer and should require justification to deviate from.If we do adopt it:
composer.json; do not float.App\Support\ArrayExpander::undot()) with our own contract and tests, so the vendor is swappable in one file. This converts an external dependency into an implementation detail and neutralises the abandonment risk.composer.json for autoload.files global function registration; if present, confirm no collision with Arr/array_undot elsewhere.Compatibility and sequencing: PHP version support must be checked against our runtime matrix — a low-traffic package can lag on new PHP majors. Sequence the work as: (a) requirements and edge-case semantics agreed, (b) native-vs-helper-vs-package decision, (c) characterisation tests written first, (d) implementation swapped in behind the adapter, (e) dependency recorded in the SBOM with license classification.
Sequencing risk: Low. This touches a leaf transformation, not a data contract, provided it is introduced behind an adapter. There is no coordinated release or data migration required.
Maintenance: Near-zero runtime maintenance — the code is a pure function with no external surface. The maintenance burden is dependency lifecycle, not operations: version bumps, PHP compatibility, and periodic review of whether the package still earns its place. In practice, adopting it costs more over a 3-year horizon than a 15-line internal helper. Set a review trigger rather than a recurring task.
Support: No vendor support. Community-only, single maintainer, no security disclosure process. If it breaks, we fix it or fork it. Mitigation: the code is small enough to fork and vendor into our repo in an afternoon, which also dissolves the LGPL redistribution concern (we would carry the license and our modifications). For a 24-star package, "we can fork it" is the honest support plan.
Scaling: Compute scaling is a non-issue — O(n) over input size, negligible for config- and form-scale payloads. Two scaling caveats worth noting:
Failure modes:
| Mode | Impact | Mitigation |
|---|---|---|
Silent overwrite on colliding paths (a vs a.b) |
Data corruption, no error raised | Validate/sanitise input; test explicitly |
| Dotted literal keys misinterpreted as nesting | Wrong shape, downstream type errors | Encode/escape keys at the boundary; document the constraint |
| Numeric segments produce string keys or vice versa | JSON shape differences break consumers | Assert on serialised output in tests |
| Global function collision from autoload | Fatal error or wrong implementation bound | Inspect composer.json; namespace-adapt |
| Package abandoned / PHP major breaks | Blocked upgrades | Adapter wrapper + fork escape hatch |
| LGPL in redistributed artifact | Legal/compliance finding | Classify in SBOM; confirm with legal |
Ramp-up: Effectively zero for any PHP developer — the concept is one sentence and the API is a single call. The genuine ramp-up is semantic, not syntactic: teams must learn the escaping and collision rules we standardise on, otherwise they will quietly assume the wrong behaviour at call sites. Budget the onboarding time on the edge-case policy document, not on the library.
Overall TPM position: Low technical risk, low operational burden, but equally low value — and the value is largely already provided by the framework. Recommend do not add as a dependency for Laravel ≥ 5.8 projects; use Arr::undot(). For non-Laravel or semantics-sensitive needs, build a tested internal helper. Reserve adoption for cases with an immediate, documented need and a stated willingness to fork, and route the LGPL-3.0 question through legal before any redistribution.
How can I help you explore Laravel packages today?