webpt / aquaduck
Requires
- php: >=5.3.0
Requires (Dev)
- phpunit/phpunit: ^4.0
This package is not auto-updated.
Last update: 2024-09-14 17:16:21 UTC
README
此包深受zendframework/zend-strategility zendframework/zend-strategility的启发。
安装和需求
使用composer安装此库
$ composer require webpt/aquaduck
使用方法
创建处理流程非常简单
use Webpt\Aquaduck\Aquaduck; require __DIR__ . '/../vendor/autoload.php'; $pipeline = new Aquaduck(); $pipeline->bind(function($value, $next) { $next($value + 5); }); echo $pipeline(5); //10
中间件
什么是中间件?
中间件是存在的一种代码,它可以接收传入的值(或对象),根据它执行操作,并返回或传递委托给队列中的下一个中间件。
在Aquaduck中,中间件可以是以下类型:
- 任何接受至少一个参数的PHP可调用函数,可选地接受一个可调用函数(用于调用队列中的下一个中间件,如果有的话)。
- 实现
Webpt\Aquaduck\Middleware\MiddlewareInterface
的对象。Webpt\Aquaduck\Aquaduck
实现了此接口。
错误处理器
要处理错误,可以编写接受恰好3个参数的中间件
function ($error, $subject, $next) { }
或者,您可以实现Webpt\Aquaduck\ErrorHandler\ErrorHandlerInterface
。
当使用Aquaduck
时,在队列执行过程中,如果调用$next()
并传递参数,或者抛出异常,中间件将迭代队列,直到找到第一个此类错误处理器。该错误处理器可以完成请求,或者自己调用$next()
。 调用$next()
的错误处理器应该用自己接收到的错误,或者另一个错误调用它。
错误处理器通常在中间件的末尾附加,以防止尝试执行非错误处理中间件,并确保它们可以拦截来自任何其他处理器的错误。
创建中间件
要创建中间件,编写一个能够接收至少一个参数的可调用函数,并可选地调用链中的下一个回调。如果您的中间件接受第二个参数$next
,如果它无法完成请求或允许进一步处理,则可以调用它以将处理权返回给父中间件。
以这种方式编写的中间件可以是以下任何一种:
- 闭包(如上所示)
- 函数
- 静态类方法
- PHP数组回调(例如,
[ $class, 'run' ]
,其中$class
是一个类实例) - 可调用的PHP对象(即实现
__invoke()
的类的实例) - 实现
Aquaduck\Middleware\MiddlewareInterface
的对象(包括Webpt\Aquaduck\Aquaduck
)
执行和组合中间件
执行中间件最简单的方法是编写闭包并将它们附加到Webpt\Aquaduck\Aquaduck
实例。您可以嵌套Aquaduck
实例以创建相关中间件的组。
$pipe = new Aquaduck(); // Middleware collection $pipe->bind(/* ... */); // repeat as necessary $superPipe = new Aquaduck(); // New Middleware collection $superPipe->bind($pipe); // Middleware attached as a group
API
以下构成了Aquaduck的主要API。
中间件
Webpt\Aquaduck\Aquaduck
是主要的应用程序接口,前面已经讨论过。其API如下:
class Aquaduck implements MiddlewareInterface { public function bind($middleware, $priority = 1); public function __invoke( $subject, $out = null ); }
bind()
接受最多两个参数。如果只提供一个参数,则将$middleware
分配给该值,将$priority
分配给值1
。
中间件的执行顺序与$priority
确定的顺序相同。
__invoke()
本身是中间件。如果没有提供$out
,则创建一个Webpt\Aquaduck\FinalHandler
实例,并在管道堆栈耗尽时使用它。可调用函数应该使用与Next()
相同的签名。
function ( $subject, $err = null ) { }
内部,Aquaduck
创建一个Webpt\Aquaduck\Next
实例,将其队列馈送给它,执行它,并返回一个响应。
Next
Webpt\Aquaduck\Next
主要是一个中间件实现的细节,存在是为了允许将任务委托给在堆栈中稍后注册的中间件。
class Next { public function __invoke( $subject, $err = null ); }
例如
提供修改后的主题
function ($subject, $next) use ($helperClass) { $subject = $helperClass->help($subject); return $next($subject); }
引发错误条件
要引发错误条件,将非空值作为$next()
的第二个参数传递
function ($subject, $next) { try { // try some operation... } catch (Exception $e) { return $next($subject, $e); // Next registered error middleware will be invoked } }
FinalHandler
Webpt\Aquaduck\FinalHandler
是在堆栈耗尽时执行的中间件的一个默认实现。当被调用时,它期望两个参数:一个主题和一个错误条件(或null
表示没有错误)。