Weave Code
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 Reader Laravel Package

codeliner/array-reader

Read values from multidimensional PHP arrays using dot-paths with escaping for dotted keys. Typed getters like stringValue() accept defaults when paths are missing, and pathExists() lets you distinguish null values from non-existent paths.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require codeliner/array-reader:~2.0
    

    Add to composer.json under require:

    "codeliner/array-reader": "^2.0"
    
  2. Basic Usage:

    use Codeliner\ArrayReader\ArrayReader;
    
    $reader = new ArrayReader([
        'user' => [
            'name' => 'John',
            'details' => [
                'age' => 30,
                'email' => 'john@example.com'
            ]
        ]
    ]);
    
    // Fetch values with dot notation
    $name = $reader->stringValue('user.name'); // 'John'
    $age = $reader->intValue('user.details.age'); // 30
    

First Use Case: Safe Array Access

Replace direct array access (e.g., $array['user']['name']) with ArrayReader to avoid UndefinedIndex or UndefinedOffset errors. Use default values for missing paths:

$email = $reader->stringValue('user.details.email', 'default@example.com');
// Returns 'john@example.com' if exists, otherwise 'default@example.com'

Implementation Patterns

1. Type-Specific Value Retrieval

Leverage type-specific methods (stringValue(), intValue(), boolValue(), etc.) to enforce type casting and avoid runtime type errors:

$isActive = $reader->boolValue('user.is_active', false); // Casts to boolean

2. Path Validation

Use pathExists() to check for nested keys before accessing them (useful for conditional logic):

if ($reader->pathExists('user.address.city')) {
    $city = $reader->stringValue('user.address.city');
}

3. Dynamic Path Construction

Build paths dynamically (e.g., from user input or config) while escaping dots in keys:

$dynamicPath = 'user.profile.' . str_replace('.', '\.', $profileKey);
$value = $reader->stringValue($dynamicPath);

4. Integration with Laravel

  • Form Requests: Validate nested array paths safely:

    $this->validate($request, [
        'user.name' => 'required|string',
        'user.details.age' => 'integer|min:18',
    ]);
    

    Use ArrayReader to parse validated data:

    $reader = new ArrayReader($request->validated());
    $name = $reader->stringValue('user.name');
    
  • Service Providers: Inject ArrayReader to handle config arrays:

    public function register()
    {
        $this->app->singleton(ArrayReader::class, function ($app) {
            return new ArrayReader(config('app.settings'));
        });
    }
    

5. Data Transformation

Chain ArrayReader with Laravel’s collect() for fluent transformations:

$collection = collect($data)->mapWithKeys(function ($item) {
    $reader = new ArrayReader($item);
    return [
        $reader->stringValue('id') => [
            'name' => $reader->stringValue('name'),
            'active' => $reader->boolValue('is_active', false),
        ]
    ];
});

Gotchas and Tips

Pitfalls

  1. Dot Escaping:

    • Forgetting to escape dots in keys (e.g., user.name.first vs. user.name\.first) will throw UndefinedIndex.
    • Fix: Use str_replace('.', '\.', $key) when constructing paths dynamically.
  2. Type Casting:

    • Methods like intValue() will cast strings (e.g., "30"30) but fail on invalid strings (e.g., "abc"0).
    • Fix: Use filterVar() or is_numeric() for stricter validation:
      $age = $reader->intValue('user.age');
      if (!is_numeric($reader->stringValue('user.age'))) {
          throw new \InvalidArgumentException('Age must be numeric');
      }
      
  3. Null vs. Missing Path:

    • pathExists() returns true for null values. Use array_key_exists() or isset() on the underlying array if you need to distinguish:
      $array = $reader->getArray();
      if (isset($array['user']['name'])) {
          // Key exists (even if value is null)
      }
      
  4. Performance:

    • ArrayReader traverses the array recursively for each call. For high-frequency access (e.g., loops), cache the reader or pre-fetch values:
      $values = [
          'name' => $reader->stringValue('user.name'),
          'age' => $reader->intValue('user.age'),
      ];
      

Debugging Tips

  1. Inspect the Underlying Array: Use $reader->getArray() to debug the raw structure:

    dd($reader->getArray());
    
  2. Path Validation: Test paths incrementally:

    if (!$reader->pathExists('user.profile')) {
        throw new \RuntimeException("Invalid path: user.profile");
    }
    
  3. Type-Specific Issues:

    • For boolValue(), empty strings ("") return false. Use stringValue() + explicit casting if needed:
      $isActive = (bool) $reader->stringValue('user.is_active');
      

Extension Points

  1. Custom Value Types: Extend ArrayReader to add domain-specific methods (e.g., dateValue()):

    class ExtendedArrayReader extends ArrayReader {
        public function dateValue(string $path, ?\DateTimeInterface $default = null): ?\DateTimeInterface {
            $value = $this->stringValue($path, $default?->format('Y-m-d'));
            return $default ? new \DateTime($value) : null;
        }
    }
    
  2. Path Normalization: Override normalizePath() to handle custom path formats (e.g., / separators):

    protected function normalizePath(string $path): string {
        return str_replace(['/', '\\'], '.', $path);
    }
    
  3. Laravel Service Binding: Bind the extended reader in AppServiceProvider:

    $this->app->bind(ExtendedArrayReader::class, function ($app) {
        return new ExtendedArrayReader(config('app.settings'));
    });
    

Config Quirks

  • Immutable Arrays: ArrayReader does not modify the input array. If you need mutability, clone the array first:
    $mutableArray = $reader->getArray();
    $mutableArray['new_key'] = 'value';
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky