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

Collection Laravel Package

zenstruck/collection

A lightweight PHP collection library by Zenstruck offering fluent, immutable-style operations for arrays and iterables. Provides map/filter/reduce, grouping, sorting, slicing, and helpful utilities to work with data sets cleanly in Laravel or standalone PHP.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require zenstruck/collection
    

    Ensure your project uses PHP 8.5+ and Symfony 6.4+ (or Laravel 10+).

  2. First Use Case: Replace native Collection operations with zenstruck/collection for enhanced type safety and Doctrine integration:

    use Zenstruck\Collection\Collection;
    
    $users = Collection::fromArray($arrayOfUsers)
        ->filter(fn ($user) => $user['active'])
        ->map(fn ($user) => $user['name'])
        ->toArray();
    
  3. Doctrine ORM Integration: For Doctrine entities, use the DoctrineBridgeCollection:

    use Zenstruck\Collection\DoctrineBridge\DoctrineBridgeCollection;
    use Doctrine\ORM\EntityRepository;
    
    $repository = $entityManager->getRepository(User::class);
    $users = DoctrineBridgeCollection::fromEntityRepository($repository)
        ->filter(fn ($user) => $user->isActive())
        ->toArray();
    
  4. Lazy Loading: Process large datasets efficiently with lazy evaluation:

    $lazyUsers = Collection::fromArray($largeArrayOfUsers)
        ->lazy()
        ->filter(fn ($user) => $user['active'])
        ->map(fn ($user) => $user['name']);
    
  5. Batch Processing: Use the built-in batch processor for chunked operations (e.g., bulk updates):

    use Zenstruck\Collection\BatchProcessor;
    
    $processor = new BatchProcessor(100); // Process 100 items at a time
    $processor->process($users, fn ($batch) => $this->updateUsers($batch));
    

Where to Look First


Implementation Patterns

Core Workflows

1. Collection Operations

Replace Laravel’s Collection with Zenstruck\Collection\Collection for stricter typing and additional methods:

use Zenstruck\Collection\Collection;

$collection = Collection::fromArray($data)
    ->filter(fn ($item) => $item['status'] === 'active')
    ->sortBy('name')
    ->groupBy('department')
    ->mapWithKeys(fn ($group, $key) => [$key => $group->values()]);

2. Doctrine ORM Integration

Leverage DoctrineBridgeCollection for seamless entity operations:

use Zenstruck\Collection\DoctrineBridge\DoctrineBridgeCollection;

$users = DoctrineBridgeCollection::fromEntityRepository($userRepository)
    ->filter(fn ($user) => $user->getRole() === 'admin')
    ->with('posts') // Eager-load associations
    ->toArray();

3. Lazy Evaluation

Optimize memory usage for large datasets:

$lazy = Collection::fromArray($hugeDataset)
    ->lazy()
    ->filter(fn ($item) => $item['active'])
    ->map(fn ($item) => $item['id']);

foreach ($lazy as $id) {
    // Process one item at a time
}

4. Batch Processing

Process collections in chunks (e.g., for API calls or database updates):

use Zenstruck\Collection\BatchProcessor;

$processor = new BatchProcessor(50); // Batch size
$processor->process($users, fn ($batch) => $this->saveUsers($batch));

5. Pagination with Pagerfanta

Integrate with Pagerfanta for advanced pagination:

use Zenstruck\Collection\Pagerfanta\PagerfantaAdapter;

$adapter = new PagerfantaAdapter($collection);
$pagerfanta = new \Pagerfanta(new \Pagerfanta\Adapter\ArrayAdapter($adapter->getIterator()));

Integration Tips

Laravel-Specific

  • Service Providers: Register the package in AppServiceProvider if extending functionality:

    public function boot()
    {
        Collection::macro('customMethod', function () {
            return $this->map(fn ($item) => strtoupper($item));
        });
    }
    
  • Eloquent Models: Use DoctrineBridgeCollection for query builder operations:

    $query = User::query()->where('active', true);
    $collection = DoctrineBridgeCollection::fromQueryBuilder($query);
    

