inmanturbo / pipes
基于函数组合的简单API的php管道
v1.1.5
2024-08-14 00:09 UTC
Requires
- php: ^8.2
Requires (Dev)
- illuminate/contracts: ^11.20
- laravel/pint: dev-main
- pestphp/pest: 3.x-dev
- pestphp/pest-plugin-laravel: 3.x-dev
- phpstan/extension-installer: 1.4.x-dev
- phpstan/phpstan-deprecation-rules: 1.2.x-dev
- phpstan/phpstan-phpunit: 1.4.x-dev
README
简单来说,它将上一个输出的结果传递给下一个。有点像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