Collections
The NexusPHP Collection class provides a fluent, immutable wrapper for working with arrays of data. Unlike native PHP arrays which require wrapping functions inside out (e.g., array_map(array_filter(...))), Collections allow you to chain methods sequentially, producing code that is highly readable and expressive.
For processing massive datasets that exceed memory limits, NexusPHP also natively provides a LazyCollection implementation powered by PHP Generators.
[!IMPORTANT] The NexusPHP
Collectionimplementation is explicitly Immutable. Data transformation methods (likemapandfilter) do not modify the original collection; instead, they return a pristine newCollectioninstance containing the modified data.
Creating Collections
In NexusPHP, Collections are instantiated explicitly via the class constructor or the static make method.
You can also use the global collect() helper function:
$collection = collect([1, 2, 3]);
use Nexus\Support\Collection;
// Using the constructor
$collection = new Collection([1, 2, 3]);
// Using the static make method
$collection = Collection::make(['name' => 'John', 'age' => 25]);
Available Collection Methods
The Nexus\Support\Collection class implements ArrayAccess, Countable, IteratorAggregate, and JsonSerializable.
Below is the verified list of methods available for data manipulation:
Basic Operations
all(): array: Returns the raw underlying PHP array.count(): int: Returns the total number of items in the collection.isEmpty(): bool: Returnstrueif the collection has zero items.isNotEmpty(): bool: Returnstrueif the collection has one or more items.jsonSerialize(): mixed: Prepares the collection for JSON encoding, recursively callingjsonSerialize()on nested objects if they implement the interface.
Accessing & Retrieving
first(?callable $callback = null, mixed $default = null): mixed: Retrieves the first item. If a callback is provided, it returns the first item that passes the truth test.last(?callable $callback = null, mixed $default = null): mixed: Retrieves the last item. If a callback is provided, it returns the last item that passes the truth test.get(mixed $key, mixed $default = null): mixed: Retrieves an item by its array key using dot-notation via the underlyingArrhelper.has(mixed $key): bool: Checks if a specific key exists in the collection.keys(): static: Returns a new collection containing only the keys of the original collection.values(): static: Returns a new collection with the values re-indexed numerically.
Filtering & Transformation
filter(?callable $callback = null): static: Returns a new collection containing only the items that pass the given callback. If no callback is provided, it filters out all "falsy" values.map(callable $callback): static: Returns a new collection by passing every item through the given callback. The returned value replaces the original value.flatMap(callable $callback): static: Similar tomap, but immediately flattens the resulting collection by one level.collapse(): static: Collapses a collection of arrays (or nested Collections) into a single, flat, new Collection.
Searching & Plucking
pluck(string $value, ?string $key = null): static: Extracts all values for a given key across the entire collection. You may optionally pass a second argument to use as the index key for the resulting collection.
Grouping & Sorting
groupBy(string|callable $groupBy): static: Groups the collection's items by a given key or callback. Returns a new Collection of new Collections.keyBy(string|callable $keyBy): static: Keys the collection by a specific key or callback. If multiple items share the key, only the last one appears in the new collection.sortBy(string|callable $callback, int $options = SORT_REGULAR, bool $descending = false): static: Sorts the collection by the given key or callback.
Utilities
chunk(int $size): static: Breaks the collection into multiple, smaller collections of a given size.each(callable $callback): static: Iterates over the items in the collection, passing them to the callback. Returningfalsefrom the callback will halt the iteration. (Note: This method returns the original$thisinstance, not a new instance).
Lazy Collections
For processing massive datasets that would otherwise trigger memory exhaustion (such as reading multi-gigabyte log files or looping over enormous database tables), NexusPHP provides the Nexus\Support\Collection\LazyCollection.
A LazyCollection leverages PHP Generators to defer memory allocation. Instead of loading all items into memory at once, it evaluates them one by one only as they are yielded.
Creating a Lazy Collection
You can instantiate a Lazy Collection by passing a generator closure (or a standard array) to the constructor or make method.
use Nexus\Support\Collection\LazyCollection;
$lazy = LazyCollection::make(function () {
$handle = fopen('massive_log.csv', 'r');
while (($line = fgetcsv($handle)) !== false) {
yield $line;
}
});
Lazy Operations
The LazyCollection supports a subset of methods that preserve the deferred generator state. Methods like map and filter return a new LazyCollection wrapping the previous generator pipeline, executing nothing until the collection is finally iterated or resolved.
map(callable $callback): staticfilter(callable $callback): statictake(int $limit): static: Halts the generator once the limit is reached.each(callable $callback): static: Iterates and executes the pipeline.all(): array: Executes the entire deferred pipeline and loads the final result into an array viaiterator_to_array().count(): int: Executes the pipeline specifically to count the yielded items.
Example: Efficient Processing
// No files are opened and no data is loaded into memory yet
$lazy = LazyCollection::make(function () {
for ($i = 0; $i < 1000000; $i++) {
yield $i;
}
})->filter(function ($i) {
return $i % 2 === 0;
})->take(5);
// The generator only runs enough to find the first 5 even numbers!
$results = $lazy->all(); // [0, 2, 4, 6, 8]
Best Practices
- Use
LazyCollectionfor Database Results: When processing thousands of ORM entities, always usechunk()on your query builder, or ideally, integrate a generator yielding toLazyCollectionto keep memory pressure minimal. - Chain Fluent Operations: Because
Collectionis immutable, chain your operations sequentially. - Beware of Key Preservation: Operations like
filter()preserve the original array keys. If you need a cleanly numerically indexed array afterward, chain thevalues()method at the end ($collection->filter(...)->values()).
Next Steps
Explore where Collections are natively returned in the framework:
- Models & Relationships: Learn how the
EntityQueryBuilderhydrates rows into Collections of models. - Database Connections: Learn about the raw database connection wrapper.