arete/collection-pipeline

PHP (部分) 实现管道集合。无需创建大量可调用对象、循环和条件语句即可与对象集合一起工作。

dev-master / 0.2.5.x-dev 2015-10-27 02:44 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:35:50 UTC


README

Build Status HHVM Status Author Latest Unstable Version License Codacy Badge

无需创建大量可调用对象、循环和条件语句即可与对象集合一起工作。

阅读了 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]]

规范

arete/specification

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()实现