star / collection
集合工具库
Requires
- doctrine/collections: ~1.1
Requires (Dev)
- doctrine/orm: *
- phpunit/phpunit: ~4.0
This package is auto-updated.
Last update: 2024-09-12 03:51:12 UTC
README
提供多种集合实现的库。
安装
要使用 [composer] (https://getcomposer.org.cn/) 安装此包,您只需将以下行添加到您的 composer.json
文件中。
...
"require": {
"star/collection": "~1.2"
}
...
支持的集合
枚举
将不可变值数组包装在对象中。确保传递给枚举的任何值都由实例支持。
$enumeration = new Enumeration(array(1,2,3));
$enumeration->getSelected(); // returns null
$enumeration->select(2);
$enumeration->getSelected(); // returns 2
$enumeration->select('invalid'); // Throw Exception
类型化集合
包装特定类型的对象(类或接口)的集合。如果给定的值不支持集合,则集合将抛出异常。
基本用法
$collection = new TypedCollection('\stdClass');
$collection->add(2); // Throw exception
$collection->add(new \stdClass()); // works
$collection = new TypedCollection('\Countable');
$collection->add(2); // Throw exception
$collection->add(new ClassThatImplementsCountable()); // works
高级用法
使用组合
假设你想有一个 Car
集合,你可以使用基本用法来定义它,但这会导致代码重复。所以一个好的做法是定义一个新的名为 CarCollection
的类,并使用组合而不是继承,并声明如下
class CarCollection
{
private $collection;
public function __construct()
{
$this->collection = new TypedCollection('tests\Star\Component\Collection\Example\Car');
}
}
以这种方式声明您的集合将使您能够将相关的逻辑封装在一个地方,而不是冒着暴露内部实现给外部世界的风险。这样,您就可以控制哪些方法可用,并避免重复。
使用此示例,通过实现 addCar
方法,轻松向集合添加 Car
。
class CarCollection
{
...
public function addCar(Car $car)
{
$this->collection->add($car);
}
...
}
同样,如果您想根据颜色过滤所有汽车,您可以在内部使用它如下
class CarCollection
{
...
public function findAllCarWithColor(Color $color)
{
$closure = function(Car $car) use ($color) {
return $car->getColor() == $color;
};
return $this->collection->filter($closure)->toArray();
}
...
}
同样,也可以根据名称找到汽车
class CarCollection
{
...
public function findAllWithName($name)
{
$expression = Criteria::expr()->eq('name', $name);
$criteria = new Criteria($expression);
return $this->collection->matching($criteria)->toArray();
}
...
}
从现在起,您的集合可重用,可在同一位置测试,同时避免继承的陷阱。
使用继承
class PassengerCollection extends TypedCollection
{
...
public function findAllWithName($name)
{
$expression = Criteria::expr()->eq('name', $name);
$criteria = new Criteria($expression);
return $this->matching($criteria)->toArray();
}
...
}
使用 Doctrine
此类可以与 doctrine/dbal 一起使用作为附加功能,但您需要确保以下步骤得到遵守。
-
自定义集合应继承自实现
Doctrine\Common\Collections\Collection
的TypedCollection
。 -
在实体化时,集合属性将被
Doctrine\ORM\PersistentCollection
替换,而不是自定义集合,尽管集合是在构造函数中实例化的。为了绕过此功能,应像这样实现应返回自定义集合的任何方法class Entity { // 可由 Doctrine 使用 PersistentCollection 实体化的自定义集合 private $myElements;
public function __construct() { $this->myElements = new CustomCollection('stdClass'); } public function getElements() { // At this point $this->myElements could be a Persistent collection return new CustomCollection($this->myElements->toArray()); }
}