Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Array Map Keys Laravel Package

aviator/array-map-keys

A small PHP utility for transforming array keys throughout nested arrays. Pass a callback to map every key, including helpers for common conversions like snake_case to camelCase. Handy for normalizing config arrays or API payloads before processing.

View on GitHub
Deep Wiki
Context7

Getting Started

This package solves one narrow problem: array_map() hands your callback the value but not the key, so any transformation where the output depends on the key (renaming, prefixing, filtering by key, building id => label maps) forces you into foreach. The package adds a key-aware array_map.

1. Install and confirm the surface area first. The library is a single-purpose utility, so the whole API is visible in under a minute:

composer require aviator/array-map-keys

Then open vendor/aviator/array-map-keys/composer.json. Look at autoload:

  • If there is a files entry, the package registers a global helper function you can call anywhere.
  • If it is PSR-4 only, you are instantiating a class or calling a static method.

Read vendor/aviator/array-map-keys/src/ — for a package this small (last release 2017, 3 stars, 0 dependents) you should never adopt it without reading the source, because there is no community usage to fall back on.

2. Smoke-test the exact contract in Tinker. Two things vary between implementations and both will bite you: argument order (key, value vs value, key) and return shape (a bare value that replaces the value with the key preserved, vs a [key => value] pair that rebuilds the array).

php artisan tinker
>>> array_map_keys(fn ($key, $value) => [$key => $value * 2], ['a' => 1, 'b' => 2]);

Whatever that prints is your contract. Write it down.

3. First real use case. Building lookup maps from keyed data you already hold — config arrays, cached payloads, pluck() results, or DTO hydration — where a Collection would be overkill or isn't available yet:

$roles = ['admin' => 1, 'editor' => 2, 'viewer' => 3];

// Invert: permission level => role name
$byLevel = array_map_keys(fn ($name, $level) => [$level => $name], $roles);
// [1 => 'admin', 2 => 'editor', 3 => 'viewer']

Implementation Patterns

Normalize inbound payloads before validation. Form/API payloads often arrive as ['field_name' => ...] lists or keyed-by-index arrays. Key-aware mapping is a clean place to convert key casing or flatten a nested keyed structure:

$camel = array_map_keys(
    fn ($key, $value) => [Str::camel($key) => $value],
    $request->validated()
);

Namespace cache keys. Prefixing every key in a config-derived array is a one-liner:

$cacheKeys = array_map_keys(
    fn ($key, $value) => ["reports.{$key}" => $value],
    config('reports.sections')
);

Wrap it behind your own helper. Do not sprinkle a 2017 third-party global function through your codebase. Put the call site behind something you own:

// app/Support/Arr.php
public static function remapKeys(array $array, callable $callback): array
{
    return array_map_keys($callback, $array); // the only call site in the app
}

Now replacing it with Arr::mapWithKeys() or a native foreach is a three-line change, and your IDE/PHPStan only needs one stub.

Use it on plain arrays, not Eloquent collections. On collections you already have mapWithKeys() (Laravel 5.4+) and chaining. This package earns its place in the gap before hydration: config, JSON from cache, package-provided arrays, DTOs, and code that deliberately avoids the container.

Pair it with array_filter for key-driven pruning. array_filter($arr, ..., ARRAY_FILTER_USE_KEY) handles deletion; this handles reshaping. Composing the two is clearer than a single foreach doing both:

$public = array_filter($settings, fn ($k) => ! Str::startsWith($k, '_'), ARRAY_FILTER_USE_KEY);
$prefixed = array_map_keys(fn ($k, $v) => ["app.{$k}" => $v], $public);

Gotchas and Tips

Verify argument order in a test, not in your head. fn ($key, $value) vs fn ($value, $key) is the single most likely source of a silently wrong result — PHP won't complain, you'll just get transposed data. Cover one call with a unit test asserting the exact output with assertSame.

Duplicate output keys overwrite silently. If your callback maps two inputs to the same output key, the last one wins with no warning. If collisions are possible, validate the input's cardinality against the output before trusting the result.

PHP coerces numeric-string keys. '1' becomes int(1), but '01' stays a string. Any key-building logic producing zero-padded or numeric keys will produce a mixed-type array, which then surprises json_encode, ksort, and strict comparisons. Cast explicitly in the callback if type matters.

Stale dependency hygiene. Last tagged release is 2017. The code is almost certainly a few lines and will run fine on modern PHP, but the package is unmaintained by definition: it won't get a PHP 8.x compatibility fix. Pin it, run composer audit, and if you keep it long-term, vendor the function into app/Support with a replace entry in composer.json so the dependency graph stops carrying dead weight.

Static analysis will flag the global function. PHPStan and Psalm don't know it exists. Add a stub file (or a @method-free plain function declaration) to your phpstan.neon scanFiles/stubFiles rather than sprinkling @phpstan-ignore-next-line.

Check for function-name collisions on autoload. Global-function packages register via files autoload, which loads eagerly. If another package defines the same name you get a fatal error at boot, not a graceful failure. composer dump-autoload -o plus a php -r "var_dump(function_exists('array_map_keys'));" will tell you quickly.

Extension point is the callback, not the package. Everything useful happens in your closure. Keep callbacks pure and single-purpose; when a callback needs the container, a repository, or a model, that's the signal to stop using a mapping utility and write an explicit loop or a dedicated transformer class.

Debugging: dd(array_map_keys(...)) mid-pipeline, and diff the result against the input with array_diff_key/array_diff_assoc to see exactly which keys moved, vanished, or collided.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core