Weave 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

easyframework/collections

A fluent, framework-agnostic PHP collections library from easyframework. Chain map, filter, reduce, group, sort, and other operations over arrays and iterables through an expressive, readable API. Immutable, lazy-friendly, dependency-free, and easy to drop into any PHP or Laravel project.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require easyframework/collections

Composer will print Package easyframework/collections is abandoned. That is expected — the last tag is 2017-01-13 and the GitHub repo is archived. Install it only into an existing codebase that already depends on it, or into a sandbox to evaluate. On PHP 8.1+ you will also see ReturnTypeWillChange deprecation notices from the internal interface implementations (ArrayAccess, Countable, IteratorAggregate); they are non-fatal but noisy.

Where to look first. The whole library is two classes plus interfaces and exceptions:

  • src/EasyFramework/Collection/Collection.php — the untyped, array-backed collection.
  • src/EasyFramework/Collection/TypedCollection.php — same API, but enforces an element type on write.
  • src/EasyFramework/Collection/Exception/ — InvalidArgumentException, OutOfBoundsException, etc.

Read Collection.php top to bottom once. There is no facade, no service provider, and no config — the class is the documentation. Confirm the exact method set (add, addAll, get, has, remove, contains, isEmpty, count, toArray, map, filter, reduce, each, first, last, keys, values, slice, merge, clear) against the source before relying on it; the README is thin and hasn't been touched since 2017.

First use case. Replace a raw array that crosses a domain boundary with a typed collection so the type contract is enforced at runtime:

use EasyFramework\Collection\TypedCollection;
use App\Domain\OrderLine;

final class Order
{
    /** @var TypedCollection */
    private $lines;

    public function __construct()
    {
        $this->lines = new TypedCollection(OrderLine::class);
    }

    public function addLine(OrderLine $line): void
    {
        $this->lines->add($line); // throws InvalidArgumentException on wrong type
    }

    public function total(): int
    {
        return $this->lines->reduce(function ($carry, OrderLine $line) {
            return $carry + $line->subtotal();
        }, 0);
    }
}

That is the honest "day one" win: TypedCollection gives you a runtime-checked homogeneous bag with iteration and aggregation, in ~200 lines of code you can vendor into your project if needed.

Implementation Patterns

Use it as a domain-layer value object, not as a Laravel replacement. Illuminate\Support\Collection is already in every Laravel app and is more capable (lazy collections, when, tap, higher-order proxies, macroable). Do not introduce easyframework/collections into a greenfield Laravel app. The only defensible pattern is inside a framework-agnostic domain package where you do not want an illuminate/support dependency, and even then a hand-rolled TypedCollection is usually cheaper than an abandoned dependency.

Typed collection as an invariant at the edge. Hydrate once when data enters the domain, then pass the collection around internally:

$lines = new TypedCollection(OrderLine::class);
$lines->addAll($repository->findLinesFor($orderId)); // validated per element

// Downstream code can now assume OrderLine without re-checking
foreach ($lines as $line) {
    $line->applyDiscount($policy);
}

Filter/map pipelines. The transformations are eager and return new collection instances, so you can chain:

$active = $collection
    ->filter(fn ($item) => $item->isActive())
    ->map(fn ($item) => $item->toArray());

Treat the result as a snapshot — do not assume the original was mutated, and do not assume it wasn't. Verify mutability semantics in Collection.php before relying on either behaviour, because the README does not document it.

Boundary conversion. Keep toArray() calls at the very edge — controllers, API resources, queue payloads. Internally, never pass the raw array around; that's the whole point of the abstraction.

return response()->json([
    'lines' => $order->lines()->toArray(),
]);

Bridging to Eloquent. There is no integration. Wrap manually:

$collection = new TypedCollection(OrderLine::class);
$collection->addAll(OrderLineModel::where('order_id', $id)->get()->all());

If you find yourself writing this wrapper in more than two places, add a small CollectionFactory in your own namespace rather than scattering addAll calls.

Keep one collection type per boundary. Mixing Illuminate\Support\Collection and EasyFramework\Collection\Collection in the same call chain produces arrays-of-collections and confusing toArray() nesting. Pick one per layer and convert explicitly at the seam.

Gotchas and Tips

  • Abandoned and unmaintained. Zero dependents, no commits since 2017, no PHP 8 CI. You are the maintainer the moment you install it. Fork it into your vendor namespace or copy the two classes in — the license is MIT, so this is one cp and a namespace rename.
  • PHP 8.1+ deprecations. ArrayAccess, Countable, and IteratorAggregate methods lack return types. You will get Deprecated: Return type of ... should either be compatible ... notices. If you fork, add #[\ReturnTypeWillChange] or proper return types; don't suppress with error_reporting.
  • Type checks happen on write only. TypedCollection validates in add()/offsetSet(). Nested arrays, unserialized payloads, and addAll() batch behaviour deserve a close read of the source — verify that every element of an array passed to addAll() is checked, and that offsetSet with an explicit key is validated the same way as add.
  • $collection[] = $x goes through offsetSet. If you pass null as the key, confirm the append semantics match your expectation against the class; array-access edge cases are the most common source of silent bugs in small collection libs.
  • Everything is eager. map/filter allocate a new collection per call. Chaining five transformations over 100k rows means five full copies. For large datasets, drop to a generator or Illuminate\Support\Collection's lazy().
  • No __toString, no debug helper. Debug with var_dump($collection->toArray()) or iterator_to_array($collection). print_r($collection) shows private internals, not the items — a frequent five-minute confusion.
  • Exception types matter. Catch EasyFramework\Collection\Exception\*, not generic \Exception. If you are mapping to HTTP responses in Laravel, translate them in the controller/exception handler rather than letting them bubble to a 500.
  • Extension points are just inheritance. Collection and TypedCollection are plain classes; the cleanest extension is a subclass that adds domain-specific aggregates (sumBy, groupByStatus) and returns static/self from transforms. If the base class returns new Collection(...) rather than new static(...), subclasses will silently degrade to the parent type mid-chain — check that before building on it.
  • Composer hygiene. Pin the exact version ("easyframework/collections": "1.0.*" or the specific tag) and add a link-source note in your README. Composer's abandoned-package warning is the only signal a future maintainer will get.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin