PHPackages                             eonx-com/easy-utils - 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. eonx-com/easy-utils

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

eonx-com/easy-utils
===================

EonX packages utils

6.20.1(1mo ago)11.2M↓22.9%18MITPHPPHP ^8.2

Since Dec 14Pushed 1mo ago3 watchersCompare

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

READMEChangelogDependencies (22)Versions (414)Used By (18)

\---eonx\_docs--- title: Introduction weight: 0 ---eonx\_docs---

EasyUtils
=========

[](#easyutils)

This package provides helper classes.

Require package (Composer)
--------------------------

[](#require-package-composer)

The recommended way to install this package is to use [Composer](https://getcomposer.org/):

```
$ composer require eonx-com/easy-utils
```

Helper list
-----------

[](#helper-list)

- `CollectorHelper`: provides methods to facilitate implementation of the [Collector Design Pattern](https://tomasvotruba.com/blog/2018/06/14/collector-pattern-for-dummies/)
- `Math`: provides methods to facilitate numbers manipulation

CollectorHelper
---------------

[](#collectorhelper)

The [Collector Design Pattern](https://tomasvotruba.com/blog/2018/06/14/collector-pattern-for-dummies/) is a great method for keeping your code SOLID. However, using it in multiple parts of your project can lead to significant repetition. The main purpose of the `CollectorHelper` is to prevent duplicated code and facilitate implementation of the [Collector Design Pattern](https://tomasvotruba.com/blog/2018/06/14/collector-pattern-for-dummies/) in your project.

Most popular PHP frameworks provide features to tag services, and then define all services for a specific tag as dependencies to other services. See the following resources for examples:

- [Tagging Services in CakePHP](https://book.cakephp.org/4.next/en/development/dependency-injection.html#tagging-services)
- [How to Work with Service Tags in Symfony](https://symfony.com/doc/current/service_container/tags.html)
- [Service Tagging in Laravel](https://laravel.com/docs/10.x/container#tagging)

Those features help you implement the [Collector Design Pattern](https://tomasvotruba.com/blog/2018/06/14/collector-pattern-for-dummies/) in your project because they allow you to easily inject a collection of services sharing the same tag into other services.

However, there are some things you need to consider:

- There is no guarantee that all given services are instances of a specific class/interface
- You have no control on the order the services are organised within the given collection

Let's elaborate on the above points.

#### No guarantee on the content of tagged services

[](#no-guarantee-on-the-content-of-tagged-services)

The service tagging features do not allow you to ensure all services sharing the same tag meet common criteria. Symfony has a feature to [automatically tag services based on their class](https://symfony.com/blog/new-in-symfony-3-3-simpler-service-configuration#interface-based-service-configuration), but nothing stops you from manually tagging a service with the same tag or even one of your dependencies.

This is why we strongly recommend you always filter the given `iterable` of services by a given class/interface of your choice by using the `filterByClass()` or `filterByClassAsArray()` methods of the `CollectorHelper`.

#### No control on the order the services are organised

[](#no-control-on-the-order-the-services-are-organised)

When using service tagging features, you can control the order that the services are organised by simply changing the order in which you define the services. However, as above, there is nothing stopping you or one of your dependencies from tagging a service with the same tag. Therefore, you cannot guarantee the order as you cannot modify the dependencies' service definitions. But the `CollectorHelper` can help us!

In some cases, the order of the given services does not matter, so there is no need to do anything. But if your logic requires the services be used in a specific order, then use the `orderHigherPriorityFirst()` and/or `orderLowerPriorityFirst()` methods!

These methods will sort the objects within the given `iterable` based on their priority. In order to define an object's priority, it must implement the `EonX\EasyUtils\Common\Helper\HasPriorityInterface` provided by this package. If an object doesn't implement this interface then its priority will default to `0` automatically.

### CollectorHelper::convertToArray()

[](#collectorhelperconverttoarray)

The `convertToArray()` method will convert any iterable to a simple PHP array. It is useful when you want to use array methods on an `iterable`.

For a simple example of when to use the `convertToArray()` method, imagine you have a class which accepts an `iterable`of "workers" in its constructor. To safely use these "workers", you want to ensure each of them implements the right interface, so you filter them to keep only the "good workers" by using the `array_filter()` function. If the "workers" were already an `array`, then there would be no problem. However, because they are defined as `iterable`, you cannot guarantee you will receive an `array`. So use the `convertToArray()` method!

```
use App\Domain\WorkerInterface;
use EonX\EasyUtils\Common\Helper\CollectorHelper;

final class MyClass
{
    /**
     * @var \App\Domain\WorkerInterface[]
     */
    private array $workers;

    public function __construct(iterable $workers)
    {
        // $workers could be any type of iterable, convert it to array
        $workers = CollectorHelper::convertToArray($workers);

        // Now we are sure $workers is an array, we can use array_filter()
        $workers = \array_filter($workers, static function ($worker): bool {
            return $worker instanceof WorkerInterface;
        });

        // $workers is now an array of WorkerInterface for sure
        $this->workers = $workers;
    }
}
```

### CollectorHelper::filterByClass()

[](#collectorhelperfilterbyclass)

The use case of filtering by class (used above to explain the `convertToArray()` method) is very common (at least in our projects 😃 ), which is why `CollectorHelper` provides the `filterByClass()` method to do it for you.

The following example is the same as for the `convertToArray()` method above. If you have an `iterable` and you want to ensure each item is an instance of a specific class/interface, use the `filterByClass()` method!

```
use App\Domain\WorkerInterface;
use EonX\EasyUtils\Common\Helper\CollectorHelper;

final class MyClass
{
    /**
     * @var iterable
     */
    private array $workers;

    public function __construct(iterable $workers)
    {
        // $workers now contains only WorkerInterface instances
        $workers = CollectorHelper::filterByClass($workers, WorkerInterface::class);

        // The filterByClass() method still returns an iterable, a generator more precisely
        // If you need an array, you can use the filterByClassAsArray() method
        $this->workers = $workers;
    }
}
```

::: tip The `filterByClass()` method still returns an iterable (or, more precisely, a generator). If you need an `array`, you can use the `filterByClassAsArray()` method instead. :::

### CollectorHelper::filterByClassAsArray()

[](#collectorhelperfilterbyclassasarray)

This method is similar to the `filterByClass()` method, but with a little tweak. If you have an `iterable` and you want to make sure each item is an instance of a specific class/interface, but you need the output to be an `array`, use the `filterByClassAsArray()` method!

```
use App\Domain\WorkerInterface;
use EonX\EasyUtils\Common\Helper\CollectorHelper;

final class MyClass
{
    /**
     * @var \App\Domain\WorkerInterface[]
     */
    private array $workers;

    public function __construct(iterable $workers)
    {
        // $workers now contains only WorkerInterface instances
        $workers = CollectorHelper::filterByClassAsArray($workers, WorkerInterface::class);

        // $workers is now an array containing only WorkerInterface instances
        $this->workers = $workers;
    }
}
```

### CollectorHelper::ensureClass() and CollectorHelper::ensureClassAsArray()

[](#collectorhelperensureclass-and-collectorhelperensureclassasarray)

Those methods are similar to the `filterByClass()` and `filterByClassAsArray()` methods, however they will throw an exception if at least of the items is not an instance of the given class.

```
use App\Domain\WorkerInterface;
use EonX\EasyUtils\Common\Helper\CollectorHelper;

final class MyClass
{
    /**
     * @var \App\Domain\WorkerInterface[]
     */
    private array $workers;

    public function __construct(iterable $workers)
    {
        // $workers now contains only WorkerInterface instances
        $workers = CollectorHelper::ensureClass(WorkerInterface::class, $workers);

        foreach ($workers as $worker) {
            // This code will be executed only if all items are instances of WorkerInterface
        }
    }
}
```

::: warning Please note that with the `ensureClass()` method, the exception will be thrown only when iterating through the generator. :::

### CollectorHelper::orderHigherPriorityFirst()

[](#collectorhelperorderhigherpriorityfirst)

The `orderHigherPriorityFirst()` method will ensure the object with the highest priority is placed first, and the object with the lowest priority is placed last.

In order to define an object's priority, it must implement the `EonX\EasyUtils\Common\Helper\HasPriorityInterface` provided by this package. If an object doesn't implement this interface then its priority will default to `0` automatically.

```
// Foo and Bar both implement EonX\EasyUtils\Common\Helper\HasPriorityInterface

$foo = new Foo(); // Has a priority of 10
$bar = new Bar(); // Has a priority of 100

// $foo is added to the array first, and $bar second
$objects = [$foo, $bar];

// $bar is now first as it has a higher priority than $foo
$objects = CollectorHelper::orderHigherPriorityFirst($objects); // [$bar, $foo]
```

::: tip The `orderHigherPriorityFirst()` method still returns an iterable (or, more precisely, a generator). If you need an `array`, you can use the `orderHigherPriorityFirstAsArray()` method instead. :::

### CollectorHelper::orderLowerPriorityFirst()

[](#collectorhelperorderlowerpriorityfirst)

The `orderLowerPriorityFirst()` method is the opposite of `orderHigherPriorityFirst()`. It will ensure the object with the lowest priority is placed first, and the object with the highest priority is placed last.

In order to define an object's priority, it must implement the `EonX\EasyUtils\Common\Helper\HasPriorityInterface` provided by this package. If an object doesn't implement this interface then its priority will default to `0` automatically.

```
// Foo and Bar both implement EonX\EasyUtils\Common\Helper\HasPriorityInterface

$foo = new Foo(); // Has a priority of 10
$bar = new Bar(); // Has a priority of 100

// $foo is added to the array first, and $bar second
$objects = [$foo, $bar];

// $foo is still first as it has a lower priority than $bar
$objects = CollectorHelper::orderLowerPriorityFirst($objects); // [$foo, $bar]
```

::: tip The `orderLowerPriorityFirst()` method still returns an iterable (or, more precisely, a generator). If you need an `array`, you can use the `orderLowerPriorityFirstAsArray()` method instead. :::

Math
----

[](#math)

The Math helper provides the following methods:

- `abs:` returns the absolute value for the given number
- `add:` adds two numbers and returns the result
- `comp:` compares two numbers
- `divide:` divides one number by the other and returns the result
- `multiply:` multiplies one number by the other and returns the result
- `round:` rounds the given number and returns the result
- `sub:` subs tow numbers and returns the result

###  Health Score

64

—

FairBetter than 99% of packages

Maintenance89

Actively maintained with recent releases

Popularity40

Moderate usage in the ecosystem

Community29

Small or concentrated contributor base

Maturity85

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~5 days

Total

406

Last Release

54d ago

Major Versions

3.x-dev → 4.0.62022-03-14

4.5.0 → 5.0.02023-07-25

4.5.5 → 5.5.02023-09-28

5.13.1 → 6.0.0-alpha2024-08-15

5.13.2 → 6.0.0-alpha.22024-08-29

PHP version history (4 changes)2.5.27PHP ^7.2

3.4.0PHP ^7.2 || ^8.0

4.0.2PHP ^8.1

6.0.0-alphaPHP ^8.2

### Community

Maintainers

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

---

Top Contributors

[![natepage](https://avatars.githubusercontent.com/u/11576446?v=4)](https://github.com/natepage "natepage (132 commits)")[![roman-eonx](https://avatars.githubusercontent.com/u/48544017?v=4)](https://github.com/roman-eonx "roman-eonx (116 commits)")[![alexndlm](https://avatars.githubusercontent.com/u/6824784?v=4)](https://github.com/alexndlm "alexndlm (52 commits)")[![itorgov](https://avatars.githubusercontent.com/u/1703419?v=4)](https://github.com/itorgov "itorgov (29 commits)")[![voodooism](https://avatars.githubusercontent.com/u/31572316?v=4)](https://github.com/voodooism "voodooism (7 commits)")[![ERuban](https://avatars.githubusercontent.com/u/13186130?v=4)](https://github.com/ERuban "ERuban (7 commits)")[![alexandrtspl](https://avatars.githubusercontent.com/u/90907144?v=4)](https://github.com/alexandrtspl "alexandrtspl (5 commits)")[![BOB41K1987](https://avatars.githubusercontent.com/u/20467102?v=4)](https://github.com/BOB41K1987 "BOB41K1987 (5 commits)")[![skrut](https://avatars.githubusercontent.com/u/2828162?v=4)](https://github.com/skrut "skrut (2 commits)")[![nick-lc](https://avatars.githubusercontent.com/u/44986892?v=4)](https://github.com/nick-lc "nick-lc (1 commits)")[![zeromodule](https://avatars.githubusercontent.com/u/5268937?v=4)](https://github.com/zeromodule "zeromodule (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/eonx-com-easy-utils/health.svg)

```
[![Health](https://phpackages.com/badges/eonx-com-easy-utils/health.svg)](https://phpackages.com/packages/eonx-com-easy-utils)
```

###  Alternatives

[symfony/maker-bundle

Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.

3.4k111.1M568](/packages/symfony-maker-bundle)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[pentatrion/vite-bundle

Vite integration for your Symfony app

2755.3M13](/packages/pentatrion-vite-bundle)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[netgen/layouts-core

Netgen Layouts enables you to build and manage complex web pages in a simpler way and with less coding. This is the core of Netgen Layouts, its heart and soul.

3689.4k10](/packages/netgen-layouts-core)

PHPackages © 2026

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