arete / collection-pipeline
PHP (部分) 实现管道集合。无需创建大量可调用对象、循环和条件语句即可与对象集合一起工作。
dev-master / 0.2.5.x-dev
2015-10-27 02:44 UTC
Requires
- arete/support: dev-master
- league/pipeline: dev-master
Requires (Dev)
- phpunit/phpunit: 5.1.*
This package is not auto-updated.
Last update: 2024-09-14 18:35:50 UTC
README
无需创建大量可调用对象、循环和条件语句即可与对象集合一起工作。
阅读了 Martin Fowler 的集合管道 之后,我想要在 PHP 中使用类似的东西,因此,这就诞生了。使用了 League\Pipeline 以及 Illuminate\Support\Collection(此集合的所有功能都在链中可用)。
示例
这是我们将要使用的示例组
use Arete\CollectionPipeline\CollectionPipeline as CP; class MockEntity { public $id; public $name; public function __construct($id, $name) { $this->id = $id; $this->name = $name; } public function getId() { return $this->id; } public function getName() { return $this->name; } } // ids are just random for testing $array = array( new MockEntity(null, "eric"), #0 new MockEntity(10, "tim"), #1 new MockEntity(111, "beau"), #2 new MockEntity(11, "ross"), #3 new MockEntity(12, "sarah"), #4 new MockEntity(13, "taylor"), #5 new MockEntity(-42, "lea"), #6 new MockEntity("eh", "phil"), #7 new MockEntity(6, "larry"), #8 new MockEntity(10, "frank"), #9 new MockEntity(["eh"], "joe"),#10 new MockEntity(99, "kayla"), #12 new MockEntity(0, "martin"), #11 new MockEntity(1, "brad"), #13 new MockEntity(2, "luke"), #14 new MockEntity(3, "paul"), #15 new MockEntity(4, "ash"), #16 new MockEntity(5, "davey"), #17 new MockEntity(18,"anthony"), #18 new MockEntity(19,"tim"), #19 );
字符串函数
$result = CP::from($array)->wheres('getId', 'is_string')->all(); # gives: [7 => $array[7]]
!
字符串函数
$result = CP::from($array)->wheres('getId', '!is_string')->all(); # gives: everything in $array except #7
每个
使用 ::wheresEach
来比较整个值,而不使用任何访问器。
instanceof
$result = CP::from($array)->wheres('instanceof', MockEntity::CLASS)->all(); # gives: everything in $array
!
instanceof
$result = CP::from($array)->wheres('!instanceof', MockEntity::CLASS)->all(); # gives: empty array, they all are instances of MockEntity
比较运算符
$result = CP::from($array)->wheres('getId', '>', 110)->all(); # gives: [9 => $array[9]]
链式调用
$result = CP::from($array)->wheres('getId', '!is_string')->wheres('getId', '>', 10)->wheres('getName', '===', 'tim')->all(); # gives: [19 => $array[19]]
参数顺序
访问器返回值(X)作为第一个参数,您正在使用的比较值(Y)。
// one does contain joe, but none contain derek $stringItWouldBeIn = 'joe,derek'; $x = 'getName'; $y = $stringItWouldBeIn; // containsSubString is from arete\support $result = CP::from($array)->wheresYX($x, 'containsSubString', $y)->all(); # gives: [10 => $array[10]]
Laravel Illuminate
由于它扩展了 Illuminate\Support\Collection,您可以使用它们的函数,例如
$result = CP::from($array)->wheres('id', 'is_string', null, 'property')->keys(); # gives: [7]
类型
// will only check for the method `getId` $result = CP::from($array)->wheres('getId', '>', 110, 'method')->all(); # gives: [9 => $array[9]]
倒序
// compares 110 < $payload->getId() $result = CP::from($array)->wheres('getId', '<', 110, 'method', 'yx')->all(); # gives: [9 => $array[9]]
可调用
$stringItWouldBeIn = 'joe,jonathon'; $result = CP::from($array)->wheresYX('getName', 'containsSubString', $stringItWouldBeIn, 'callable')->all(); $result = CP::from($array)->wheres('getId', function($value) { if ($value == 'tim') return true return false; })->all(); # gives: [10 => $array[10]]
值
值是可选参数,因此如果您想检查例如 属性
,但没有值来比较
// will only check for the property `id`, // it could be ['property', 'method'] if you wanted to use a method if the property was not there // or it could be ['property', 'method', 'callable'] (which is default) $result = CP::from($array)->wheres('id', 'is_string', null, 'property')->all(); # gives: [9 => $array[9]]
规范
use Arete\Specification\Specification; use Arete\Specification\SpecificationTrait; class NameEquals implements Specification { use ParameterizedSpecification; use SpecificationTrait; public function isSatisfiedBy($entity) { if ($entity->getName() == $this->value) return true; return false; } } $result = CP::from($array)->satisfying(new NameEquals('tim')); # gives: [10 => $array[10]]
安装
可以通过 Packagist 使用 Composer 安装。
在您的项目根目录下运行
$ composer require arete/collection-pipeline
请确保您已将项目设置为 自动加载 Composer 安装的包。
运行测试
通过命令行运行,进入 arete/collection-pipeline
目录并运行 phpunit
@TODO
- 添加获取包含对象方法值的数组的功能。这意味着,如果我想只获取 $objects->getName(); 作为 $objectNames 的数组,也许还可以设置键是什么?
- 传递包含 '!' 的数组,如果您希望它不是?
- 将 ExpressionBuilder 移动到 Constructor()
- 优化过滤器,以便它们可以在请求数组 / all() 时组合并在一个循环中完成?
- 传递多个字符串函数和比较运算符,例如
'is_string | is_int & >'
,能够做到('methodName', 'strlen >', 5)
(如果需要,可以使用一些 Symfony\ExpressionLanguage)(当这样做时,它将真正使用管道如何应该使用) - 类似于上一个待办事项,但是使用链式方法调用
- 将示例从readme中移除(除了1个),并放入[examples/]目录下
- 根据版本添加飞船比较运算符(感谢 @seldaek)
- 使用最后一种方法来使用
ands
? - 重构
ExendedPipeline
,使其不再是上帝对象。 Specification
中的数组键- 匹配方法、属性和可调用函数时使用的数组键
- 抽象出argsOrderYX & XY
- 从
::wheresComparison
中移除null检查 - 添加在表达式中反转参数的能力
- 添加访问器的类型转换
- 添加与::map()类似的::reduce()实现