这是一个示例代码,我可以想象它可以工作。当然,还缺少很多东西,比如设置路由、解决依赖关系、PSR 接口和其他框架附带的东西。
此代码将中间件和操作添加到请求处理程序,请求处理程序可以在需要时执行两者。
<?php
interface RequestInterface {}
class Request implements RequestInterface {}
interface ResponseInterface {}
class Response implements ResponseInterface {}
class Response404 implements ResponseInterface {}
class FirstMiddleware {
public function process(RequestInterface $request, RequestHandler $handler): ResponseInterface {
echo ' First-Before ';
$response = $handler->handle($request);
echo ' First-After ';
return $response;
}
}
class SecondMiddleware {
public function process(Request $request, RequestHandler $handler): Response {
echo ' Second-Before ';
$response = $handler->handle($request);
echo ' Second-After ';
return $response;
}
}
class RequestHandler {
private $middleware;
private $callable;
private $params;
public function __construct(array $middleware = [], callable $callable, array $params = []) {
$this->middleware = $middleware;
$this->callable = $callable;
$this->params = $params;
}
public function handle(RequestInterface $request): ResponseInterface {
$middleware = current($this->middleware);
next($this->middleware);
if (!$middleware) {
$response = ($this->callable)(...$this->params);
return $response;
}
return $middleware->process($request, $this);
}
}
class App {
private $middleware = [];
private $callable;
public function setMiddleware(array $middleware) {
$this->middleware = $middleware;
}
public function setCallable(callable $callable) {
$this->callable = $callable;
}
public function run() {
$handler = new RequestHandler($this->middleware, $this->callable, ['one', 'two']);
$handler->handle(new Request());
}
}
class Controller {
public function action($a, $b) {
echo ' Controller Action ';
echo $a;
echo $b;
return new Response();
}
}
$middleware = [
new FirstMiddleware(),
new SecondMiddleware(),
];
// Using closure ...
$callable = function ($a, $b) {
echo ' Closure Action ';
echo $a;
echo $b;
return new Response();
};
// Or an object method
$controller = new Controller();
$callable = array($controller, 'action');
/** Run */
$app = new App();
$app->setMiddleware($middleware);
$app->setCallable($callable);
$app->run();