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

Collection Laravel Package

somnambulist/collection

A PHP/Laravel collection package that extends the standard Collection with type-safe wrappers, extra helper methods, and immutable-style operations for cleaner, more predictable data manipulation.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require somnambulist/collection

There is no service provider, no facade, no config file — it is a single-purpose, dependency-free library. Everything lives under Somnambulist\Collection\ and the entry point is nearly always the same:

use Somnambulist\Collection\Collection;

$c = Collection::create($payload); // or new Collection($payload)

Where to look first:

  1. README.md — the behaviour list is effectively the API index; methods are grouped by concern (map, filter, sort, mutate, extract, debug).
  2. src/Behaviours/* — the class is assembled from traits (Map, Filter, Sort, Mutate, Extract, Query, Compare, Debug, …). When in doubt about a method's semantics, read the trait; it is short and readable.
  3. src/Contracts/ — CollectionInterface and the typed/immutable variants, which tell you what you can rely on when type-hinting.

First use case: replace a block of nested array_map / foreach / usort / isset($a['b']['c']) code in a service that massages an API or CSV payload. Build the collection at the boundary (Collection::create($response->json())), then chain filter(), pluck(), keyBy(), sortBy(), toArray() in a single readable expression. That is the 80% use case; everything else is refinement.

Implementation Patterns

Normalise at the edges, chain in the middle. Convert arrays to collections where they enter your application (HTTP clients, repositories, file readers) and convert back (toArray(), toJson()) where they leave. Passing a Collection through your service layer is fine and often nicer than array, but do not expose it from a public API contract unless you deliberately want to depend on the package.

Dot notation for nested payloads. get(), set(), has(), forget() and pluck() accept 'a.b.c' paths. This is the single biggest day-to-day win over vanilla arrays for config-like or JSON-shaped data, and it composes well with only()/except() when shaping a response.

Report-style transformation. groupBy() + map() + sum()/avg()/count() covers most ad-hoc reporting without touching SQL, and mapWithKeys() + keyBy() is the standard way to reindex a list of DTO-as-array rows into an id-keyed map.

Typed collections for domain lists. Subclass TypedCollection (or ImmutableTypedCollection) and declare the element type. You get insertion-time validation, a named type you can hint against, and — more importantly — a natural home for domain queries (ActiveUsers::fromRepository()->withExpiredSubscriptions()). This is where the package stops being "Laravel collections without Laravel" and starts earning its keep: the type class is your domain-specific collection, not a generic bag.

Immutability as a design tool. Use ImmutableCollection for value objects, configuration snapshots, and anything shared between services. Mutation attempts throw instead of silently corrupting a reference someone else holds. Reach for the mutable Collection only inside a single, contained method.

Conditional pipelines. when() / unless() / whenEmpty() keep a chain flat when part of the transformation is conditional; tap() for side-effect logging mid-chain; pipe() to hand off to a function that expects a plain array or a differently-typed result. This keeps service methods as one linear expression rather than a series of reassignments.

Integration tips. With Eloquent, Collection::create($models->all()) is usually enough — you rarely need the Laravel collection. With Doctrine ArrayCollection, convert via ->toArray() at the boundary. In Laravel, do not register anything; just import the class and avoid shadowing the global collect() helper. In Symfony, it works as a plain service dependency with no bundle.

Testing. Assert on toArray() rather than poking at internals; typed collections double as fixtures that fail loudly if a test builds the wrong element type.

Gotchas and Tips

  • Mixed value/reference semantics. Many mutators (set, forget, push, transform) act in place, while map, filter, sort variants typically return new instances. Assume nothing; if a chain looks like it should have changed the original, it probably didn't. Standardise on immutable collections in shared code and the question disappears.
  • Dot notation eats literal dots. A key that genuinely contains . will not be found by get('a.b'). Keep payload keys dot-free, or bypass path resolution for those lookups.
  • Loose vs strict comparisons. where(), contains(), unique() follow the usual loose/strict split — the *Strict variants exist for a reason. Comparisons of 0, '0', null and false are the classic source of "why did this filter match?".
  • Typed collections and bulk insertion. Type checks apply on add; paths that bulk-load (merge, constructor with a large array, deserialisation) are worth a test — a badly-typed element slipping in via an array merge is the failure mode to guard against.
  • Immutability is shallow. Wrapping objects in an immutable collection stops you replacing elements, not mutating the objects themselves. Deep-copy or use immutable value objects if that matters.
  • No framework helpers. There is no dd(), dump(), or debug bar integration — zero dependencies means zero magic. Debug with var_dump($c->toArray()) or json_encode($c) (JsonSerializable is implemented, which is also why it drops neatly into API responses).
  • Intermediate arrays. Every chain step generally builds a new array. Fine for request-sized data; if you are iterating tens of thousands of rows in a hot loop, a plain foreach will be faster — build the collection after the loop, not inside it.
  • Extension points are OO, not macro-based. Custom behaviour means subclassing, composing traits from src/Behaviours, or implementing CollectionInterface. There is no runtime macro() registry, so keep extensions in your own namespace and don't monkey-patch.
  • Small ecosystem. Eleven stars and no dependents means no Stack Overflow corpus and no third-party tutorials — the README and the traits are the documentation. The upside is a tiny, MIT-licensed, PHP-version-tolerant surface you can read end-to-end in an afternoon and fork if the maintainer steps away. Pin the minor version and treat upgrades as routine but reviewed.
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