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

Collections Laravel Package

doctrine/collections

Doctrine Collections provides a lightweight, flexible collection abstraction for PHP. It offers ArrayCollection and collection interfaces with rich filtering, mapping, matching, and criteria-based querying, useful as a foundation for domain models and ORM-friendly data handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

Install via Composer:

composer require doctrine/collections

First Use Case

Replace native PHP arrays with ArrayCollection for type safety and utility methods:

use Doctrine\Common\Collections\ArrayCollection;

$users = new ArrayCollection(['Alice', 'Bob', 'Charlie']);

// Basic operations
$users->add('Dave');
$users->remove('Bob');
$firstUser = $users->first();
$filtered = $users->filter(fn($user) => strlen($user) > 3);

Key Entry Points

  1. ArrayCollection – Core collection class with rich methods
  2. Criteria – For complex filtering/sorting
  3. ExpressionBuilder – Fluent query builder for Criteria
  4. Collection/ReadableCollection – Abstract base classes

Implementation Patterns

Core Workflows

1. Type-Safe Collections

use Doctrine\Common\Collections\ArrayCollection;

class User {
    private ArrayCollection $roles;
}

$user = new User();
$user->roles = new ArrayCollection(['admin', 'user']); // Type-safe

2. Criteria-Based Filtering

use Doctrine\Common\Collections\Criteria;

$criteria = new Criteria();
$criteria->where(Criteria::expr()->gt('age', 25))
          ->orderBy(['name' => Criteria::ASC]);

$adults = $users->matching($criteria);

3. Lazy-Loading with LazyCollection

use Doctrine\Common\Collections\LazyCollection;

$lazyUsers = LazyCollection::fromCallback(function() {
    return User::query()->fetchAll();
});

foreach ($lazyUsers as $user) { // Loads on-demand
    // ...
}

4. Immutable Collections

use Doctrine\Common\Collections\ReadableCollection;

$immutable = new ReadableCollection(['a', 'b', 'c']);
// $immutable->add('d'); // Throws \LogicException

Integration Tips

With Eloquent Models

use Doctrine\Common\Collections\ArrayCollection;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;

$eloquent = new EloquentCollection([$user1, $user2]);
$doctrine = new ArrayCollection($eloquent->all());

// Convert back
$eloquent->replace($doctrine->toArray());

Custom Collection Classes

use Doctrine\Common\Collections\AbstractCollection;

class TagCollection extends AbstractCollection {
    public function addTag(string $tag): void {
        $this->add($tag);
    }
}

Criteria in API Responses

use Doctrine\Common\Collections\Criteria;

$criteria = new Criteria();
$criteria->setMaxResults(10);
$criteria->orderBy(['created_at' => Criteria::DESC]);

return response()->json($users->matching($criteria)->toArray());

Gotchas and Tips

Pitfalls

  1. Criteria::expr() Deprecation

    • Prefer ExpressionBuilder for new code:
      $expr = Criteria::create()->expression();
      $expr->gt('age', 25); // Old
      $expr = Criteria::expr()->gt('age', 25); // New (3.1+)
      
  2. Key Preservation

    • ArrayCollection preserves array keys. Use ->toArray() to reset:
      $coll = new ArrayCollection(['a' => 1, 'b' => 2]);
      $coll->add('c'); // Key 'c' is lost unless explicitly set
      
  3. LazyCollection Pitfalls

    • No count() until loaded: Use LazyCollection::count() carefully.
    • Closure scope: Ensure callbacks in fromCallback() have access to dependencies.
  4. Type Safety

    • Generic types are strict. Mixing types (e.g., string|int) may cause runtime errors.

Debugging

  1. Criteria Debugging

    $criteria->where(Criteria::expr()->eq('status', 'active'));
    dump($criteria->getWhereExpressionString()); // Inspect raw SQL-like logic
    
  2. Collection Dumping

    dump($collection->getIterator()->getArrayCopy()); // Force materialization
    

Extension Points

  1. Custom Criteria Functions

    use Doctrine\Common\Collections\Criteria;
    
    Criteria::create()
        ->addCustomExpression('is_active', function($field, $value) {
            return "$field = :val AND $field->isActive()";
        }, ['val' => true]);
    
  2. Override ArrayCollection Methods

    class CustomCollection extends ArrayCollection {
        public function customMethod(): void {
            $this->filter(fn($item) => /* ... */);
        }
    }
    
  3. Serialization

    $collection->willInitializeObjectClosure = function() {
        return new ArrayCollection(['default' => 'value']);
    };
    

Performance Tips

  1. Avoid toArray() in Loops

    • Use getIterator() or getValues() for memory efficiency.
  2. Criteria Optimization

    $criteria->setMaxResults(100); // Limit results early
    $criteria->orderBy(['id' => Criteria::DESC]); // Sort before filtering
    
  3. Lazy Loading

    • Prefer LazyCollection for large datasets:
      $lazy = LazyCollection::fromCallback(fn() => User::all());
      

Laravel-Specific Quirks

  1. Service Container Binding

    $this->app->bind(ArrayCollection::class, function() {
        return new ArrayCollection();
    });
    
  2. Eloquent Relationships

    • Use hasMany with Collection:
      public function posts(): HasMany {
          return $this->hasMany(Post::class)->setCollectionClass(ArrayCollection::class);
      }
      
  3. API Resource Collections

    use Doctrine\Common\Collections\Criteria;
    
    public function toArray($request) {
        $criteria = new Criteria();
        $criteria->where(Criteria::expr()->eq('active', true));
        return $this->collection->matching($criteria)->toArray();
    }
    
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai