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

Arraypath Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation: Add to composer.json:

    "require": {
        "mathiasgrimm/arraypath": "^2.0"
    }
    

    Run composer update.

  2. Register Class Alias (recommended for IDE autocompletion): In AppServiceProvider.php (or any bootstrap file):

    use MathiasGrimm\ArrayPath\ArrayPath;
    
    public function boot()
    {
        ArrayPath::registerClassAlias('A');
    }
    
  3. First Use Case: Replace a nested isset() check with A::get():

    // Before
    $name = isset($user['profile']['first_name']) ? $user['profile']['first_name'] : null;
    
    // After
    $name = A::get($user, 'profile/first_name');
    

Implementation Patterns

Core Workflows

  1. Data Retrieval:

    • Basic Get:
      $value = A::get($array, 'path/to/value');
      
    • With Default:
      $value = A::get($array, 'path/to/value', 'default');
      
    • In Controllers/Requests:
      $city = A::get($request->all(), 'user.address.city');
      
  2. Data Manipulation:

    • Set Values:
      A::set($array, 'user.profile.email', 'user@example.com');
      
    • Remove Values:
      $removedValue = A::remove($array, 'user.profile.email');
      
  3. Existence Checks:

    • Replace array_key_exists() chains:
      if (A::exists($config, 'app.settings.featureFlags')) {
          // Safe to proceed
      }
      
  4. Dynamic Paths (e.g., from user input):

    $path = $request->input('dynamic_path');
    $value = A::get($data, $path);
    

Integration Tips

  • Laravel Config: Replace config('app.settings.nested.key') with:

    $value = A::get(config('app.settings'), 'nested.key');
    
  • Form Requests: Use in prepareForValidation() to flatten nested arrays:

    $this->merge([
        'user_name' => A::get($this->all(), 'user/name'),
    ]);
    
  • API Responses: Sanitize nested data before returning:

    $response['user'] = A::get($data, 'user', []);
    
  • Testing: Assert array paths in PHPUnit:

    $this->assertEquals('John', A::get($user, 'profile/first_name'));
    

Advanced Patterns

  1. Custom Separators (e.g., for JSON-like paths):

    ArrayPath::setSeparator('.');
    $value = A::get($data, 'user.profile.name');
    
  2. Path Validation: Combine with A::exists() to validate required fields:

    if (!A::exists($request->all(), 'user.email')) {
        throw new \InvalidArgumentException('Email is required.');
    }
    
  3. Deep Merging: Use A::set() to merge nested arrays:

    $defaults = ['user' => ['role' => 'guest']];
    A::set($defaults, 'user.role', 'admin'); // Override
    

Gotchas and Tips

Pitfalls

  1. Empty Arrays:

    • A::set() on an empty array may not create intermediate keys as expected (fixed in v2.0.7, but test edge cases).
    • Workaround: Initialize with empty arrays if needed:
      $array = ['user' => []];
      A::set($array, 'user/profile', ['name' => 'John']);
      
  2. Non-String Keys:

    • Paths with non-string keys (e.g., 0/1/2) may behave unexpectedly.
    • Tip: Ensure paths use string keys or cast to string:
      A::get($array, (string) $dynamicKey);
      
  3. Default Values:

    • A::get() returns null for missing paths (not false or empty string).
    • Gotcha: Avoid:
      if (A::get($data, 'path')) { // Always false if path doesn’t exist!
      
    • Fix: Use A::exists() or provide a default:
      if (A::exists($data, 'path')) { ... }
      // or
      $value = A::get($data, 'path', '');
      
  4. Class Alias Scope:

    • The alias (A) is static and global. Avoid naming conflicts in large teams.
    • Tip: Use a custom namespace alias (e.g., App\A) to scope it:
      ArrayPath::registerClassAlias('App\A');
      
  5. Performance:

    • Not optimized for deeply nested loops (e.g., processing 1000+ items).
    • Tip: Benchmark against native PHP for critical paths.

Debugging Tips

  1. Path Errors:

    • A::get() silently returns null for invalid paths. Use A::exists() to debug:
      if (!A::exists($data, 'user.profile')) {
          dd($data); // Inspect structure
      }
      
  2. Circular References:

    • May cause infinite loops if arrays contain circular references.
    • Tip: Use get_debug_type() to detect:
      if (is_array($data) && get_debug_type($data) === 'array') {
          // Safe to use ArrayPath
      }
      
  3. IDE Issues:

    • Some IDEs may not autocomplete A:: if the alias isn’t registered early.
    • Fix: Register the alias in a global bootstrap file (e.g., bootstrap/app.php).

Extension Points

  1. Custom Logic:

    • Extend the package by subclassing MathiasGrimm\ArrayPath\ArrayPath:
      class CustomArrayPath extends ArrayPath {
          public static function customGet($array, $path) {
              // Add logic here
              return parent::get($array, $path);
          }
      }
      
  2. Path Sanitization:

    • Pre-process paths to handle special cases (e.g., URL-decoded paths):
      $path = urldecode($request->input('path'));
      $value = A::get($data, $path);
      
  3. Integration with Laravel:

    • Bind the package to the container for dependency injection:
      $this->app->singleton('arrayPath', function () {
          return new ArrayPath();
      });
      

Configuration Quirks

  1. Separator Persistence:

    • The separator is static and shared across all calls. Reset it if needed:
      ArrayPath::setSeparator('/'); // Default
      
  2. Case Sensitivity:

    • Paths are case-sensitive (e.g., user/Nameuser/name).
    • Tip: Normalize paths if case-insensitive access is needed:
      $normalizedPath = strtolower($path);
      
  3. Non-Associative Arrays:

    • Paths like 0/1/2 work but may not behave as expected for numeric keys.
    • Tip: Use string keys for reliability:
      A::set($array, 'items/0/name', 'Item 1');
      

Laravel-Specific Tips

  1. Request Data:

    • Use with Request objects by casting to array:
      $value = A::get($request->all(), 'user.name');
      
  2. Validation:

    • Combine with Laravel Validation:
      $validator = Validator::make($request->all(), [
          'user.name' => 'required|string',
      ]);
      // Or dynamically:
      $path = 'user.'.$request->input('field');
      $validator->sometimes($path, 'required', function () {
          return A::exists($request->all(), 'user');
      });
      
  3. Service Providers:

    • Register the alias in boot() to ensure it’s available early:
      public function boot()
      {
          ArrayPath::registerClassAlias('A');
      }
      
  4. Testing:

    • Mock A:: calls in tests:
      A::shouldReceive('get')->with($data, 'path')->andReturn('mocked');
      
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.
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
spatie/mailcoach-vapor