Symfony-Specific

  • DoctrineBundle 3: Enable output walkers for debugging:

    # config/packages/zenstruck_collection.yaml
    zenstruck_collection:
        doctrine:
            output_walkers: true
    
  • Dependency Injection: Bind DoctrineBridgeCollection as a service:

    // src/Service/CollectionService.php
    public function __construct(
        private DoctrineBridgeCollectionFactory $factory
    ) {}
    

Performance Patterns

  • Avoid toArray() Early: Use lazy loading or generators to defer materialization.
  • Batch Sizes: Tune BatchProcessor sizes based on database/index performance.
  • Doctrine Joins: Use with() sparingly to avoid the N+1 problem; prefer join in QueryBuilder.

Gotchas and Tips

Pitfalls

  1. PHP Version Requirements:

    • PHP 8.5+ is mandatory for full feature support (e.g., enums, new array functions).
    • Symfony 6.4+ or Laravel 10+ is recommended for compatibility.
  2. Doctrine ORM Quirks:

    • Lazy-Loaded Associations: with() may trigger multiple queries if not used with fetchJoinColumn.
    • QueryBuilder Conflicts: Ensure DoctrineBridgeCollection is used with Doctrine’s latest QueryBuilder methods (e.g., expr()).
  3. Immutable Collections:

    • Methods like filter() return new collections; chain operations carefully to avoid memory leaks:
      // Bad: Creates many intermediate collections
      $result = $collection->filter(...)->map(...)->filter(...);
      
      // Good: Use lazy evaluation
      $result = $collection->lazy()->filter(...)->map(...);
      
  4. Batch Processor Pitfalls:

    • Error Handling: Uncaught exceptions in batch callbacks will halt processing. Use try-catch:
      $processor->process($items, fn ($batch) => {
          try {
              $this->saveBatch($batch);
          } catch (\Throwable $e) {
              $this->logError($e);
              throw $e; // Re-throw to continue with next batch
          }
      });
      
    • Batch Size: Too small = overhead; too large = memory issues. Test with 100–1000 items.
  5. Type Safety:

    • Generics: The package uses array<array-key, T> for type hints. Ensure your IDE (PHPStorm, VSCode) supports PHP 8.5 generics.
    • Doctrine Entities: Return types for DoctrineBridgeCollection are strict. Cast to array if needed:
      $array = $collection->toArray(); // array<array-key, mixed>
      

Debugging Tips

  1. Doctrine Debugging:

    • Enable SQL logging in config/packages/dev/doctrine.yaml:
      doctrine:
          dbal:
              logging: true
              profiler: true
      
    • Use DoctrineBridgeCollection::getQueryBuilder() to inspect the underlying query.
  2. Lazy Collection Issues:

    • Generator Wrapping: Ensure generators are properly wrapped in LazyCollection:
      $lazy = Collection::fromGenerator($generator)->lazy();
      
    • Memory Leaks: Use memory_get_usage() to profile lazy-loaded operations.
  3. Batch Processor:

    • Progress Tracking: Add logging to track batch completion:
      $processor->process($items, fn ($batch) => {
          $this->logger->info('Processing batch', ['count' => count($batch)]);
          $this->saveBatch($batch);
      });
      
  4. Performance Bottlenecks:

    • Profile with Xdebug: Use xdebug_profile_enable() to identify slow collection operations.
    • Avoid toArray(): Materializing large collections prematurely can cause OOM errors.

Extension Points

  1. Custom Collections: Extend Zenstruck\Collection\Collection for domain-specific logic:

    class UserCollection extends Collection
    {
        public function activeAdmins(): array
        {
            return $this->filter(fn ($user) => $user->isActive() && $user->isAdmin())
                ->values()
                ->toArray();
        }
    }
    
  2. **Doctrine

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.
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
spatie/laravel-javascript-views