PHPackages                             pinkcrab/function-constructors - 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. pinkcrab/function-constructors

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

pinkcrab/function-constructors
==============================

A collection of functions to make working with the standard php library a little easier for function composition. Allows the creation of partially applied library functions, to work as close to pure fucntions as possible.

0.2.0(3y ago)456.5k↓42.5%1[9 issues](https://github.com/gin0115/pinkcrab_function_constructors/issues)[2 PRs](https://github.com/gin0115/pinkcrab_function_constructors/pulls)6GPL-2.0-or-laterPHPPHP &gt;=7.1.0

Since Dec 3Pushed 2y ago1 watchersCompare

[ Source](https://github.com/gin0115/pinkcrab_function_constructors)[ Packagist](https://packagist.org/packages/pinkcrab/function-constructors)[ Docs](https://pinkcrab.co.uk)[ RSS](/packages/pinkcrab-function-constructors/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (45)Used By (6)

The PinkCrab FunctionConstructors library.
==========================================

[](#the-pinkcrab-functionconstructors-library)

[![PHPUnit](https://github.com/gin0115/pinkcrab_function_constructors/actions/workflows/php.yml/badge.svg?branch=master)](https://github.com/gin0115/pinkcrab_function_constructors/actions/workflows/php.yml) [![codecov](https://camo.githubusercontent.com/1993fdcf22cfaa1f646eb7bcbb5afca46b9698ba0ec095e718fdb3d4a57ae844/68747470733a2f2f636f6465636f762e696f2f67682f67696e303131352f70696e6b637261625f66756e6374696f6e5f636f6e7374727563746f72732f6272616e63682f646576656c6f702f67726170682f62616467652e7376673f746f6b656e3d58344c53353936315431)](https://codecov.io/gh/gin0115/pinkcrab_function_constructors) [![Scrutinizer Code Quality](https://camo.githubusercontent.com/0b43fe26c4e2d58934d19312acecba2ed99f1f1fc91dcb68f637bf49c6d6e2a6/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f67696e303131352f70696e6b637261625f66756e6374696f6e5f636f6e7374727563746f72732f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/gin0115/pinkcrab_function_constructors/?branch=master) [![Packagist Downloads](https://camo.githubusercontent.com/f79a1f7ee14bd28b9ad79fa56b098a3c37d32f7001f4ebda38a52f0941b335d7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f70696e6b637261622f66756e6374696f6e2d636f6e7374727563746f72733f6c6162656c3d446f776e6c6f616473)](https://camo.githubusercontent.com/f79a1f7ee14bd28b9ad79fa56b098a3c37d32f7001f4ebda38a52f0941b335d7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f70696e6b637261622f66756e6374696f6e2d636f6e7374727563746f72733f6c6162656c3d446f776e6c6f616473) [![GitHub tag (latest by date)](https://camo.githubusercontent.com/a9ce8ca7e040b7e7fd919ac6acd0f24e2e652b7fb4b237c456cd80090a8d5c1c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f67696e303131352f70696e6b637261625f66756e6374696f6e5f636f6e7374727563746f72733f6c6162656c3d4c6174657374)](https://camo.githubusercontent.com/a9ce8ca7e040b7e7fd919ac6acd0f24e2e652b7fb4b237c456cd80090a8d5c1c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f67696e303131352f70696e6b637261625f66756e6374696f6e5f636f6e7374727563746f72733f6c6162656c3d4c6174657374)

---

This library provides a small selection of functions for making functional programming a little cleaner and easier in php.

Setup
-----

[](#setup)

Can be included into your project using either composer or added manually to your codebase.

### Via Composer

[](#via-composer)

`$ composer require pinkcrab/function-constructors`

### Via Manual Loader

[](#via-manual-loader)

If you wish to use this library within WordPress or other PHP codebase where you do not or cannot use composer, you can use the **FunctionsLoader** class. Just clone the repo into your codebase and do the following.

```
require_once 'path/to/cloned/repo/FunctionsLoader.php';
FunctionsLoader::include();
```

All of our functions are namespaced as **PinkCrab\\FunctionConstructors\\{lib}**. So the easiest way to use them is to use with an alias. Throughout all the docs on the wiki we use the following aliases.

```
use PinkCrab\FunctionConstructors\Arrays as Arr;
use PinkCrab\FunctionConstructors\Numbers as Num;
use PinkCrab\FunctionConstructors\Strings as Str;
use PinkCrab\FunctionConstructors\Comparisons as C;
use PinkCrab\FunctionConstructors\GeneralFunctions as F;
use PinkCrab\FunctionConstructors\Objects as Obj;

// Allowing for
Arr\Map('esc_html') or Str\append('foo') or F\pipe($var, 'strtoupper', Str\append('foo'))
```

Usage
-----

[](#usage)

At its core, the Function Constructors library is designed to make using PHP easier to use in a functional manor. With the use of functions `compose()` and `pipe()` its possible to construct complex functions, from simpler ones.

### Function Composition and Piping

[](#function-composition-and-piping)

#### pipe()

[](#pipe)

> PLEASE NOTE THIS HAS CHANGED IN VERSION 2.0.0, using `compose()` is now the preferred method.

Using `pipe(mixed $value, callable ...$callables)` and [ `pipeR()` \*](#pipe "Same as pipe(), but callables in reverse order"), allows you to pass a value through a chain of callables. The result of the 1st function, is passed as the input the 2nd and so on, until the end when the final result is returned.

> The rest of this library makes it easier to use standard php functions as callables, by defining some of the parameters up front.

```
$data = [0,3,4,5,6,8,4,6,8,1,3,4];

// Remove all odd numbers, sort in an acceding order and double the value.
$newData = F\pipe(
    $data,
    Arr\filter(Num\isMultipleOf(2)), // Remove odd numbers
    Arr\natsort(),                 // Sort the remaining values
    Arr\map(Num\multiply(2))       // Double the values.
);

// Result
$newData = [
 2 => 8,
 6 => 8,
 11 => 8,
 4 => 12,
 7 => 12,
 5 => 16,
 8 => 16,
];
```

#### compose()

[](#compose)

Piping is ideal when you are working with a single value, but when it comes to working with Arrays or writing callbacks, compose() is much more useful.

`compose(callable ...$callables)` , `composeR(callable ...$callables)` , `composeSafe(callable ...$callables)` and `composeTypeSafe(callable $validator, callable ...$callables)` all allow you to create custom Closures.

```
$data = [
    ['details'=>['description' => '    This is some description ']],
    ['details'=>['description' => '        This is some other description    ']],
];

$callback = F\compose(
   F\pluckProperty('details','description'), // Plucks the description
   'trim',                                   // Remove all whitespace
   Str\slice(0, 20),                         // Remove all but first 20 chars
   'ucfirst',                                // Uppercase each word
   Str\prepend('...')                        // End the string with ...
);

$results = array_map($callback, $data);

$results = [
    'This Is Some Descrip...',
    'This Is Some Other D...'
]
```

> You can use `composeTypeSafe()` if you want to pass the return of each callable through a validator before being passed to the next. If the validator fails, the rest of the chain will be skipped and null will be returned.

---

### Working with Records

[](#working-with-records)

It is possible to work with the properties of *Records* (arrays and objects). Indexes or Properties can be checked, fetched and set using some of the `GeneralFunctions` .

#### Reading Properties

[](#reading-properties)

You can check if a property exists, get its value or compare it an defined value.

```
$data = [
    ['id' => 1, 'name' => 'James', 'timezone' => '+1', 'colour' => 'red'],
    ['id' => 2, 'name' => 'Sam', 'timezone' => '+1', 'colour' => 'red', 'special' => true],
    ['id' => 3, 'name' => 'Sarah', 'timezone' => '+2', 'colour' => 'green'],
    ['id' => 4, 'name' => 'Donna', 'timezone' => '+2', 'colour' => 'blue', 'special' => true],
];

// Filter all users with +2 timezone.
$zonePlus2 = array_filter($data, F\propertyEquals('timezone','+2'));
$results = [['id' => 3, ....],['id' => 4, ...]];

// Filter all user who have the special index.
$special = array_filter($data, F\hasProperty('special'));
$results = [['id' => 2, ....],['id' => 4, ...]];

// Get a list of all colours.
$colours = array_map(F\getProperty('colour'), $data);
$results = ['red', 'red', 'green', 'blue'];
```

> `pluckProperty()` can also be used if you need to traverse nested properties/indexes of either **arrays** or **objects** *also handles `ArrayAccess` objects, set with array syntax* [see example on `compose()` ](#compose)

#### Writing Properties

[](#writing-properties)

Its also possible to write properties of objects and set values to indexes in arrays using the `setProperty()` function. More complex structures can also be created using the [Record Encoder](../../../../pinkcrab_function_constructors/wiki/Record_Encoder)

```
// Set object property.
$object = new class(){ public $key = 'default'};

// Create a custom setter function.
$setKeyOfObject = F\setProperty($object, 'key');
$object = $setKeyOfObject('new value');
// {"key":"new value"}

// Can be used with arrays too
$array = ['key' => 'default'];

// Create a custom setter function.
$setKeyOfSArray = F\setProperty($array, 'key');
$array = $setKeyOfSArray('new value');
// [key => "new value"]
```

---

### String Functions

[](#string-functions)

Much of the string functions found in this library act as wrappers for common standard (PHP) library functions, but curried to allow them to be easier composed with.

#### String Manipulation

[](#string-manipulation)

There is a collection of functions with make for the concatenation of strings.

```
$appendFoo = Str\append('foo');
$result = $appendFoo('BAR');

$prependFoo = Str\prepend('foo');
$result = $prependFoo('BAR');

$replaceFooWithBar = Str\replaceWith('foo', 'bar');
$result = $replaceFooWithBar("its all a bit foo foo");
// "its all a bit bar bar"

$wrapStringWithBar = Str\wrap('bar-start-', '-bar-end');
$result = $wrapStringWithBar('foo');
// bar-start-foo-bar-end
```

#### String Contents

[](#string-contents)

There is a collection of functions that be used to check the contents of a string.

```
// Check if a string contains
$containsFoo = Str\contains('foo');
$containsFoo('foo');   // true
$containsFoo('fobar'); // false

// Check if string start with (ends with also included)
$startsBar = Str\startsWith('bar');
$startsBar('bar-foo'); // true
$startsBar('foo-bar'); // false

// Check if a blank string
Str\isBlank('');   // true
Str\isBlank(' ');  // false

// Unlike using empty(), this checks if the value is a string also.
Str\isBlank(0);    // false
Str\isBlank(null); // false

// Contains a regex pattern
$containsNumber = Str\containsPattern('~[0-9]+~');
$containsNumber('apple');   // false
$containsNumber('A12DFR3'); // true
```

> `Str\isBlank()` can be used when composing a function, thanks to the Functions::isBlank constant.

```
$data = [0 => '', 1 => 'fff', 2 => '    '];
$notBlanks = array_filter(PinkCrab\FunctionConstructors\Functions::IS_BLANK, $data);
// [0 => '']
```

#### Sub Strings

[](#sub-strings)

There is a series of functions that can be used to work with substrings.

```
// Split the string into sub string
$inFours = Str\split(4);
$split = $inFours('AAAABBBBCCCCDDDD');
// ['AAAA','BBBB','CCCC','DDDD']

// Chunk the string
$in5s = Str\chunk(5, '-');
$result = $in5s('aaaaabbbbbccccc');
// 'aaaaa-bbbbb-ccccc-'

// Count all characters in a given string.
$charCount = Str\countChars();
$results = $charCount('Hello World');
// [32 => 1, 72 => 1, 87 => 1, 100 => 1, 101 => 1, 108 => 3, 111 => 2, 114 => 1]
// If the keys are mapped using chr(), you will get
$results = (Arr\mapKey('chr')($results));
// ['H' => 1,'e' => 1,'l' => 3,'o' => 2,' ' => 1,'W' => 1,'r' => 1,'d' => 1,]

// Count occurrences of a substring.
$countFoo = Str\countSubString('foo');
$results = $countFoo('foo is foo and bar is not foo');
// 3

// Find the first position of foo in string.
$firstFoo = Str\firstPosition('foo');
$result = $firstFoo('abcdefoog');
// 5
```

> See more of the Strings functions [on the wiki](../../../../pinkcrab_function_constructors/wiki/Strings)

---

### Number Functions

[](#number-functions)

Much of the number functions found in this library act as wrappers for common standard (PHP) library functions, but curried to allow them to be easier composed with.

#### Basic Arithmetic

[](#basic-arithmetic)

You can do some basic arithmetic using composable functions. This allows for the creation of a base value, then work using the passed value.

> All these functions allow the use of `INT` or `FLOAT` only, all numerical strings must be cast before being used. Will throw `TypeError` otherwise.

```
// Add
$addTo5 = Num\sum(5);

$addTo5(15.5); // 20.5
$addTo5(-2); // 3

// Subtract
$subtractFrom10 = Num\subtract(10);
$subtractFrom10(3)  // 7
$subtractFrom10(20) // -10

// Multiply
$multiplyBy10 = Num\multiply(10)
$multiplyBy10(5);   // 50
$multiplyBy10(2.5); // 25.0

// Divide By
$divideBy3 = Num\divideBy(3);
$divideBy3(12); // 4 = 12/3
$divideBy3(10); // 3.333333333333

// Divide Into
$divideInto12 = Num\divideInto(12);
$divideInto12(4); // 3 = 12/4
```

#### Multiple and Modulus

[](#multiple-and-modulus)

It is possible to do basic modulus operations and working out if a number has a whole factor of another.

```
// Factor of
$isMultipleOf2 = Num\isMultipleOf(2);
$isMultipleOf2(12); // true
$isMultipleOf2(13); // false

// Getting the remainder
$remainderBy2 = Num\remainderBy(2);
$remainderBy2(10); // 0 = (5 * 2) - 10
$remainderBy2(9);  // 1 = (4 * 2) - 9
```

### Array Functions

[](#array-functions)

As you can imagine there are a large number of functions relating to arrays and working with them.

#### Map

[](#map)

This library contains a large number of variations of `array_map` , these can all be pre composed, using the other functions to be extremely powerful and easy to follow.

```
// Create a mapper which doubles the value.
$doubleIt = Arr\map( Num\multiply(2) );
$doubleIt([1,2,3,4]); // [2,4,6,8]

// Create mapper to normalise array keys
$normaliseKeys = Arr\mapKey(F\compose(
    'strval',
    'trim',
    Str\replace(' ', '-')
    Str\prepend('__')
));

$normaliseKeys(1 => 'a', ' 2 ' => 'b', 'some key' => 'c');
// ['__1'=> 'a', '__2' => 'b', '__some-key' => 'c']

// Map and array with the value and key.
$mapWithKey = Arr\mapWithKey( function($key, $value) {
    return $key . $value;
});
$mapWithKey('a' => 'pple', 'b' => 'anana');
// ['apple', 'banana']
```

> There is `flatMap()` and `mapWith()` also included, please see the wiki.

#### Filter and Take

[](#filter-and-take)

There is a large number of composible functions based around `array_filter()` . Combined with a basic set of `take*()` functions, you can compose functions to work with lists/collections much easier.

```
// Filter out ony factors of 3
$factorsOf3s = Arr\filter( Num\factorOf(3) );
$factorsOf3s([1,3,5,6,8,7,9,11]); // [3,6,9]

// Filer first and last of an array/
$games = [
    ['id'=>1, 'result'=>'loss'],
    ['id'=>2, 'result'=>'loss'],
    ['id'=>3, 'result'=>'win'],
    ['id'=>4, 'result'=>'win'],
    ['id'=>5, 'result'=>'loss'],
];

$firstWin = Arr\filterFirst( F\propertyEquals('result','win') );
$result = $firstWin($games); // ['id'=>3, 'result'=>'win']

$lastLoss = Arr\filterLast( F\propertyEquals('result','loss') );
$result = $lastLoss($games); // ['id'=>5, 'result'=>'loss']

// Count result of filter.
$totalWins = Arr\filterCount( F\propertyEquals('result','win') );
$result = $totalWins($games); // 2
```

> Filter is great if you want to just process every result in the collection, the `take()` family of functions allow for controlling how much of an array is filtered

```
// Take the first or last items from an array
$first5 = Arr\take(5);
$last3 = Arr\takeLast(5);

$nums = [1,3,5,6,8,4,1,3,5,7,9,3,4];
$first5($nums); // [1,3,5,6,8]
$last3($nums);  // [9,3,4]

// Using takeWhile and takeUntil to get the same result.
$games = [
    ['id'=>1, 'result'=>'loss'],
    ['id'=>2, 'result'=>'loss'],
    ['id'=>3, 'result'=>'win'],
    ['id'=>4, 'result'=>'win'],
    ['id'=>5, 'result'=>'loss'],
];

// All games while the result is a loss, then stop
$initialLoosingStreak = Arr\takeWhile(F\propertyEquals('result','loss'));
// All games until the first win, then stop
$untilFirstWin = Arr\takeUntil(F\propertyEquals('result', 'win'));

$result = $initialLoosingStreak($game);
$result = $untilFirstWin($game);
// [['id' => 1, 'result' => 'loss'], ['id' => 2, 'result' => 'loss']]
```

#### Fold and Scan

[](#fold-and-scan)

Folding or reducing an a list is a pretty common operation and unlike the native `array_reduce` you have a little more flexibility.

```
$payments = [
    'gfg1dg3d' => ['type' => 'card', 'amount' => 12.53],
    'eg43ytfh' => ['type' => 'cash', 'amount' => 21.95],
    '5g7tgxfb' => ['type' => 'card', 'amount' => 1.99],
    'oitu87uo' => ['type' => 'cash', 'amount' => 4.50],
    'ew1e5435' => ['type' => 'cash', 'amount' => 21.50],
];

// Get total for all cash payment.
$allCash = Arr\fold(function($total, $payment){
    if($payment['type'] === 'cash'){
        $total += $payment['amount'];
    }
    return $total;
},0.00);

$result = $allCash($payments); // 47.95

// Log all card payment in some class, with access to array keys.
$logCardPayments = Arr\foldKeys(function($log, $key, $payment){
    if($payment['type'] === 'card'){
        $log->addPayment(payment_key: $key, amount: $payment['amount']);
    }
    return $log;
}, new CardPaymentLog('some setup') );

$cardPaymentLog = $logCardPayments($payments);
var_dump($cardPayments->getPayments());
// [{'key': 'gfg1dg3d', 'amount': 12.53}, {'key': '5g7tgxfb', 'amount': 1.99}]

// Generate a running total of all payments.
$runningTotal = Arr\scan(function($runningTotal, $payment){
    $runningTotal += $payment['amount'];
    return $runningTotal;

}, 0.00);

$result = $runningTotal($payments);
// [0.0, 12.53, 34.48, 36.47, 40.97, 62.47]
```

> You also have access to `foldR()` and `scanR()` which will iterate through the array backwards.

#### Grouping and Partitioning

[](#grouping-and-partitioning)

Function Constructor has a number of functions which make it easy to group and partition arrays

```
$data = [
    ['id'=>1, 'name'=>'John', 'age'=>20, 'someMetric' => 'A12'],
    ['id'=>2, 'name'=>'Jane', 'age'=>21, 'someMetric' => 'B10'],
    ['id'=>3, 'name'=>'Joe', 'age'=>20, 'someMetric' => 'C15'],
    ['id'=>4, 'name'=>'Jack', 'age'=>18, 'someMetric' => 'B10'],
    ['id'=>5, 'name'=>'Jill', 'age'=>22, 'someMetric' => 'A12'],
];

// Group by the return value of the function.
$groupedByMetric = Arr\groupBy(function($item){
    return $item['someMetric'];
});

$results = $groupedByMetric($data);
["A12" =>  [
    ["id" => 1,"name" => "John", ...],
    ["id" => 5,"name" => "Jill", ...]
],
"B10" =>  [
    ["id" => 2,"name" => "Jane", ...],
    ["id" => 4,"name" => "Jack", ...]
],
"C15" =>  [
    ["id" => 3,"name" => "Joe", ...]
]];

// Partition using a predicate function.
$over21 = Arr\partition(function($item){
    return $item['age'] >= 21;
});

$results = $over21($data);
[0 => [ // false values
    ["name" => "John", "age" => 20, ...],
    ["name" => "Joe", "age" => 20, ...],
    ["name" => "Jack", "age" => 18, ...]
],
1 => [ // true values
    ["name" => "Jane", "age" => 21, ...],
    ["name" => "Jill", "age" => 22, ...]
]];
```

> It is possible to chunk and split arrays, see the wiki for more.

#### Sorting

[](#sorting)

The native PHP `sort` functions are tricky with a functional approach, as they sort via reference, rather than by a return value. The Function Constructor library covers all native sorting as partially applied functions.

```
// Sorting simple arrays
$dataWords = ['Zoo', 'cat', 'Dog', 'ant', 'bat', 'Cow'];

$sortWords = Arr\sort(SORT_STRING);
$result = $sortWords($dataWords);
// ['ant', 'bat', 'cat', 'Cow', 'Dog', 'Zoo'];

// Sorting associative arrays
$dataBooks = [
    'ehjf89' => ['id'=>'ehjf89', 'title'=>'Some title', 'author'=> 'Adam James'],
    'retg23' => ['id'=>'retg23', 'title'=>'A Title', 'author'=> 'Jane Jones'],
    'fvbi43' => ['id'=>'fvbi43', 'title'=>'Some title words', 'author'=> 'Sam Smith'],
    'mgged3' => ['id'=>'mgged3', 'title'=>'Book', 'author'=> 'Will Adams'],
];

// Sort by key
$sortBookByKey = Arr\ksort(SORT_STRING | SORT_FLAG_CASE);
$result = $sortBookByKey($dataBooks);
[
    'ehJF89' => ['id' => 'ehjf89', 'title' => 'Some title', 'author' => 'Adam James'],
    'fvbI43' => ['id' => 'fvbi43', 'title' => 'Some title words', 'author' => 'Sam Smith'],
    'MggEd3' => ['id' => 'mgged3', 'title' => 'Book', 'author' => 'Will Adams'],
    'Retg23' => ['id' => 'retg23', 'title' => 'A Title', 'author' => 'Jane Jones'],
]

// Sort by author
$sortBookByAuthor = Arr\uasort(function ($a, $b) {
    return strcmp($a['author'], $b['author']);
});
$sortBookByAuthor($dataBooks);
[
    'ehJF89' => ['id' => 'ehjf89', 'title' => 'Some title', 'author' => 'Adam James'],
    'Retg23' => ['id' => 'retg23', 'title' => 'A Title', 'author' => 'Jane Jones'],
    'fvbI43' => ['id' => 'fvbi43', 'title' => 'Some title words', 'author' => 'Sam Smith'],
    'MggEd3' => ['id' => 'mgged3', 'title' => 'Book', 'author' => 'Will Adams'],
]
```

---

### Contributions

[](#contributions)

If you would like to contribute to this project, please feel to fork the project on github and submit a pull request.

---

> For more details, please read the [wiki](https://github.com/gin0115/pinkcrab_function_constructors/wiki)

Changes
-------

[](#changes)

- 0.2.0 -

    - **New Functions**
    - `Numbers\isMultipleOf()`
    - `Numbers\isFactorOf()`
    - `Strings\isBlank()`
    - `Strings\splitByLength()`
    - `GeneralFunctions\ifThen()`
    - `GeneralFunctions\ifElse()`
    - `GeneralFunctions\composeR()`
    - `Arrays\fold()`
    - `Arrays\foldR()`
    - `Arrays\foldKey()`
    - `Arrays\scan()`
    - `Arrays\scanR()`
    - `Arrays\take()`
    - `Arrays\takeLast()`
    - `Arrays\takeUntil()`
    - `Arrays\takeWhile()`
    - `Arrays\filterAny()`
    - `Arrays\filterAll()`
    - `Arrays\mapWithKey()`
    - `Objects\isInstanceOf()`
    - `Objects\implementsInterface()`
    - `Objects\toArray()`
    - `Objects\usesTrait()`
    - `Objects\createWith()`
    - **Breaking Changes**
    - `GeneralFunctions\pipe()` &amp; `GeneralFunctions\pipeR()` have now changed and are no longer alias for `compose()`
    - `GeneralFunctions\setProperty()` now takes the property argument when creating the Closure.
    - `Strings\tagWrap()` has been removed
    - `Strings\asUrl()` has been removed
    - `Strings\vSprintf()` has has its arguments reversed.
    - `Strings\split()` is now a wrapper for explode() and the existing `Strings\split()` has been renamed to `Strings\splitByLength()`
    - **Other Changes**
    - Constants added using the `Functions` class-name, `Functions::isBlank` can be used as a string for a callable.
    - `GeneralFunctions\toArray()` has been moved to `Objects\toArray()`, `Objects\toArray()` is now an alias for `GeneralFunctions\toArray()`
- 0.1.2 - Added `Arrays\zip()`
- 0.1.3 - Added` Arrays\filterKey()`

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity34

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~81 days

Recently: every ~52 days

Total

10

Last Release

1207d ago

### Community

Maintainers

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

---

Top Contributors

[![gin0115](https://avatars.githubusercontent.com/u/28779094?v=4)](https://github.com/gin0115 "gin0115 (398 commits)")

---

Tags

functionalfpcurryingpartial applicationpiping

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/pinkcrab-function-constructors/health.svg)

```
[![Health](https://phpackages.com/badges/pinkcrab-function-constructors/health.svg)](https://phpackages.com/packages/pinkcrab-function-constructors)
```

###  Alternatives

[lstrojny/functional-php

Functional primitives for PHP

2.0k7.3M48](/packages/lstrojny-functional-php)[nikic/iter

Iteration primitives using generators

1.1k5.9M38](/packages/nikic-iter)[ihor/nspl

Non-standard PHP library (NSPL) - functional primitives toolbox and more

381368.5k](/packages/ihor-nspl)[qaribou/immutable.php

Immutable, highly-performant collections, well-suited for functional programming and memory-intensive applications.

344146.0k](/packages/qaribou-immutablephp)[lambdish/phunctional

λ PHP functional library

3612.0M23](/packages/lambdish-phunctional)[crell/fp

Functional utilities for PHP 8 and later

91429.8k11](/packages/crell-fp)

PHPackages © 2026

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