eonx-com/easy-utils

EonX 包工具类

6.0.0 2024-09-12 07:59 UTC

This package is auto-updated.

Last update: 2024-09-19 04:47:52 UTC


README

---eonx_docs--- 标题:介绍 重量:0 ---eonx_docs---

EasyUtils

此包提供辅助类。

所需包(Composer)

安装此包的推荐方法是使用 Composer

$ composer require eonx-com/easy-utils

辅助类列表

  • CollectorHelper:提供方便实现 收集者设计模式 的方法
  • Math:提供方便数字操作的方法

CollectorHelper

收集者设计模式 是一种保持你的代码 SOLID 的好方法。然而,在项目的多个部分中使用它可能导致大量的重复。CollectorHelper 的主要目的是防止代码重复,并方便在你的项目中实现 收集者设计模式

大多数流行的 PHP 框架提供了标记服务并定义特定标签的所有服务作为其他服务的依赖项的功能。以下是一些示例资源

这些功能可以帮助你在项目中实现 收集者设计模式,因为它们允许你轻松地将共享相同标签的服务集合注入到其他服务中。

但是,有一些事情你需要考虑

  • 没有保证所有提供的服务都是特定类/接口的实例
  • 你没有控制给定集合中服务的组织顺序

让我们详细阐述以上几点。

无法保证标记服务的内

服务标记功能不允许你确保共享相同标签的所有服务满足共同的标准。Symfony 有一个功能可以 自动根据类自动标记服务,但没有任何阻止你手动使用相同标签或甚至你的依赖项标记服务的。

这就是为什么我们强烈建议你始终使用 CollectorHelperfilterByClass()filterByClassAsArray() 方法通过你选择的类/接口过滤提供的 iterable 服务。

无法控制服务的组织顺序

当使用服务标记功能时,你可以通过简单地改变定义服务的顺序来控制服务的组织顺序。然而,正如上面所述,没有任何阻止你或你的依赖项使用相同标签标记服务的。因此,你不能保证顺序,因为你不能修改依赖项的服务定义。但 CollectorHelper 可以帮助我们!

在某些情况下,给定服务的顺序并不重要,因此不需要做任何事情。但如果你需要按照特定顺序使用服务,则使用 orderHigherPriorityFirst() 和/或 orderLowerPriorityFirst() 方法!

这些方法将根据优先级对给定 iterable 中的对象进行排序。为了定义对象的优先级,它必须实现本包提供的 EonX\EasyUtils\Common\Helper\HasPriorityInterface 接口。如果对象没有实现此接口,则其优先级将自动默认为 0

CollectorHelper::convertToArray()

convertToArray() 方法将任何可迭代的对象转换为简单的 PHP 数组。当你想在可迭代对象上使用数组方法时,这很有用。

以下是一个简单示例,说明何时使用 convertToArray() 方法。假设你有一个类,其构造函数接受一个 "workers" 的 iterable。为了安全地使用这些 "workers",你想要确保每个都实现了正确的接口,所以你使用 array_filter() 函数来过滤它们,只保留 "好工人"。如果 "workers" 已经是一个 array,那么就没有问题。然而,因为它们被定义为 iterable,你不能保证你会收到一个 array。所以使用 convertToArray() 方法!

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()

按类过滤的使用场景(如上所述,用于解释 convertToArray() 方法)非常常见(至少在我们的项目中 😃 ),这就是为什么 CollectorHelper 提供了 filterByClass() 方法来自动完成它。

以下示例与上述 convertToArray() 方法相同。如果你有一个 iterable,并且想确保每个项目都是特定类/接口的实例,请使用 filterByClass() 方法!

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

final class MyClass
{
    /**
     * @var iterable<\App\Domain\WorkerInterface>
     */
    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 filterByClass() 方法仍然返回一个可迭代对象(更准确地说,是一个生成器)。如果你需要一个 array,可以使用 filterByClassAsArray() 方法代替。 ::

CollectorHelper::filterByClassAsArray()

此方法与 filterByClass() 方法类似,但略有不同。如果你有一个可迭代对象,并想确保每个项都是特定类/接口的实例,但需要输出是 array,请使用 filterByClassAsArray() 方法!

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() 和 CollectorHelper::ensureClassAsArray()

这些方法与 filterByClass()filterByClassAsArray() 方法类似,但是当至少有一个项目不是给定类的实例时,它们将抛出异常。

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 请注意,在迭代生成器时,只有当使用 ensureClass() 方法时才会抛出异常。 ::

CollectorHelper::orderHigherPriorityFirst()

orderHigherPriorityFirst() 方法将确保具有最高优先级的对象被放在第一位,具有最低优先级的对象被放在最后。

为了定义对象的优先级,它必须实现本包提供的 EonX\EasyUtils\Common\Helper\HasPriorityInterface 接口。如果对象没有实现此接口,则其优先级将自动默认为 0

// 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 orderHigherPriorityFirst() 方法仍然返回一个可迭代对象(更准确地说,是一个生成器)。如果你需要一个 array,可以使用 orderHigherPriorityFirstAsArray() 方法代替。 ::

CollectorHelper::orderLowerPriorityFirst()

orderLowerPriorityFirst() 方法是 orderHigherPriorityFirst() 的反方法。它将确保具有最低优先级的对象被放在第一位,具有最高优先级的对象被放在最后。

为了定义对象的优先级,它必须实现本包提供的 EonX\EasyUtils\Common\Helper\HasPriorityInterface 接口。如果对象没有实现此接口,则其优先级将自动默认为 0

// 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 orderLowerPriorityFirst() 方法仍然返回一个可迭代对象(更准确地说,是一个生成器)。如果你需要一个 array,可以使用 orderLowerPriorityFirstAsArray() 方法代替。 ::

数学

数学助手提供了以下方法

  • abs: 返回给定数字的绝对值
  • add: 将两个数字相加并返回结果
  • comp: 比较两个数字
  • divide: 将一个数字除以另一个并返回结果
  • multiply: 将一个数字乘以另一个并返回结果
  • round: 对给定数字进行四舍五入,并返回结果
  • sub: 从两个数中减去,并返回结果