fusion-php / collection
适用于PHP 7.4+的小型集合库
Requires
- php: >=7.4
Requires (Dev)
- phpunit/phpunit: ^9
README
本包提供一个小型集合库,适用于在对象中聚合数据值。存储的值可以通过方法、循环或数组访问。
需求
PHP 7.4或更高版本。
安装
此包通过Composer安装。
composer require fusion-php/collection
用法
该库提供了两种不同类型的集合。基本对象,简单地称为Collection
,以及Dictionary
。这两种类型有两个变体,称为TypedCollection
和TypedDictionary
,用于存储特定对象类型的实例。
实例化
可以通过构造函数或使用CollectionFactory
类创建本库提供的任何集合对象。本节以下内容将假设使用CollectionFactory
类创建集合对象。有关构造函数实例化的信息,请参阅以下手动实例化部分。
集合类
Collection
对象将保留PHP数组可以保留的任何值,除了null
值。
Collection
可以实例化为空或包含起始元素的数组。在后一种情况下,现有数组的键将被忽略。
<?php namespace App; use Fusion\Collection\CollectionFactory; require '../vendor/autoload.php'; $collection = CollectionFactory::newCollection(); //empty // ... or ... $items = ['foo', 'bar', 'baz']; $collection = CollectionFactory::newCollection($items); var_dump($collection->count()); //int (3)
如上所示,count()
方法返回一个整数,表示集合中的项目数。集合使用Countable接口,允许您通过PHP的count()
方法以另一种方式获取集合大小。
$size = count($collection); //same as $size = $collection->count();
要向集合添加项目,请使用add()
方法并传递您希望存储的值。
$collection->add(42);
使用带有现有索引的find()
方法从集合中检索值。
$collection = CollectionFactory::newCollection(['foo', 'bar', 'baz']); var_dump($collection->find(1)); //string 'bar'
可以通过调用replace()
方法并传递要替换的值的索引和替换值来替换集合中的值。
$collection = CollectionFactory::newCollection(['foo', 'bar', 'baz']); $collection->replace(1, 'bam'); //Collection is now ['foo', 'bam', 'baz']
要从不集合中删除项目,请使用remove()
方法并传递要删除的值。
$collection = CollectionFactory::newCollection(['foo', 'bar', 'baz']); $collection->remove('foo'); //count() == 2
使用remove()
方法将删除所有与提供的参数相同的值。这意味着也会删除任何相同实例的重复值或对象的重复值。要删除特定值,请使用removeAt()
方法并传递值的数值索引。
$collection = CollectionFactory::newCollection(['foo', 'bar', 'baz']); $collection->removeAt(1); //Collection is now [0 => 'foo', 1 => 'baz');
remove()
和removeAt()
方法都会导致集合的数值索引更新,关闭索引序列中的任何间隙。
要清空集合,只需调用clear()
方法。
$collection = CollectionFactory::newCollection(['foo', 'bar', 'baz']); $collection->clear(); var_dump($collection->count()); //int (0)
迭代和直接访问
Collection
实例可以使用ArrayAccess和Iterator。这意味着您可以使用集合作为for
或foreach
的主体。
$collection = CollectionFactory::newCollection(['foo', 'bar', 'baz']); for ($i = 0; $i < count($collection); $i++) { //... do something with $collection[$i]; } // ... or ... foreach ($collection as $key => $value) { //... do something with $key and/or $value }
如果您可以直接通过它们的索引访问和替换项目,那么您也可以这样做。
$collection = CollectionFactory::newCollection(['foo', 'bar', 'baz']); var_dump($collection[2]); //string 'baz' $collection[2] = 'qux'; //same as calling $collection->replace(2, 'qux');
您可以随时通过带有值索引的unset()
调用以这种方式删除项目。
unset($collection[3]); //same as calling $collection->removeAt(3);
字典类
Dictionary
与Collection
非常相似,主要区别在于Dictionary
只接受字符串索引(以下简称键)。Dictionary
将保留PHP数组可以保留的任何值,除了null
值。
字典可以被实例化为空字典或包含起始元素的数组。在后一种情况下,数组中存在的键不会被忽略,但它们必须是字符串。
<?php namespace App; use Fusion\Collection\CollectionFactory; require '../vendor/autoload.php'; $dictionary = CollectionFactory::newDictionary(); //empty // ... or ... $items = ['foo' => 'bar', 'baz' => 'bam']; $dictionary = CollectionFactory::newDictionary($items); var_dump($dictionary->count()); //int (2)
如上所示,可以使用 count()
方法获取字典中的项目数量,并且,与 Collection
类一样,也可以使用 PHP 的 count()
方法来获取。
$size = count($dictionary); //same as $size = $dictionary->count();
可以使用 add()
方法将项目添加到字典中,指定存储它们的键。
$dictionary->add('foo', 'bar');
也可以在给定的键处替换项目。
$dictionary->replace('foo', 'bam');
Dictionary
类中的 find()
、remove()
、removeAt()
和 clear()
方法的工作方式与在 Collection
类中完全相同,其中 find()
和 removeAt()
方法需要它们的参数是字符串而不是整数。
迭代和直接访问
Dictionary
类还利用了 ArrayAccess 和 Iterator 接口,允许循环遍历。
$dictionary = CollectionFactory::newDictionary(['foo1' => 'bar', 'foo2' => 'bam']); for ($i = 1; $i <= count($dictionary); $i++) { // ... do something with $dictionary['foo' . $i]; } // ... or ... foreach ($dictionary as $key => $value) { // ... do something with $key and/or $value }
可以通过键偏移直接访问字典中的值。
$dictionary = CollectionFactory::newDictionary(['foo' => 'bar', 'baz' => 'bam']); var_dump($dictionary['baz']); //string 'bam'
可以直接使用 unset()
移除项目。
unset($dictionary['foo']); // same as calling $dictionary->removeAt('foo');
可以直接在它们的偏移处替换值,并且还可以直接在它们的偏移处添加新项目。
$dictionary['foo'] = 'bar'; // same as calling $dictionary->add('foo', 'bar'); or $dictionary->replace('foo', 'bar');
TypedCollection 和 TypedDictionary 类
在某些情况下,可能需要有一个只存储特定类型对象引用的集合或字典。在这些情况下,可以使用 TypedCollection
或 TypedDictionary
。
这两个类分别是 Collection
和 Dictionary
类的子类,并且可以使用可选的起始项目集构造。然而,在实例化过程中,唯一必需的参数是可接受的类或接口的 完全限定名称。
<?php namespace App; use Fusion\Collection\CollectionFactory; require '../vendor/autoload.php'; class Apple { /* ... */ } $apples = CollectionFactory::newTypedCollection(Apple::class); //Only instances of Apple are allowed $apples->add(new Apple()) ->add(new Apple()) ->add(new Apple()); var_dump(count($apples)); //int (3) // ... or ... $setOfApples = [new Apple(), new Apple(), new Apple()]; $apples = CollectionFactory::newTypedCollection(Apple::class, $setOfApples); var_dump(count($apples)); //int (3)
TypedDictionary
变体类似,但是需要字符串键。
<?php namespace App; use Fusion\Collection\CollectionFactory; require '../vendor/autoload.php'; interface AppleInterface { /* ... */ } class RedDelicious implements AppleInterface { /* ... */ } class GrannySmith implements AppleInterface { /* ... */ } class Gala implements AppleInterface { /* ... */ } $appleBasket = CollectionFactory::newTypedDictionary(AppleInterface::class); $appleBasket->add('redDelicious', new RedDelicious()) ->add('grannySmith', new GrannySmith()) ->add('gala', new Gala());
与标准 Collection
和 Dictionary
类一样,不允许使用 null
值。
异常情况
库定义了 CollectionException
异常,在以下情况下会抛出此异常
集合
- 添加
null
值。 - 用
null
替换现有值。 - 使用不在集合中的索引调用
find()
。 - 直接访问不存在的索引。
- 访问非整数的索引。
TypedCollection
- 与
Collection
相同的条件适用。 - 向集合中添加(或替换)不符合接受类型的实例。
字典
- 添加
null
值。 - 用
null
替换现有值。 - 使用不在集合中的键调用
find()
。 - 直接访问不存在的键。
- 访问非字符串的键。
TypedDictionary
- 与
Dictionary
相同的条件适用。 - 向字典中添加(或替换)不符合接受类型的实例。
手动实例化
此库中的每个集合对象都可以使用它们的构造函数手动实例化,而不是使用 CollectionFactory
类。构造函数签名与工厂版本中的签名相似,但增加了一个参数,即 CollectionValidationInterface
的实例,它负责对集合操作进行完整性检查。
每个构造函数签名如下
Collection::__construct(CollectionValidationInterface $validator, array $items = []);
Dictionary::__construct(CollectionValidationInterface $validator, array $items = []);
TypedCollection::__construct(CollectionValidationInterface $validator, string $acceptedType, array $items = []);
TypedDictionary::__construct(CollectionValidationInterface $validator, string $acceptedType, array $items = []);
该库提供了CollectionValidationInterface
的实现,形式为CollectionValidator
类。以下是创建集合对象的替代方法
<?php namespace App; use Fusion\Collection\Collection; use Fusion\Collection\CollectionValidator; require '../vendor/autoload.php'; $validator = new CollectionValidator(); $collection = new Collection($validator, ['foo', 'bar', 'baz']); var_dump(count($collection)); //int (3)
上述模式对剩余的集合对象同样适用。只需创建一个CollectionValidationInterface
的实例,并将其作为构造函数的第一个参数传递。