Installation:
composer require igorw/get-in
Add the namespace to your composer.json aliases (optional but recommended):
"autoload": {
"files": ["vendor/igorw/get-in/src/functions.php"]
}
Run composer dump-autoload.
First Use Case:
Replace a nested isset check with get_in:
// Before
$darkMode = isset($user['preferences']['theme']['darkMode'])
? $user['preferences']['theme']['darkMode']
: false;
// After
$darkMode = igorw\get_in($user, ['preferences', 'theme', 'darkMode'], false);
Key Functions to Explore:
get_in: Fetch nested values with defaults.assoc_in: Set nested values (creates intermediate arrays if needed).update_in: Modify nested values via a callback.src/functions.php (100 lines) to understand edge cases.Arr::get() for hybrid traversal (e.g., get_in($request->all(), ['user', 'id'])).Pattern: Replace repetitive isset checks or Arr::get with defaults.
// API Response Handling
$userId = igorw\get_in($apiResponse, ['data', 'user', 'id'], null);
if ($userId) {
// Proceed
}
// Config Overrides
$timeout = igorw\get_in(config('services'), ['api', 'timeout'], 30);
Pattern: Use update_in for conditional or dynamic modifications.
// Sanitize API Input
$cleanedData = igorw\update_in(
$request->all(),
['user', 'name'],
fn($name) => trim(strtolower($name))
);
// Increment a Counter
$data = igorw\update_in($stats, ['visits'], fn($count) => $count + 1);
Pattern: Build paths dynamically (e.g., from user input or config).
$path = explode('.', $request->input('path'));
$value = igorw\get_in($data, $path, 'default');
Pattern: Combine with Laravel helpers for seamless adoption.
// Eloquent Relationships
$user = User::find(1);
$email = igorw\get_in($user->toArray(), ['profile', 'contact', 'email'], 'no-email@example.com');
// Request Data
$theme = igorw\get_in($request->json()->all(), ['preferences', 'theme'], 'light');
// Config Merging
$merged = igorw\assoc_in(
config('app.settings'),
['features', 'analytics'],
igorw\get_in($envConfig, ['analytics'], false)
);
Pattern: Chain operations for complex transformations.
$processed = igorw\update_in(
$data,
['user', 'metadata', 'lastActive'],
fn($timestamp) => now()->diffInSeconds($timestamp)
);
Arr::get() for simple, flat traversals (e.g., Arr::get($array, 'key')).get_in:
/** @return string|null */
$value = igorw\get_in($data, ['path'], null);
get_in in unit tests:
$this->partialMock()
->shouldReceive('get_in')
->with(['data', 'key'])
->andReturn('mocked');
// Benchmark: get_in vs. manual traversal
$data = ['a' => ['b' => ['c' => 1]]];
$start = microtime(true);
igorw\get_in($data, ['a', 'b', 'c']);
$time = microtime(true) - $start;
Non-Array Inputs:
InvalidArgumentException if the first argument isn’t traversable.if (!is_array($data)) {
throw new \InvalidArgumentException('Input must be an array.');
}
Mutable State in update_in:
$newData = igorw\update_in(clone $data, ['path'], $callback);
Default Value Confusion:
null values).
$data = ['a' => null];
igorw\get_in($data, ['a', 'b'], 'default'); // Returns null (not 'default')
Key Collisions:
0 or a string that could be misinterpreted as an array index, behavior may vary.['0', 'key'] instead of [0, 'key']).IDE Autocompletion:
['user', 'profile'].phpstan to catch invalid paths early.Enable Error Reporting:
error_reporting(E_ALL);
ini_set('display_errors', 1);
Helps catch InvalidArgumentException for non-array inputs.
Log Paths:
$path = ['user', 'profile', 'email'];
$value = igorw\get_in($data, $path, null);
logger()->debug("Path {$path[0]}->...->{$path[count($path)-1]}: {$value}");
Validate Paths:
function isValidPath(array $data, array $path): bool {
$current = $data;
foreach ($path as $key) {
if (!array_key_exists($key, $current)) {
return false;
}
$current = $current[$key];
}
return true;
}
get_in:
function getInWithFallback(array $data, array $path, $default = null, callable $fallback = null) {
$value = igorw\get_in($data, $path, $default);
return $fallback ? $fallback($value) : $value;
}
Custom Default Factories:
function get_in_with_factory(array $data, array $path, callable $factory) {
return igorw\get_in($data, $path, $factory());
}
Path Normalization:
function normalizePath(array $path): array {
return array_map('strval', $path); // Ensure all keys are strings
}
Laravel Service Provider:
// app/Providers/AppServiceProvider.php
public function boot() {
app()->bind('getIn', function() {
return new class {
public function __invoke(array $data, array $path, $default = null) {
return igorw\get_in($data, $path, $default);
}
};
});
}
JSONPath-like Queries:
function jsonPathGet(array $data, string $query) {
$path = explode('.', $query);
return igorw\get_in($data, $path);
}
Request Data:
get_in($request->all(), ['user', 'id']) works, but ensure $request->all() returns an array.$request->json()->all() for JSON requests.Eloquent Models:
How can I help you explore Laravel packages today?