PHPackages                             popcorn4dinner/collections - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. popcorn4dinner/collections

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

popcorn4dinner/collections
==========================

A flexible, simple to use and non-opinionated collection library

1.0.1(7y ago)15MITPHPPHP &gt;=7.1

Since Apr 13Pushed 7y ago2 watchersCompare

[ Source](https://github.com/popcorn4dinner/php-collections)[ Packagist](https://packagist.org/packages/popcorn4dinner/collections)[ RSS](/packages/popcorn4dinner-collections/feed)WikiDiscussions master Synced 2d ago

READMEChangelogDependencies (2)Versions (8)Used By (0)

PHP Collection
==============

[](#php-collection)

A flexible, simple to use and non-opinionated collection library.

Features
--------

[](#features)

- minimalistic and easily comprehendable
- supports pagiantion
- supports json serialization
- a bunch of util functions to make your live easier
- designed for extensibility

Creating a collection
---------------------

[](#creating-a-collection)

Minimal Usage:

```
use Popcorn4dinner\Collection\AbstractCollection;

class MyCollection extends AbstractCollection
{

 protected function isCollectableInstance($item): bool
     {
        // This is the place where you can inforce typing,
        // but also any other convention that all items in your collection
        // have to follow.

         return true;
     }
}
```

```
$item1 = new ExampleItem();
$item2 = new ExampleItem();

$collection = new MyCollection($item1, $item2);

foreach($collection as $item){
   //  Your logic goes here...
}
```

Controlling storage mechanics
-----------------------------

[](#controlling-storage-mechanics)

```
use Popcorn4dinner\Collection\AbstractCollection;

class MyCollection extends AbstractCollection
{

 // Now users are stored uniquly by their email address
 protected function store($user)
 {
     $this->items[$user->email] = $user;
 }

 protected function isCollectableInstance($user): bool
 {
     return $user->email !== null;
 }
}
```

Pagination and REST API endpoints
---------------------------------

[](#pagination-and-rest-api-endpoints)

Paginated Collections can be used so enable pagination for API Endpoints and Views.

```
use Popcorn4dinner\Collection\AbstractPaginatedCollection;

class ExampleCollection extends AbstractPaginatedCollection
{

    protected function isCollectableInstance($item): bool
    {
        return is_a($item, ExampleItem::class);
    }

}
```

```
$offset = 10;
$limit = 20;
$totalAmountOfItems = 25;

$collection = new ExampleCollection($items, $offset, $limit, $totalAmountOfItems);

$collection->getPageSize()
// 10

$collections->getAmountPages()
// 3

$collection->getCurrentPage()
// 2

$collection->hasPreviousPage()
// true

$collection->hasNextPage()
// true
```

### Paginated REST endpoints

[](#paginated-rest-endpoints)

```
use Popcorn4dinner\Collection\AbstractJsonSerializableCollection;

class ExampleJsonSerializableCollection extends AbstractJsonSerializableCollection
{
    protected function isCollectableInstance($item): bool
    {
        return is_a($item, ExampleItem::class);
    }

    protected static function serializeItem($item): array
    {
        return [ 'name' => $item->name];
    }

}
```

```
$collection->jsonSerialize();

/*
 * [
 *   "items" =>
 *      [
 *        [ "name" => "Some name"],
 *        ...
 *      ],
 *   "_total" => 25,
 *   "_offset" => 10,
 *   "_limit" => 20,
 *   "_page_size" => 10,
 *   "_current_page" => 2,
 *   "_amount_pages" => 3,
 *   "_has_next_page" => true,
 *   "_has_previous_page" => true
 * ]
 */
```

### Create collections from a request body

[](#create-collections-from-a-request-body)

```
$users = PaginatedUserCollection::fromRequestBody($requestBody,
    function($userDataRow){
        return new User($userDataRow['name']);
    }
);
```

Utility functions
-----------------

[](#utility-functions)

### each

[](#each)

Applies the callback to all items within the collection.

```
$users->each(
    function($user) { return $user->lock(); }
);
```

### map

[](#map)

Applies the callback to all items within the collection and returns a new collection.

```
$lockedUsers = $users->map(
    function($user) { return $user->lock(); }
);
```

### first

[](#first)

Returns the first item in the collection

```
$bird = $birds->first();
```

### last

[](#last)

Returns the last item in the collection

```
$bird = $birds->last();
```

### get

[](#get)

Return and item by key

```
$bird = $birds->get(3);

$user = $user->get("someone@example.com");
```

### filter

[](#filter)

Returns a new collection based on the filter callback

```
$productsAddedToday = $products->filter(
    function($product) { return $product->createdAt() > new \DateTime('today'); }
);
```

### reject

[](#reject)

Reverse effect of filter(). Return a new collection based on the filter callback

```
$delayedTrains = $trains->reject(
    function($tain) { return $train->isOnTime(); }
);
```

### sort

[](#sort)

Sorts the collection based on a callback

```
$purchases->sort(
    function($a, $b){ return $a->createdAt > $b->createdAt; }
);
```

### unique

[](#unique)

Return a new Collection with unique items.

```
$uniqueVisits = $visits->unique();
```

### split

[](#split)

Maybe my personal favorite: Returns an array of collections, split based on the given callback.

```
$purchasesByDay = $purchases->split(
    functions($purchase){ return $purchase->createdAt->format('Y-m-d'); }
);

// returns:
// [
//    '2017-08-01' => PurchaseCollection...
```

### reduce

[](#reduce)

Returns an array of transformed items.

```
$userIds = $users->reduce(
    function($user){ $user->id }
);
```

### toArray

[](#toarray)

Returns an Array with all items in the collection.

```
SomeArrayFunction( $collection->toArray() );
```

License
-------

[](#license)

MIT

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~24 days

Total

4

Last Release

2879d ago

Major Versions

0.2.0 → 1.0.02018-04-13

### Community

Maintainers

![](https://www.gravatar.com/avatar/b7f09c6677ed6fffa796df715c75bba02176e7329794b01059d5f73fdcec295c?d=identicon)[popcorn4dinner](/maintainers/popcorn4dinner)

---

Top Contributors

[![popcorn4dinner](https://avatars.githubusercontent.com/u/7091162?v=4)](https://github.com/popcorn4dinner "popcorn4dinner (2 commits)")[![timothyk0908](https://avatars.githubusercontent.com/u/10809590?v=4)](https://github.com/timothyk0908 "timothyk0908 (2 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/popcorn4dinner-collections/health.svg)

```
[![Health](https://phpackages.com/badges/popcorn4dinner-collections/health.svg)](https://phpackages.com/packages/popcorn4dinner-collections)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
