appertly / ducts
适用于 Hack/HHVM 的 PSR-7 兼容中间件分发器
0.1.0
2016-05-26 20:16 UTC
Requires
- hhvm: >=3.12.0
- psr/http-message: ^1.0
Requires (Dev)
This package is not auto-updated.
Last update: 2024-09-14 18:53:10 UTC
README
适用于 Hack/HHVM 的 PSR-7 兼容中间件分发器。
这与 Connect、Relay、Stratigility、Middleman 等类似,但严格遵循 Hack。
安装
您可以使用 Composer 安装此库
$ composer require appertly/ducts
- 此项目的 master 分支(版本 0.x)需要 HHVM 3.12,没有依赖项。
兼容性
此库的版本将遵循 语义版本控制。
我们的代码旨在遵循 PSR-1、PSR-2 和 PSR-4。如果您发现任何与标准兼容性相关的问题,请发送 pull request!
层和分发
这里的想法是您提供一系列函数,这些函数
- 接受一个请求、一个响应和一个下一个函数
- 可能修改请求和响应
- 可能调用下一个函数,该函数返回一个响应
- 可能修改返回的响应
- 返回响应
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; function foobar(Request $req, Response $res, (function (Request,Response): Response) $next): Response { // 2. possibly modify the request and response // 3. invoke next $res = $next($req, $res); // 4. possibly modify response // 5. return $res; }
层最终会这样交互
- → 第一层
- → 第二层
- → 第三层
- ← 第三层
- ← 第二层
- → 第二层
- ← 第一层
分发请求
use Ducts\Runner; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; /** * @var \Psr\Http\Message\ServerRequestInterface $request The PSR-7 HTTP request * @var \Psr\Http\Message\ResponseInterface $response The PSR-7 HTTP response */ // any Traversable will do. Use an array, Vector, etc. $runner = new Runner([ // you can use closures function(Request $req, Response $res, (function (Request,Response): Response) $next): Response { $req = $req->withAttribute('foo', 'bar'); return $next($req, $res); }, // or lambdas ($req, $res, $next) ==> $next($req, $res)->withHeader('X-Ducts', 'Yes') // or objects with an __invoke method new MyInvokableThing(), // or Hack-style callables fun('myLayer'), class_meth('MyLayer', 'staticMethod'), inst_meth($myObject, 'layer') ]); $response = $runner->run($request, $response); // Runner::run can be called multiple times if needed $anotherResponse = $runner->run($request, $response);
如果您想查找层可调用函数,也可以使用 ResolvingRunner
。
// a function to look up names $resolver = function(mixed $name): (function (Request,Response,(function(Request,Response): Response)): Response) { // look up your callable thing in a dependency injection container $container = MyClass::getSomeContainer(); return $container->get($name); }; // Items in this traversable can be a combination of functions or items to resolve $runner = new ResolvingRunner([ ($req, $res, $next) ==> $next($req, $res)->withHeader('X-Ducts', 'Yes'), 'MyClassName', 'AnotherClass' ], $resolver);
将 Runner 作为层使用
您可以通过调用 $runner->layer()
将 Runner
用作层!例如,您将 Runner
的 $bar
声明为 Runner
的第二层,其中 $foo
有三个层。如果 $bar
有三个层,它将像这样参与 $foo
:
- →
$foo
层 1- →
$bar
层 1- →
$bar
层 2- →
$bar
层 3- →
$foo
层 3 - ←
$foo
层 3
- →
- ←
$bar
层 3
- →
- ←
$bar
层 2
- →
- ←
$bar
层 1
- →
- ←
$foo
层 1