mathiasgrimm/arraypath
Convenient array manipulation for PHP, especially multidimensional arrays. Safely get, set, check existence, add or remove values using simple “a/b/c” paths, avoiding undefined index notices. Optional class alias (A) for cleaner calls and IDE autocomplete.
Pros:
isset()/array_key_exists() chains with a fluent, path-based API (A::get(), A::set(), etc.), improving readability and maintainability.$arrayData, $index, $value, $default), reducing cognitive overhead for developers.data_get()/data_set()-like workflows.A) enables autocompletion and static analysis (e.g., PHPStorm, Psalm), accelerating development.Cons:
null handling.user.*.address).null for missing keys (unlike Laravel’s data_get() with null defaults).isset() spaghetti into A::exists()/A::get() calls.A::get($data, 'user/profile/name')) across teams.array_walk_recursive).null values.A::set() with non-array inputs).isset() (microseconds per operation).data_get()/data_set() (Laravel 5.5+) or Arr:: helpers (Laravel 5.x) for basic cases.array_key_first() (PHP 7.3+), null coalescing (??), or Spatie’s array-to-object for OOP approaches.null values, and strict typing scenarios.A::remove() or custom separators that Laravel’s Arr helpers lack?"A::get() over data_get()? How will we enforce consistency?"A::get($data, [0, 'name'])) or circular references?"composer require mathiasgrimm/arraypath:^2.0.A) enables static analysis (e.g., Psalm, PHPStan).Collection instances; cast to array first:
A::get((array) $request->input(), 'user.name');
Pilot Phase (1–2 weeks):
isset() chain with A::get().// Before
$name = $request->input('user.profile.name', null);
if ($name === null) {
return response()->json(['error' => 'Missing name'], 400);
}
// After
$name = A::get($request->all(), 'user.profile.name');
if ($name === null) {
return response()->json(['error' => 'Missing name'], 400);
}
Gradual Rollout (4–6 weeks):
isset() patterns:
if\s*\(\s*isset\s*\(\s*\$data\[[^\]]*\]\s*\)\s*\)\s*\{.*?\}
A::exists() or A::get().// Before
if (isset($config['app']['debug']) && $config['app']['debug'] === true) {
$debug = true;
} else {
$debug = false;
}
// After
$debug = A::get($config, 'app.debug', false);
Alias Registration:
AppServiceProvider::boot():
public function boot()
{
ArrayPath::registerClassAlias('A');
// Or custom alias: ArrayPath::registerClassAlias('App');
}
Testing:
public function testArrayPathGet()
{
$data = ['user' => ['name' => 'John']];
$this->assertEquals('John', A::get($data, 'user.name'));
$this->assertNull(A::get($data, 'user.age'));
$this->assertEquals('default', A::get($data, 'user.age', 'default'));
}
| Feature | Compatibility Notes |
|---|---|
| PHP 5.3–7.4 | Fully supported (tested in package). |
| PHP 8.0+ | Unverified: May require backports for strict typing or JIT. |
| Laravel 5.x–8.x | Works with all versions (no framework dependencies). |
| Custom Separators | Supported (e.g., A::setSeparator('.')), but enforce consistency across codebase. |
| Non-String Keys | Limited: Paths like `A::get($data, [0, 'name'] |
How can I help you explore Laravel packages today?