psg/psr-101

将 PSR 15 重构为 AppInterface

0.4 2021-07-11 23:11 UTC

This package is auto-updated.

Last update: 2024-09-12 06:12:31 UTC


README

==== 这不是一个 FIG PSR,也没有经过成为 PSR 的严格流程 ====

PSR 101

这是 PSR 15 的重写,并将 PSR 17 包含到 MiddlewareAppInterface 中。这个过程中融入了各种想法

  • 由于接口方法参数必须匹配(见 PSR 100 README),并且由于 PSR 101 中间件要求处理程序是 RequestionHandlerInterface 的扩展版本,因此 PSR 15 无法扩展中间件接口
  • 为了编写标准化的中间件,应该标准化使用 PSR 17 工厂的方法
    • 为此,MiddlewareAppInterface 提供了对这些工厂的访问
  • 某些中间件并不关心 App,它们只想获得一个用于 next 调用的闭包。这种类型的中间件作为 MiddlewareNextInterface 单独提供
    • 应用应该通过检测中间件类型并正确应用来处理这类中间件
  • 中间件是通过 MiddlewareAppInterface 期望的。因此,有添加、移除和检查中间件的方法。
    • 这些方法是未上下文相关的 hasaddremove。这里的预期是,框架通常不会在它们的 $app 对象上实现这些方法(因为它们太通用),但这些方法引用中间件是有意义的。此外,将类似 addMiddleware 的方法添加到接口可能会与框架的 $app 对象上的现有方法冲突。

用法

让我们看看基于这个 PSR 101 的中间件示例

use Psg\Psr100\Factory\Psr100Factory;
use Psg\Http\Message\{ResponseInterface, ServerRequestInterface};
use Psg\Http\Server\{MiddlewareAppInterface, MiddlewareInterface, MiddlewareNextInterface};


class App extends Psr100Factory implements MiddlewareAppInterface{
	public $middleware;
	public function __construct(){
		$this->middleware = new \SplObjectStorage();
	}
	public function handle(\Psr\Http\Message\ServerRequestInterface $request): ResponseInterface {
		$middleware = $this->middleware->current();
		$this->middleware->next();
		return $middleware->process($request, $this);
	}
	public function add($middleware){
		$this->middleware->attach($middleware);
	}
	public function remove($middleware){
		$this->middleware->detach($middleware);
	}
	public function has($middleware){
		return $this->middleware->contains($middleware);
	}
}

class Control implements MiddlewareInterface {
	public function process(ServerRequestInterface $request, MiddlewareAppInterface $app): ResponseInterface {
		return $app->createResponse(200)->withBody($app->createStream('there is one name in programming, and that name is bill'));
	}
}
class MiddleOut implements MiddlewareInterface {
	public function process(ServerRequestInterface $request, MiddlewareAppInterface $app): ResponseInterface {
		$response = $app->handle($request);
		$only_bob = preg_replace('/bill/i', 'bob', (string)$response->getbody());
		$new_stream = $response->getBody()->create($only_bob);
		return $response->withBody($new_stream);
	}
}

$App = new App;
$App->add(new MiddleOut);
$App->add(new Control);
$App->middleware->rewind();
$response = $App->handle($App->createServerRequest('get', 'http://bobery.com/'));
echo (string)$response->getBody();

#> there is one name in programming, and that name is bob