PHPackages                             mblarsen/arrgh - 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. mblarsen/arrgh

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

mblarsen/arrgh
==============

Arrgh—a sane PHP array library

0.11.0(10y ago)82922MITPHPPHP &gt;=5.6

Since Jan 27Pushed 10y ago4 watchersCompare

[ Source](https://github.com/mblarsen/arrgh)[ Packagist](https://packagist.org/packages/mblarsen/arrgh)[ RSS](/packages/mblarsen-arrgh/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (23)Used By (0)

Arrgh—a sane PHP array library
==============================

[](#arrgha-sane-php-array-library)

[![Build Status](https://camo.githubusercontent.com/861ce519286b9abafab361fd4e281dc7e4b42b0a4f7a4b4e050f308e138cda68/68747470733a2f2f7472617669732d63692e6f72672f6d626c617273656e2f61727267682e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/mblarsen/arrgh) [![Coverage Status](https://camo.githubusercontent.com/b133c744fb48ee3ed2290a0d70a945850168c6323278c09abab9df7bd01039a9/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6d626c617273656e2f61727267682f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/mblarsen/arrgh?branch=master) [![Total Downloads](https://camo.githubusercontent.com/dad0a2874cfb30a1418ed8c1c8fbcd9ecae85b5457d550db4b402d0d5297ff1e/68747470733a2f2f706f7365722e707567782e6f72672f6d626c617273656e2f61727267682f646f776e6c6f6164732e737667)](https://packagist.org/packages/mblarsen/arrgh) [![Scrutinizer Code Quality](https://camo.githubusercontent.com/505db5c19d817efb334bdb7da0f2ce83a038e841d83dd66e1644c01a50098603/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d626c617273656e2f61727267682f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/mblarsen/arrgh/?branch=master) [![Codacy Badge](https://camo.githubusercontent.com/f4352e094cb387eba3adb0bcc413c2ca0678f86646a58123fc72c83c33dbc0b4/68747470733a2f2f6170692e636f646163792e636f6d2f70726f6a6563742f62616467652f67726164652f3663646165346134386333393435343239323232303039336365633234376663)](https://www.codacy.com/app/mblarsen/arrgh)
[![Get help on Codementor](https://camo.githubusercontent.com/946849bf79fb5d17765232b1fe38f4184923e7d4e532bcb028dd14b2b26ecc52/68747470733a2f2f63646e2e636f64656d656e746f722e696f2f6261646765732f6765745f68656c705f6769746875622e737667)](https://www.codementor.io/mblarsen?utm_source=github&utm_medium=button&utm_term=mblarsen&utm_campaign=github) [![Join the chat at https://gitter.im/mblarsen/arrgh](https://camo.githubusercontent.com/ef6f557cdd3afee5fd90f4a60b23484b046b5946db07268fc2bab0a5a9791125/68747470733a2f2f6261646765732e6769747465722e696d2f6d626c617273656e2f61727267682e737667)](https://gitter.im/mblarsen/arrgh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

The goal of *Arrgh* is to provide a more uniform library for working with arrays in PHP.

- Arrays as first parameter and they are immutable. The existing API for arrays can be confusing. For some functions the input array is the first parameter on others the last. Moreover some functions returns a new array others mutate the input array (passing it by reference).
- *Arrgh* is not a re-write but a remapping of parameters to native functions. E.g. `array_map($callable, $array)` becomes `arr_map($array, $callable)`.
- Comes in three flavors:
    1. function `arr_map($people, $callable)`
    2. static `Arrgh::map($people, $callable)`
    3. object/chainable `$array->map($callable)`
- Adds missing functions like: `tail`, `collapse`, `sortBy`, `mapAssoc` (associative mapping function), `get` (a dot-path getter) and many more. (see [Additional functions](#additional-functions))
- Sorting and comparing works both with PHP5 and PHP7, even for your custom sort and compare functions.
- You can use the the names you know or shorter ones using snake\_case or camelCase. E.g. `$array->array_map()`, `$array->arrayMap()`, `$array->map()`.

Installing
----------

[](#installing)

```
composer require mblarsen/arrgh

```

Examples
--------

[](#examples)

Functions takes array as the first parameter in every case—no more looking up in the documents:

```
arr_map($input, $callable);
arr_join($input, ",");

```

Chain functions together:

```
arr($input)->reverse()->slice(0, 5)->sum();

```

Powerful get function using *dot-paths*:

```
// People and their children
$array = [
    [ "name" => "Jakob", "age" => 37, "children" => [
        [ "name" => "Mona", "sex" => "female" ],
        [ "name" => "Lisa", "sex" => "female" ],
    ] ],
    [ "name" => "Topher", "age" => 18, "children" => [
        [ "name" => "Joe", "sex" => "male" ],
    ] ],
    [ "name" => "Ginger", "age" => 43 ],
];

// Return all children's names
arr_get($array, "children.name");      // returns [ ["Mona", "Lisa"] , ["Joe"] ]
arr_get($array, "children.name", true) // returns [ "Mona", "Lisa", "Joe" ]

```

Use buil-in select functions, select by index:

```
arr_get($array, "children.0.name");    // returns [ ["Mona"], ["Joe"] ]
arr_get($array, "children.1.name");    // returns [ ["Lisa"] ]
arr_get($array, "children.-1.name");   // returns [ ["Lisa"], ["Joe"] ]

```

... or roll your own select functions, return names of all female children:

```
$children = arr($array)->get([ "children.!$.name",
    function ($item, $index) { return $item['sex'] === 'female'; }
])->toArray();

// returns [ Mona, Lisa ]

```

*(Syntax: An array with the path followed by a callable for each occurance of `!$` in the path)*

To achieve the same using chain API (which is also pretty concise) it looks like this:

```
$children = arr($array)
    ->map(function ($person) { return isset($person["children"]) ? $person["children"] : null; })
    ->filter()
    ->collapse()
    ->map(function ($child) {
        if ($child["sex"] === "female") { return $child["name"]; }
        return null;
    })
    ->filter()
    ->toArray();

```

Array as first argument
-----------------------

[](#array-as-first-argument)

*Arrgh* doesn't rewrite the array algorithms but remaps parameters to native functions. E.g. `arr_map` moves the `$callable` as the last parameter.

```
array_map ( callable $callback , array $array1 [, array $... ] )

```

Becomes:

```
arr_map ( array $array1 [, array $... ] , callable $callback )

```

Example usage:

```
arr_map($products, function ($product) {
    return $product->code();
});

```

All functions that takes one or more arrays now takes them as their first arguments:

```
array_key_exists($key, $array)         => ($array, $key)
in_​array($key, $array)                 => ($array, $key)
array_search($search, $array)          => ($array, $search)
implode($glue, $array)                 => ($array, $glue);
join($glue, $array)                    => ($array, $glue);
array_map($callable, $array[, arrayN]) => ($array[, arrayN], $callable)

```

All functions are immutable
---------------------------

[](#all-functions-are-immutable)

Most of the functions that makes alterations to arrays like sorting all pass the input array by reference like:

```
usort ( array &$array , callable $value_compare_func )

```

This make functional programming difficult and less fluent in PHP.

In *Arrgh* all array functions will return an array, unless of course a value is being computed (`sum`, `pop`, `min`, `max`, etc).

These functions will now return a result:

[array multisort](http://php.net/manual/en/function.array_multisort.php), [array push](http://php.net/manual/en/function.array_push.php), [array splice](http://php.net/manual/en/function.array_splice.php), [array walk](http://php.net/manual/en/function.array_walk.php), [array walk recursive](http://php.net/manual/en/function.array_walk_recursive.php), [arsort](http://php.net/manual/en/function.arsort.php), [asort](http://php.net/manual/en/function.asort.php), [krsort](http://php.net/manual/en/function.krsort.php), [ksort](http://php.net/manual/en/function.ksort.php), [natcasesort](http://php.net/manual/en/function.natcasesort.php), [natsort](http://php.net/manual/en/function.natsort.php), [rsort](http://php.net/manual/en/function.rsort.php), [shuffle](http://php.net/manual/en/function.shuffle.php), [sort](http://php.net/manual/en/function.sort.php), [uasort](http://php.net/manual/en/function.uasort.php), [uksort](http://php.net/manual/en/function.uksort.php), [usort](http://php.net/manual/en/function.usort.php)

This means where you had to like this:

```
// Top 5 most expensive products
array_usort($products, function ($p1, $p2) { ... };
return array_slice($products, 0, 5);

```

You can now do like this:

```
// Top 5 most expensive products
return arr_slice(arr_usort($products, function ($p1, $p2) { ... }), 0, 5);

```

Or you could use chains like this \[[see more below](#chain-style)\]:

```
// Top 5 most expensive products
return arr($products)
    ->usort($products, function ($p1, $p2) { ... })
    ->slice(0, 5);

```

Choose your style
-----------------

[](#choose-your-style)

*Arrgh* comes in three styles for your temperament:

- [Function style](#function-style)
- [Static style](#static-style)
- [Chain style](#chain-style)

### Function style

[](#function-style)

The *Arrgh* repertoire of functions is include in the global scope, so that you can use the functions anywhere. Just like the native array functions:

```
arr_replace($defaults, $params);

```

The constructor function `aargh()` lets you start a chain:

```
arr($defaults)->replace($params);

```

#### Using function style

[](#using-function-style)

If you want to make use of function-style you have to define the following before autoloading.

```
define("ARRGH", true);
require __DIR__ . "/vendor/autoload.php";

```

You can change the function prefix using:

```
define("ARRGH_PREFIX", "arr");

```

Now `arr_reverse` becomes:

```
arr_reverse([1, 2, 3]);

```

*Note: changing the function prefix requires the use of `eval()`. If `eval()` is disabled *Arrgh* will throw an exception. *Arrgh* comes prebuild with `arrgh` and `arr` prefixes, so for these `eval()` is not needed.*

### Static style

[](#static-style)

You can use the static functions on `Arrgh`:

```
Arrgh::array_flip($music);
Arrgh::flip($music);

```

All static methods takes an array as the first input and returns an array. Even sort:

```
return Arrgh::sort($big_numbers);

```

You can break out of static-style and start a [chain](#chain-style) like this:

```
Arrgh::arr($big_numbers)
    ->sort()
    ->reduce(function ($k, $v) { return $k += ln($v); });

```

A synonym of `arrgh` is `chain`. A shorthand for both is to prefix any method with *underscore*:

```
Arrgh::_sort($big_numbers)
    ->reduce(function ($k, $v) { return $k += $v });

```

`_sort()` returns chainable *Arrgh* object.

### Chain style

[](#chain-style)

Chains can be created in a couple of ways.

Using the `arr()` function:

```
arr($array)->reverse();

```

Using the static methods `Arrgh::arr()` or `Arrgh::chain()`:

```
Arrgh::chain($array)->reverse();

```

Using the static method shorthand (\_):

```
Arrgh::_reverse($array);

```

Or by creating a chainable object:

```
$videos = new Arrgh($videos);
$media = $videos->merge($music)->shuffle()->slice(0, 3);

```

When you are working with objects all methods returns an object, not an actual array. To get a native PHP array invoke the `toArray()` method:

```
$media->toArray();

```

*Note: *Arrgh* implements both [ArrayAccessphp](http://php.net/manual/en/class.arrayaccess.php) and [Iteratorphp](http://php.net/manual/en/class.iterator.php) so you can [use an Arrgh object as an array](#works-like-array).*

In case you want to preserve the array rather than the result of a terminating functions like e.g. `pop()`, you can use `keepChain()`:

```
arr([1, 2, 3])->pop(); // will return 3

```

With use of `keepChain()` we'll get the array instead:

```
arr([1, 2, 3])->keepChain()->pop(); // will return an Arrgh object with the array [1, 2]

```

If you want to break the chain again. For example to get the sum of the remaining elements you can:

```
arr([1, 2, 3])->keepChain()->pop()->keepChain(false)->sum(); // returns 3
arr([1, 2, 3])->keepChain()->pop()->breakChain()->sum(); // breakChain() = keepChain(false)

```

If `->keepChain(false)` had been left out `sum()` would also have returned the `Arrgh` object.

The same expression can be written using `keepOnce()`:

```
arr([1, 2, 3])->keepOnce()->pop()->sum(); // returns 3

```

All functions are there
-----------------------

[](#all-functions-are-there)

All the functions from the PHP manual [Array Functionsphp](http://php.net/manual/en/ref.array.php) section are supported.

If you use function style the methods are prefixed with `arr_` except for functions starting with `array_` (in that case it is replaced):

```
array_map => arr_map
usort => arr_usort

```

These functions are not supported:

[compact](http://php.net/manual/en/function.compact.php), [extract](http://php.net/manual/en/function.extract.php), [current](http://php.net/manual/en/function.current.php), [each](http://php.net/manual/en/function.each.php), [key](http://php.net/manual/en/function.key.php), [next](http://php.net/manual/en/function.next.php), [pos](http://php.net/manual/en/function.pos.php), [prev](http://php.net/manual/en/function.prev.php), [reset](http://php.net/manual/en/function.reset.php)

Additional functions
--------------------

[](#additional-functions)

In addition to [Array Functionsphp](http://php.net/manual/en/ref.array.php) *Arrgh* provides these functions:

- `map_assoc(array, function)`: Map function that works on associative arrays. Map function `function ($key, $value)`.
- `sort_by(array, key|function)`: Sort a collection of items by a key or a function. Sort function `function ($item)`.
- `contains(array, [key])`: Looks through a collection for a certain value and returns true or falls. Can be restricted to a key.
- `collapse(array)`: Collapses an array of arrays into one. E.g. `[[1, 2], [3, 4]]` becomes `[1, 2, 3, 4]`
- `except(array, key|array)`: Return all collections of items having some keys in `key|array` stripped.
- `only(array, key|array)`: Like `except` but will only return items with the keys in `key|array`.
- `get(array, path)`: A powerful getter of multidimensional arrays.
- `isCollection(array)`: Tells if an array is a collection (as opposed ot an associative array)
- `depth(array)`: Tells the depth of arrays of arrays (excluding associative arrays)
- `head(array)`: Synonym for shift
- `tail(array)`: Returns everything but the head. E.g. tail(\[1, 2, 3\]) outputs \[2, 3\]
- `first(array)`: Synonym for shift
- `last(array)`: Synonym for pop
- `partition(array, callable)`: Splits array into two arrays determined by callable function
- `odd(array)`: Gives all odd-indexed items in an array. 1, 3, 5, etc.
- `even(array)`: Gives all even-indexed items in an array. 0, 2, 4, etc.

Works like array
----------------

[](#works-like-array)

*Arrgh* implements [ArrayAccessphp](http://php.net/manual/en/class.arrayaccess.php) and [Iteratorphp](http://php.net/manual/en/class.iterator.php), so you can use it as an array.

Here is an example using foreach:

```
$arr = arr([1, 2, 3, 4, 5]);
foreach ($arr as $value) {
    echo $value . PHP_EOL;
}

```

You can push values onto array like native arrays:

```
echo $arr->sum(); // 15
$arr[] = 6;
echo $arr->sum(); // 21

```

Array values are returned as `Arrgh` objects:

```
$arr = arr([[3, 2, 1], [5, 4]]);
$content = arr([]);
foreach ($arr as $value) {
    $content = $content->merge($value->reverse());
}
$content->toArray(); // returns array [ 1, 2, 3, 4, 5 ];

```

*Note: PHP's native functions can only take arrays as parameters, so that is a limitation. But you are not using them anyway are you?*

If you want to make use of function-style you have to define the following before `vendor/autoload` require.

```
define("ARRGH", true);

```

Now you can use functions like this anywhere in your code:

```
arr_reverse([1, 2, 3]);

```

You can change the function prefix using:

```
define("ARRGH_PREFIX", "arrgh");

```

Now `arr_reverse` becomes:

```
arrgh_reverse([1, 2, 3]);

```

*Note: changing the function prefix requires the use of `eval()`. If `eval()` is disabled *Arrgh* will throw an exception. *Arrgh* comes prebuild with arr prefixes, so for these `eval()` is not needed.*

PHP5 vs PHP7
------------

[](#php5-vs-php7)

At the time of writing if PHP5 and PHP7 treats equal values returned by comparable-functions differently.

For example. The following unittest will fail in PHP 5.6.x and not in 7:

```
$original_input = [
    [ "name" => "Jakob", "age" => 42 ],
    [ "name" => "Topher", "age" => 18 ],
    [ "name" => "Ginger", "age" => 42 ],
];
$expected_result = [
    [ "name" => "Topher", "age" => 18 ],
    [ "name" => "Jakob", "age" => 42 ],
    [ "name" => "Ginger", "age" => 42 ],
];

$input = $original_input;
usort($input, function ($a, $b) {
    return $a["age"] - $b["age"];
});

// Actual ouput in PHP5 (Jakob and Ginger reversed):
// [
//     [ "name" => "Topher", "age" => 18 ],
//     [ "name" => "Ginger", "age" => 42 ],
//     [ "name" => "Jakob", "age" => 42 ],
// ]
//
// Actual ouput in PHP7 (Jakob and Ginger in the original order):
// [
//     [ "name" => "Topher", "age" => 18 ],
//     [ "name" => "Jakob", "age" => 42 ],
//     [ "name" => "Ginger", "age" => 42 ],
// ]

```

PHP5 and PHP7 treats the items in an array with a compare result differently. You have to take this into account if you code for both versions. While PHP5 changes the order, PHP7 does not have this side-effect.

*Arrgh* elevates this problem by providing the correctly signed integer depending on which version is running. So when running your custom compare functions you can do like this:

```
usort($input, function ($a, $b) {
    return Arrgh::getSortDirection($a["age"] - $b["age"]);
});

```

or using *Arrgh*:

```
arr_usort($input, function ($a, $b) {
    return Arrgh::getSortDirection($a["age"] - $b["age"]);
});

```

See example in the unit test `ArrghGeneralTest::testPhpVersionFail*`.

**As of v0.6 *Arrgh* handles this internally** so you can simply do like this:

```
arr_usort($input, function ($a, $b) {
    return $a["age"] - $b["age"];
});

```

The callable is wrapped in PHP version aware callable that inspects the result and returns a value according to the PHP version.

Changelog
---------

[](#changelog)

See [CHANGELOG.md](https://github.com/mblarsen/arrgh/blob/master/CHANGELOG.md)

TODO
----

[](#todo)

See [TODO.md](https://github.com/mblarsen/arrgh/blob/master/TODO.md)

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.8% 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 ~1 days

Total

22

Last Release

3732d ago

PHP version history (2 changes)0.1.0PHP ^5.6

0.5.1PHP &gt;=5.6

### Community

Maintainers

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

---

Top Contributors

[![mblarsen](https://avatars.githubusercontent.com/u/247048?v=4)](https://github.com/mblarsen "mblarsen (89 commits)")[![gitter-badger](https://avatars.githubusercontent.com/u/8518239?v=4)](https://github.com/gitter-badger "gitter-badger (1 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (1 commits)")

---

Tags

shimarrayfunctionalchainingPHP7Chain

### Embed Badge

![Health badge](/badges/mblarsen-arrgh/health.svg)

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

###  Alternatives

[symfony/polyfill-mbstring

Symfony polyfill for the Mbstring extension

7.8k1.2B514](/packages/symfony-polyfill-mbstring)[symfony/polyfill-php72

Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions

4.8k674.7M31](/packages/symfony-polyfill-php72)[symfony/polyfill-intl-idn

Symfony polyfill for intl's idn\_to\_ascii and idn\_to\_utf8 functions

3.4k774.6M90](/packages/symfony-polyfill-intl-idn)[symfony/polyfill-intl-normalizer

Symfony polyfill for intl's Normalizer class and related functions

2.1k830.2M36](/packages/symfony-polyfill-intl-normalizer)[symfony/polyfill-php80

Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions

1.7k815.2M455](/packages/symfony-polyfill-php80)[symfony/polyfill-intl-grapheme

Symfony polyfill for intl's grapheme\_\* functions

1.7k702.8M27](/packages/symfony-polyfill-intl-grapheme)

PHPackages © 2026

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