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

Iterators Laravel Package

loophp/iterators

loophp/iterators adds “missing” PHP iterators and iterator aggregates for lazy, composable pipelines: caching rewindable generators, chunk/map/filter/reduce/sort/unique/concat/pack/unpack, plus typed, random, recursive, and resource-based iterables.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require loophp/iterators
    

    Add to composer.json if using Laravel's autoloader:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Loophp\\Iterators\\": "vendor/loophp/iterators/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case: Transform a Laravel collection into an iterable with MapIterableAggregate:

    use Loophp\Iterators\MapIterableAggregate;
    use Illuminate\Support\Collection;
    
    $collection = collect([1, 2, 3]);
    $iterator = new MapIterableAggregate($collection, fn($item) => $item * 2);
    
    foreach ($iterator as $value) {
        // Outputs: 2, 4, 6
    }
    
  3. Key Entry Points:

    • src/IterableIteratorAggregate.php: Base class for most iterators.
    • src/MapIterableAggregate.php: For transforming data.
    • src/FilterIterableAggregate.php: For filtering data.
    • src/CachingIteratorAggregate.php: For caching generators.

Implementation Patterns

Core Workflows

  1. Data Transformation Pipelines: Chain iterators for complex operations:

    $pipeline = new MapIterableAggregate(
        new FilterIterableAggregate(
            range(1, 10),
            fn($item) => $item % 2 === 0
        ),
        fn($item) => $item * 10
    );
    
  2. Laravel Collection Integration: Convert collections to iterators for custom logic:

    $users = User::all();
    $iterator = new MapIterableAggregate($users, fn($user) => $user->name);
    
  3. Generator Handling: Cache generators for reusability:

    $generator = function() {
        yield 1; yield 2; yield 3;
    };
    $cached = new CachingIteratorAggregate($generator());
    
  4. Recursive Data Processing: Flatten nested structures:

    $tree = ['a' => ['b' => ['c']]];
    $iterator = new RecursiveIterableAggregate($tree, fn($item) => $item ?? []);
    

Laravel-Specific Patterns

  1. Eloquent Query Results: Process query results as iterators:

    $posts = Post::query()->get();
    $titles = new MapIterableAggregate($posts, fn($post) => $post->title);
    
  2. Service Provider Bootstrapping: Register iterators as Laravel bindings:

    public function register()
    {
        $this->app->bind('custom.iterator', function() {
            return new MapIterableAggregate([], fn($item) => $item);
        });
    }
    
  3. Middleware for Request Data: Transform request data iteratively:

    $requestData = new MapIterableAggregate(
        $request->all(),
        fn($value, $key) => strtolower($key)
    );
    
  4. Event Listeners: Process event payloads with iterators:

    public function handle(OrderProcessed $event)
    {
        $items = new MapIterableAggregate(
            $event->order->items,
            fn($item) => $item->name
        );
    }
    

Gotchas and Tips

Pitfalls

  1. Memory Management:

    • CachingIteratorAggregate: Caches all keys/values in memory. Avoid with large datasets.
    • RandomIterableAggregate: Requires a seed proportional to dataset size. Use CachingIteratorAggregate for repeated iterations.
  2. Generator State:

    • Generators can only be iterated once. Use CachingIteratorAggregate for rewindable generators:
      $generator = function() { yield 1; yield 2; };
      $cached = new CachingIteratorAggregate($generator());
      foreach ($cached as $item) {} // First pass
      foreach ($cached as $item) {} // Second pass (works)
      
  3. ClosureIterator:

    • Closures are executed per iteration. Avoid expensive operations inside:
      // Bad: Heavy DB query per iteration
      $iterator = new ClosureIterator(fn() => User::find(1));
      
  4. RecursiveIterableAggregate:

    • Infinite recursion risk if the callback returns the same item:
      $iterator = new RecursiveIterableAggregate(
          ['a' => ['b' => ['a']]],
          fn($item) => $item // ❌ Infinite loop
      );
      
  5. Type Safety:

    • Some iterators (e.g., TypedIterableAggregate) enforce strict typing. Ensure input matches expected types.

Debugging Tips

  1. Iterator Validation: Use iterator_to_array() to inspect contents:

    $array = iterator_to_array(new MapIterableAggregate([1, 2, 3], fn($i) => $i * 2));
    // Debug $array
    
  2. Performance Profiling: Benchmark iterators with microtime():

    $start = microtime(true);
    foreach ($iterator as $item) {}
    $time = microtime(true) - $start;
    
  3. Laravel Logging: Log iterator results for debugging:

    foreach ($iterator as $item) {
        \Log::debug('Iterator item', ['item' => $item]);
    }
    

Extension Points

  1. Custom Iterators: Extend IterableIteratorAggregate for domain-specific logic:

    class UserNameIterator extends IterableIteratorAggregate
    {
        public function __construct(private Collection $users) {}
    
        public function getIterator(): Iterator
        {
            return new MapIterableAggregate(
                $this->users,
                fn($user) => $user->name
            );
        }
    }
    
  2. Laravel Service Providers: Bind iterators to Laravel's container:

    $this->app->bind('user.names', function() {
        return new MapIterableAggregate(
            User::all(),
            fn($user) => $user->name
        );
    });
    
  3. Dynamic Iterator Factories: Create factories for reusable iterator patterns:

    class IteratorFactory
    {
        public static function map(Collection $collection, callable $callback)
        {
            return new MapIterableAggregate($collection, $callback);
        }
    }
    
  4. Integration with Laravel Collectors: Convert iterators to collections:

    $collection = collect(iterator_to_array($iterator));
    

Laravel-Specific Quirks

  1. Eloquent Relationships: Iterators work with lazy-loaded relationships:

    $users = User::with('posts')->get();
    $posts = new MapIterableAggregate($users, fn($user) => $user->posts);
    
  2. API Resources: Transform API resources iteratively:

    $resources = new MapIterableAggregate(
        User::all(),
        fn($user) => new UserResource($user)
    );
    
  3. Queue Jobs: Process queue jobs with iterators:

    public function handle()
    {
        $data = new MapIterableAggregate(
            $this->data,
            fn($item) => $item->process()
        );
    }
    
  4. Blade Directives: Use iterators in Blade templates (via helper functions):

    // app/Helpers/IteratorHelper.php
    function mapIterable($items, $callback)
    {
        return new MapIterableAggregate($items, $callback);
    }
    
    @foreach(mapIterable($users, fn($user) => $user->name) as $name)
        {{ $name }}
    @endforeach
    
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.
cadot.eu/make
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
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