transprime-research/arrayed
Arrayed brings fluent, chainable array helpers to Laravel and PHP, making it simple to filter, map, group, sort, and transform nested data with clean, readable syntax. A lightweight toolkit for everyday array manipulation without boilerplate.
transprime-research/arrayed is a small utility package for working with keyed array data in Laravel — most useful when you have associative arrays (config-like payloads, API responses, form data) where keys may be missing and you want predictable defaults instead of nested ?? chains or isset() guards.
Install:
composer require transprime-research/arrayed
First place to look: the package's Arrayed (or equivalent entry class) and its method list — read the README examples before touching your own code, since the API surface is intentionally thin and the value is in composing a few methods rather than learning a framework.
First use case: take a request payload or decoded JSON array with optional keys, wrap it, and read values with defaults so you never emit Undefined array key warnings:
$data = arrayed($request->validated());
$name = $data->get('user.name', 'Guest');
$roles = $data->get('user.roles', []);
Start by converting one controller or one DTO-ish array into a wrapped instance, confirm behaviour matches your expectations (especially around empty arrays vs. missing keys — see the 2.3.1 fix below), then decide whether to adopt it more widely.
Wrap at the boundary, not in the middle. Instantiate the wrapper once where data enters your app — a controller, a FormRequest, a job's handle(), an API client response — and pass the wrapped object down. This keeps defaulting and key-normalisation logic in one place.
Defaults per field, not ?? everywhere. Instead of:
$timeout = $config['timeout'] ?? $defaults['timeout'] ?? 30;
use a single read with an explicit fallback:
$timeout = arrayed($config)->get('timeout', 30);
Chained fallbacks for layered config. Useful when merging package defaults, app config, and per-tenant overrides — read each layer with the previous as default, so precedence is visible in code rather than implicit.
Guard against empty-but-present keys. Post-2.3.1, defaults are applied when the key's value resolves to an empty key set. This means you don't need to special-case [] before reading; but you do want to be explicit in tests that [] and "absent" behave the same for your use case — they now do by default, which may not always be what you want.
Pair with validation for anything user-supplied. The package handles shape (missing keys, defaults), not correctness. Run Validator/FormRequest first, then wrap the validated array — that way your defaults only paper over genuinely optional fields, not validation gaps.
Use it in tests as a fixture builder. Wrapping partial arrays in tests lets you assert on defaults without writing out every key, keeping fixtures short and making it obvious which fields a test actually cares about.
Don't wrap Eloquent models. Convert with $model->toArray() or ->only([...]) first if you must; the package is for arrays, and wrapping models hides attribute casting and accessor behaviour.
Default-on-empty behaviour changed in 2.3.1. The fix ("default value missing when keys are empty") means a key present but holding an empty array of keys now yields the supplied default rather than an empty result. Audit any code that relied on distinguishing "present but empty" from "absent" — if that distinction mattered, you need an explicit existence check alongside the read, not just a default.
Defaults are not deep merges. A fallback array typically replaces, not recursively merges, a partially-populated value. If you need merge semantics, do the merge yourself before wrapping, or read sub-keys individually.
Dot-notation can collide with literal keys. If your data legitimately contains keys with dots in them (common with dotted config names or flat env-style arrays), dotted path lookups may resolve differently than you expect. Keep dot-bearing keys in a flat wrapper or escape/prefix them.
null is a value. Decide up front whether null should trigger the default. Most wrappers treat "key exists with null" as present — if you want null-coalescing semantics you may need to normalise the array first (array_filter carefully, or explicit ??).
Debugging: when a default unexpectedly wins, dump both array_key_exists() and the raw value — the wrapper hides the difference between absent, empty, and null, which is exactly where bugs hide. A quick dd($raw, $wrapped) pair at the boundary saves a lot of guessing.
Version-pin consciously. 2.3.1 is an additive correctness fix, not a breaking change, so a minor-range constraint (^2.3) is safe — but since the semantics of empty keys shifted, add a regression test for your defaulting behaviour rather than trusting existing green tests to have covered it.
Extension points are minimal by design. This is a thin helper, not a framework — resist building abstractions on top of it. If you find yourself needing custom resolution, macros, or subclassing, a plain data_get() / small local helper is usually clearer than layering on the package.
Composer hygiene: keep it in require (not require-dev) only if runtime code reads arrays through it; otherwise require-dev keeps production vendor size down and signals intent.
How can I help you explore Laravel packages today?