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.

View on GitHub
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.
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