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

Underscore Php Laravel Package

anahkiasen/underscore-php

Underscore.php brings functional helpers to PHP inspired by Underscore.js. Chainable, collection and array utilities like map, filter, reduce, groupBy, sortBy, pluck, and more. Handy for concise data manipulation in any PHP project, including Laravel.

Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Add the package via Composer:

    composer require anahkiasen/underscore-php
    

    No Laravel-specific setup is required—it works as a standalone library.

  2. First Use Case Import the library and use a basic function (e.g., map or filter):

    use Underscore\Underscore;
    
    $numbers = [1, 2, 3, 4];
    $doubled = Underscore::map($numbers, function($n) { return $n * 2; });
    // Result: [2, 4, 6, 8]
    
  3. Where to Look First

    • Documentation: GitHub README (if archived, check cached versions).
    • Core Functions: Focus on map, filter, reduce, pluck, groupBy, and findWhere for Laravel collections.
    • Laravel Integration: Use as a drop-in replacement for Laravel’s built-in collection methods where needed.

Implementation Patterns

Usage Patterns

  1. Collection Manipulation Replace Laravel’s Collection methods with Underscore for functional programming:

    $users = collect([['name' => 'John'], ['name' => 'Jane']]);
    $names = Underscore::pluck($users->all(), 'name'); // ['John', 'Jane']
    
  2. Data Transformation Use map/reduce for complex transformations:

    $orders = [
        ['id' => 1, 'items' => [10, 20]],
        ['id' => 2, 'items' => [15]],
    ];
    $total = Underscore::reduce($orders, function($sum, $order) {
        return $sum + array_sum($order['items']);
    }, 0);
    // Result: 45
    
  3. Conditional Filtering Combine with filter/where for dynamic queries:

    $activeUsers = Underscore::filter($users, function($user) {
        return $user['active'] && $user['role'] === 'admin';
    });
    
  4. Laravel Service Providers Bind Underscore globally for reusable logic:

    // app/Providers/AppServiceProvider.php
    public function boot() {
        $this->app->singleton('underscore', function() {
            return new Underscore\Underscore();
        });
    }
    

    Then inject via constructor:

    public function __construct(private Underscore\Underscore $underscore) {}
    

Workflows

  • API Responses: Use map to transform Eloquent models to JSON:
    $data = Underscore::map($posts->toArray(), function($post) {
        return ['id' => $post['id'], 'title' => $post['title']];
    });
    
  • Form Requests: Validate and sanitize input with filter/reject:
    $cleanData = Underscore::pick($request->all(), ['name', 'email']);
    
  • Testing: Simplify test assertions with isEqual, isEmpty, etc.

Integration Tips

  • Laravel Collections: Use Underscore for operations not natively supported (e.g., groupBy with nested keys).
  • Blade Templates: Pass Underscore to views for client-side-like logic:
    @php
        $grouped = Underscore::groupBy($items, function($item) {
            return $item['category'];
        });
    @endphp
    
  • Event Listeners: Process queued jobs or events with each/forEach.

Gotchas and Tips

Pitfalls

  1. Archived Package

    • No active maintenance; test thoroughly in production.
    • Fork or extend if critical bugs arise (e.g., edge cases in reduce or pluck).
  2. Laravel Collection Conflicts

    • Avoid mixing Underscore and Laravel’s Collection methods on the same array:
      // ❌ Risky: Underscore modifies the array in-place.
      $collection = collect([1, 2, 3]);
      Underscore::map($collection->all(), ...); // Mutates original!
      
    • Fix: Clone arrays before passing to Underscore:
      Underscore::map(clone $collection->all(), ...);
      
  3. Callback Scope

    • Underscore callbacks use $this as the array item (like Underscore.js), which may break in Laravel’s context:
      // ❌ Unexpected $this binding
      Underscore::map($users, function() { return $this->name; });
      
    • Fix: Use arrow functions or explicit binding:
      Underscore::map($users, fn($user) => $user['name']);
      
  4. Performance

    • Underscore’s reduce/map are slower than Laravel’s Collection for large datasets.
    • Tip: Benchmark and prefer Laravel’s methods for critical paths.

Debugging

  • Unexpected Outputs: Use Underscore::inspect() to log complex objects:
    dd(Underscore::inspect($data));
    
  • Type Mismatches: Ensure arrays are properly structured (e.g., pluck fails on non-associative arrays).
  • Callback Errors: Wrap in try-catch for silent failures:
    try {
        $result = Underscore::filter($data, $callback);
    } catch (\Error $e) {
        $result = [];
    }
    

Config Quirks

  • No Laravel Config: Underscore is stateless; no config/underscore.php exists.
  • Customization: Extend the class for domain-specific functions:
    class CustomUnderscore extends Underscore\Underscore {
        public static function snakeCaseKeys(array $array) {
            return Underscore::map($array, function($item) {
                return is_array($item)
                    ? self::snakeCaseKeys($item)
                    : $item;
            }, 'keys');
        }
    }
    

Extension Points

  1. Add Custom Functions Override or extend the base class:

    Underscore\Underscore::mixin([
        'chunk' => function(array $array, $size) {
            // Custom implementation
        }
    ]);
    
  2. Laravel Facade Create a facade for cleaner syntax:

    // app/UnderscoreFacade.php
    class UnderscoreFacade extends \Illuminate\Support\Facades\Facade {
        protected static function getFacadeAccessor() {
            return 'underscore';
        }
    }
    

    Register in config/app.php:

    'aliases' => [
        'Underscore' => App\Facades\UnderscoreFacade::class,
    ],
    

    Usage:

    $result = Underscore::chunk($data, 2);
    
  3. Integration with Laravel Mix Bundle Underscore for frontend-backend consistency (if using PHP for JS-like logic).

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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests