dcsg / php-immutable-collections
极简和类型化不可变集合
Requires
- php: ^7.2|^7.4|^8.0|^8.1
Requires (Dev)
- phpunit/phpunit: ^8
- squizlabs/php_codesniffer: ^3.0
This package is auto-updated.
Last update: 2024-09-21 17:40:50 UTC
README
一个为PHP提供一组极简、类型化和管道不可变集合的库。
需求
PHP > 7.2
安装
composer require dcsg/php-immutable-collections
该库解决了哪些问题?
PHP中没有泛型,因此无法在PHP中拥有类型化集合。
此库提供了两个抽象的不可变集合
- 不可变列表集合 - ImmutableCollection
- 不可变集合集合 - SetImmutableCollection
为什么需要类型化不可变集合
类型化集合
由于PHP没有像Java那样的泛型,因此无法拥有本机类型化集合。此库中提供的集合是您创建自己的类型化集合的基础,您只需扩展它们即可。
类型化不可变集合适用于 DDD (领域驱动设计)
DDD的一切都是让您的代码说业务语言,即无处不在的语言。没有PHP中的集合,使用数组
来实现这一点非常困难,因为您不能向它们添加行为。所以通常会发生的是,您将这种行为添加到您的实体中,但这不应该在那里。另一个问题是数组的可变性,VOs
(值对象) MUST 始终是 不可变 的,而使用 数组
和 VOs
是不可能的,您应该始终保证该数组的 元素
都是同一类型的。
集合与 数组 的比较
集合
和数组
都表示一组元素。集合
不是PHP的原生支持,而数组
是。数组
是PHP的THE数据结构,几乎用于所有事情。数组
不允许您添加新的行为,而集合
允许。数组
不允许您为其元素定义一个 类型,而集合
允许。
其他PHP集合
还有其他PHP集合,例如我们有的 Doctrine Collections 和 Illuminate Collections。这些集合解决了不同的问题,针对特定的用例进行了定制,它们的API广泛,更重要的是,这些集合是可变的。这些组合使得在更简单的用例中使用这些集合变得困难。这就是为什么我们提供的集合有一个非常小的API,甚至不公开迭代器API。这样,您就有可能使用它们并扩展其行为,以满足您的需求。
特性
- 用于管道使用的静态构造。
- 一些实用方法,如
isEmpty
、count
、toArray
、contains
、get
、map
、filter
、slice
、merge
、reverse
、reduce
、first
、last
、head
、tail
。
基本用法
创建类型化列表集合
<?php declare(strict_types=1); use DCSG\ImmutableCollections\ImmutableCollection; final class MyStringCollection extends ImmutableCollection { protected function validateItems(array $elements): void { foreach ($elements as $element) { if (!\is_string($element)) { throw new InvalidArgumentException('Element is not a String.'); } } } } $collection = MyStringCollection::create(['foo', 'bar']); echo $collection->count(); // 2 $slicedCollection = $collection->slice(0, 1); // MyStringCollection { $elements=['foo']}
创建类型化集合集合
<?php declare(strict_types=1); use DCSG\ImmutableCollections\SetImmutableCollection; final class MyStringSetCollection extends SetImmutableCollection { protected function validateItems(array $elements): void { foreach ($elements as $element) { if (!\is_string($element)) { throw new InvalidArgumentException('Element is not a String.'); } } } } $collection = MyStringSetCollection::create(['foo', 'bar']); echo $collection->count(); // 2 $slicedCollection = $collection->tail(); // MyStringSetCollection { $elements=['bar']} $collection = MyStringSetCollection::create(['foo', 'bar', 'foo']); // Throws InvalidArgumentException
示例
我们提供两个简单的示例以帮助更好地理解。一个与发票相关,另一个与货船航段有关。
变更日志
请参阅变更日志以获取有关最近更改的更多信息。
测试
$ composer test
贡献
安全性
如果您发现任何与安全相关的问题,请通过电子邮件hi@dcsg.me联系,而不是使用问题跟踪器。
鸣谢
许可协议
MIT 许可协议 (MIT)。请参阅许可文件以获取更多信息。