eboreum/collections

希望 PHP 有泛型吗?这个库提供了一种管理数据集合(即具有限制的数组)的合理方式,直到 PHP 泛型降临。

1.1.0 2022-07-28 14:45 UTC

This package is auto-updated.

Last update: 2024-08-29 00:45:42 UTC


README

license build Code Coverage PHPStan Level

希望 PHP 有泛型吗?这个库提供了一种管理数据集合(即具有限制的数组)的合理方式,直到 PHP 泛型降临。

完全配备 phpstan 泛型注释。有关详细信息,请参阅: https://phpstan.org/blog/generics-in-php-using-phpdocs

需求

"php": "^8.1",
"eboreum/caster": "^1.0",
"eboreum/exceptional": "^1.0"

有关更多信息,请参阅 composer.json 文件。

安装

通过 Composer (https://packagist.org.cn/packages/eboreum/collections)

composer install eboreum/collections

通过 GitHub

git clone git@github.com:eboreum/collections.git

基础

此库有两个核心组件

  1. Eboreum\Collections\Collection
  2. 接口 Eboreum\Collections\Contract\CollectionInterface

Eboreum\Collections\Collection 本身不施加任何限制,可以用于存储任何数据类型。它可以被视为一个花哨的数组。然而,它有两个关键的区别和优势:它是 不可变的 并且它有 类型提示,包括泛型的注解(《https://phpstan.org/blog/generics-in-php-using-phpdocs》)。

当你开始创建集合类,扩展 Eboreum\Collections\Collection,它具有限制时,这个库的真实力量就显现出来了。

此库配备了以下简单数据类型集合类

  • Eboreum\Collections\FloatCollection:一个只包含浮点数的集合。
  • Eboreum\Collections\IntegerCollection:一个只包含整数的集合。
  • Eboreum\Collections\ObjectCollection:一个只包含对象(任何对象)的集合。下面将详细介绍如何为特定类实例创建集合。
  • Eboreum\Collections\StringCollection:一个只包含字符串的集合。

当我们开始对集合类的内容施加限制时,比如对特定类的限制,真正的亮点就出现了。

此库有以下 预定义类集合

  • \Eboreum\Collections\Object_\ClosureCollection:一个可能且只包含 \Closure 实例的集合。
  • \Eboreum\Collections\Object_\DateTimeCollection:一个可能且只包含 \DateTime 实例的集合。
  • \Eboreum\Collections\Object_\DateTimeImmutableCollection:一个可能且只包含 \DateTimeImmutable 实例的集合。
  • \Eboreum\Collections\Object_\DateTimeInterfaceCollection:一个可能且只包含 \DateTimeInterface 实例的集合。
  • \Eboreum\Collections\Object_\DirectoryCollection:一个可能且只包含 \Directory 实例的集合。
  • \Eboreum\Collections\Object_\ErrorCollection:一个可能且只包含 \Error 实例的集合。
  • \Eboreum\Collections\Object_\ExceptionCollection:一个可能且只包含 \Exception 实例的集合。
  • \Eboreum\Collections\Object_\SplFileInfoCollection:一个可能且只包含 \SplFileInfo 实例的集合。
  • \Eboreum\Collections\Object_\SplFileObjectCollection:一个可能且只包含 \SplFileObject 实例的集合。
  • \Eboreum\Collections\Object_\ThrowableCollection:一个可能且只包含 \Throwable 实例的集合。
  • \Eboreum\Collections\Object_\stdClassCollection:一个集合,可能且只能包含\stdClass的实例。

您可以将上述文件作为构建您自己的特定类集合的灵感来源。然而,这个过程可以自动化;更多关于自动化的信息请参阅下文。

上述类使用抽象类\Eboreum\Collections\Abstraction\AbstractNamedClassOrInterfaceCollection以及随后使用的接口\Eboreum\Collections\Contract\ObjectCollectionInterface

自动化编写集合类

⚠️ 注意 ⚠️

“eboreum/collection-class-generator”尚未公开提供!

编写成百上千个结构基本相同的集合类是繁琐的。可以通过利用https://packagist.org.cn/packages/eboreum/collection-class-generator来自动化这个过程,该工具将为您自动编写所需的全部集合类,并将其直接写入您的项目中的指定位置。它甚至还提供了可选的单元测试编写(https://packagist.org.cn/packages/phpunit/phpunit)!

为任何东西创建集合——而不仅仅是类

您可以对任何东西设置限制——而不仅仅是类——包括联合(https://php.watch/versions/8.0/union-types)。本质上,您只需在您实现的集合类中重写isElementAccepted方法。

需要同时接受整数和浮点数的工具(联合)?

只需做以下操作

/**
 * {@inheritDoc}
 */
public static function isElementAccepted($element): bool
{
    return is_int($element) || is_float($element);
}

请记住:如果您使用phpstan,您也应该在您的自定义集合类中添加和/或更新@template及其引用。

您还应该用合适的返回类型重写如currentfindfirst等方法。例如

PHP ^8.1

/**
 * {@inheritDoc}
 */
public function current(): int|float
{
    // ...
}

注意:交集类型(https://php.watch/versions/8.1/intersection-types)不支持,因为它们由于https://wiki.php.net/rfc/nullable_intersection_types被拒绝而未得到PHP 8的支持。

原因是当处理交集时,如currentfindfirst等方法不能有可空的返回类型。

测试

测试/开发要求

"phpstan/phpstan": "^1.4",
"phpunit/phpunit": "^9.5"

运行测试

对于所有单元测试,首先遵循以下步骤

cd tests
php ../vendor/bin/phpunit

许可 & 声明

请参阅LICENSE文件。基本上:使用此库的风险自负。

贡献

我们更喜欢您在我们的https://github.com/eboreum/collections上创建一个工单或拉取请求,并在此处讨论功能或错误。

没有\ArrayAccess

这个库不会也不将使用\ArrayAccesshttps://php.ac.cn/manual/en/class.arrayaccess.php)。

这与该库不可变的本质相悖,有点邪恶,并且使代码变得不必要地晦涩。

致谢

作者

致谢

doctrine/collections

此库深受https://packagist.org.cn/packages/doctrine/collections (https://github.com/doctrine/collections) 的启发,并且确实有一些代码是从该库复制的(通过在选定文件顶部包含LICENSE文件内容进行认可,如https://github.com/doctrine/collections/blob/94918256daa6ac99c7e5774720c0e76f01936bda/LICENSE所要求)。