inmanturbo/pipes

基于函数组合的简单API的php管道

v1.1.5 2024-08-14 00:09 UTC

This package is auto-updated.

Last update: 2024-09-14 00:17:06 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

简单来说,它将上一个输出的结果传递给下一个。有点像bash的cat ./file | grep -e 'waldo'

安装

您可以通过composer安装此包

composer require inmanturbo/pipes

或者直接从该存储库复制或下载functions.php文件:functions.php

使用方法

pipe()

require __DIR__.'/../vendor/autoload.php';

use function Inmanturbo\Pipes\pipe;

$addOne = fn ($number = 0) => $number + 1;

$five = pipe($addOne) // 1
    ->pipe(fn ($number) => $number + 1) // 2
    ->pipe($addOne) // 3
    ->pipe($addOne) // 4
    ->thenReturn(); // 4

它不会延迟执行

$fifty = pipe(1);

    while ($fifty->result() < 50) {
        $fifty->pipe(fn ($number) => ++$number);
    }

echo $fifty->result();
// 50
     

您也可以传递一个类或类字符串

use function Inmanturbo\Pipes\pipe;

class Subtract
{
    public function __invoke($number)
    {
        return $number - 1;
    }
}

$addOne = fn ($number = 0) => $number + 1;

$six = pipe($addOne, 1)
    ->pipe($addOne)
    ->pipe($addOne)
    ->pipe($addOne)
    ->then(fn ($number) => ++$number);

$five = pipe($six)
    ->pipe(Subtract::class)
    ->thenReturn();

$three = pipe(new Subtract, $five)
    ->pipe(new Subtract)
    ->thenReturn();

返回结果

结果可以通过三种方式返回

then()thenReturn() 都接受最终回调并返回结果,或者 result(),它简单地返回结果。

$addOne = fn ($number = 0) => $number + 1;

$six = pipe($addOne, 1)
    ->pipe($addOne)
    ->pipe($addOne)
    ->pipe($addOne)
    ->then(fn ($number) => ++$number);

$sixAgain = pipe($addOne, 1)
    ->pipe($addOne)
    ->pipe($addOne)
    ->pipe($addOne)
    ->thenReturn(fn ($number) => ++$number);

$five = pipe($addOne, 1)
    ->pipe($addOne)
    ->pipe($addOne)
    ->pipe($addOne)
    ->result();

停止管道

halt()

您可以从回调中返回 halt() 来停止链。 halt 可以接受一个可选的结果作为参数,您可以将它作为链的最终 result()。随后的 ->pipe() 调用将不会影响最终结果。

    use function Inmanturbo\Pipes\{pipe, halt};

    $fortyFive = pipe(1);

    $count = 1;
    while ($count < 50) {
        $fortyFive->pipe(fn ($number) => $number < 45 ? ++$number : halt($number));

        $count ++;
    }

    echo $fortyFive->result();

    // 45

    echo $fortyFive->pipe(fn ($number) => ++$number)->result();

    // 45

您也可以在管道本身上调用halt

    use function Inmanturbo\Pipes\{pipe, halt};

    $fortyFive = pipe(1);

    $count = 1;
    while ($count < 50) {
        
        if (($number = $fortyFive->result()) >= 45) {
            $fortyFive->halt($number);
        }

        $fortyFive->pipe(fn ($number) => ++$number);

        $count ++;
    }

    echo $fortyFive->result();

    // 45

    echo $fortyFive->pipe(fn ($number) => ++$number)->result();

    // 45

resume()

您可以使用resume来继续管道。 pipe()->resume() 接受一个可选的回调,如果传递了回调,则与 pipe()->pipe() 的行为相同

use function Inmanturbo\Pipes\{pipe, halt};

$fortySix = pipe(1);

$count = 1;
while ($count < 50) {
    
    if (($number = $fortySix->result()) >= 45) {
        $fortySix->halt($number);
    }

    $fortySix->pipe(fn ($number) => ++$number);

    $count ++;
}

echo $fortySix->result();

// 45

echo $fortySix->resume(fn ($number) => ++$number)->result();

// 46

hop() 和 Laravel

此包不需要Laravel即可使用pipe或 hop(),但 hop()(高阶管道)是一个高阶函数,旨在与Laravel的Pipeline辅助函数一起使用。此高阶函数接受一个接受单个参数的回调,并为您包装 $callback 在一个实现 function($next, $passable) 的闭包中。

use Illuminate\Pipeline\Pipeline;

use function Inmanturbo\Pipes\hop;

class Add {
    public function add($number)
    {
        return $number +1;
    }
}
class InvokeAdd {
    public function __invoke($number)
    {
        return $number +1;
    }
}

$five = (new Pipeline)->send(1)
    ->pipe(hop(fn($number) => $number +1))
    ->pipe(hop(new InvokeAdd))
    ->pipe(hop(InvokeAdd::class))
    ->pipe(hop(fn($number) => (new Add)->add($number)))
->thenReturn();

// 5

您可以选择将单个 middleware 作为第二个参数传递给 hop(),它将在第一个参数之前被调用,这使得您可以在 $callback 执行之前确定是否应该停止管道。

$limitThreeMiddleware = function ($number, $next) {
    if($number >= 3) {
        Log::info('Limit hit');
        return $number;
    }

    return $next($number);
};

$five = (new Pipeline)->send(1)
    ->pipe(hop(fn($number) => $number +1, $limitThreeMiddleware))
    ->pipe(hop(new InvokeAdd, $limitThreeMiddleware))
    // Limit hit
    ->pipe(hop(InvokeAdd::class, $limitThreeMiddleware))
    ->pipe(hop(fn($number) => (new Add)->add($number), $limitThreeMiddleware))
->thenReturn();

// 3