PHP functional collection
, (*1)
This little library was inspired by Martin Fowler's collection pipeline pattern,
with the intent of implementing that pattern in PHP., (*2)
The beauty in the Ruby and Clojure examples in the article contrast with PHP's clunky syntax for lambdas (closures); nevertheless, my intention is making it easy to
create collection pipelines in PHP., (*3)
Installation
You can get this PHP library via a composer package in Packagist.
Just add this dependency to your composer.json
:, (*4)
{
"require": {
"marcegarba/funccoll": "@stable"
}
}
How it works
The Collection
class implements an immutable collection, backed by an array., (*5)
The class has two static factory methods, fromArray()
and generate()
., (*6)
The former creates a Collection object by passing a PHP array., (*7)
The latter uses a closure to generate the collection elements., (*8)
Immutability
Each transformation creates a new collection object., (*9)
The class itself implements ArrayAccess
and Countable
, so that it somehow
can be used as an array; but it doesn't implement Iterator
(for traversing the collection
by using the foreach
language construct), because that would imply having a counter
and therefore making the class instances mutable., (*10)
Being immutable, the implementation of offsetSet()
and offsetUnset()
of the
ArrayAccess
interface throws a LogicException
., (*11)
Obviously, the immutability has to do with the collection itself, not the state of its elements., (*12)
The toArray()
method extracts the original array., (*13)
If any mutation needs to be done, then it should be on this array. The mutated array,
of course, can be used to create another Collection object., (*14)
Examples
Here are a couple of simple examples, using the two factory methods., (*15)
Example 1: adding odd numbers times two
A list of consecutive numbers, from 1 to 10, is used to generate the first object;
successive transformations then are applied, so as to obtain the sum of the double
of the first three odd numbers., (*16)
use Marcegarba\FuncColl\Collection;
$sum = Collection::fromArray(range(1, 10))
->filter(function ($elem) { return $elem % 2 != 0; })
->take(3)
->map(function ($elem) { return $elem * 2; })
->reduce(function ($acc, $num) { return $acc + $num; });
echo $sum; // Outputs 18
This example uses the result of a PDO query to generate a list of associative
arrays (with a maximum of 100 elements), each of which is then used to create an
entity object, based on that row contents, and the resulting array of
entity objects are stored in a variable., (*17)
use Marcegarba\FuncColl\Collection;
$pdo = new PDO(...);
$stmt = $pdo->query('SELECT * from items');
$generator = function () use ($stmt) {
return $stmt->fetch(PDO_ASSOC);
}
$items =
Collection::generate($generator, 100)
->map(function ($row) { return new Item($row); });
Summary of methods
These are the main instance methods, sorted alphabetically:, (*18)
Method |
Meaning |
count() |
Returns a count of all elements in the collection |
drop() |
Creates a collection dropping the first n elements |
dropWhile() |
Creates a collection dropping the first evaluated elements |
each() |
Executes a closure for each element |
filter() |
Filters a collection |
findFirst() |
Returns the first element that matches a condition |
flatten() |
Creates a new collection containing a flattened list |
groupBy() |
Groups elements according to a closure |
head() |
Returns the first element |
map() |
Creates a new collection with elements mapped |
reduce() |
Reduces a collection to a single value |
sort() |
Creates a sorted collection applying a closure |
tail() |
Creates a collection with all but the first element |
take() |
Creates a collection with the first n elements |
takeWhile() |
Creates a collection with the first evaluated elements |
toArray() |
Returns copy of the Collection's inner array |
values() |
Creates a new collection with the keys wiped |