111
This commit is contained in:
@@ -19,7 +19,7 @@ class HandlerProviders extends BaseObject
|
|||||||
* @param $method
|
* @param $method
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function get($path, $method): mixed
|
public static function get($path, $method): ?Pipeline
|
||||||
{
|
{
|
||||||
return static::$handlers[$method][$path] ?? null;
|
return static::$handlers[$method][$path] ?? null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,23 @@ class MiddlewareManager extends BaseObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $handler
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
public static function get($handler)
|
||||||
|
{
|
||||||
|
if ($handler instanceof Closure) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
[$class, $method] = [$handler[0]::class, $handler[1]];
|
||||||
|
if (!static::hasMiddleware($class, $method)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return static::$_middlewares[$class . '::' . $method];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $class
|
* @param $class
|
||||||
* @param $method
|
* @param $method
|
||||||
@@ -78,7 +95,7 @@ class MiddlewareManager extends BaseObject
|
|||||||
return array_reduce(array_reverse($middlewares), function ($stack, $pipe) {
|
return array_reduce(array_reverse($middlewares), function ($stack, $pipe) {
|
||||||
return function ($passable) use ($stack, $pipe) {
|
return function ($passable) use ($stack, $pipe) {
|
||||||
if ($pipe instanceof MiddlewareInterface) {
|
if ($pipe instanceof MiddlewareInterface) {
|
||||||
return $pipe->onHandler($passable, $stack);
|
$pipe = [$pipe, 'onHandler'];
|
||||||
}
|
}
|
||||||
return call_user_func($pipe, $passable, $stack);
|
return call_user_func($pipe, $passable, $stack);
|
||||||
};
|
};
|
||||||
@@ -93,14 +110,18 @@ class MiddlewareManager extends BaseObject
|
|||||||
*/
|
*/
|
||||||
public static function closureMiddlewares($middlewares, Closure $caller): Closure
|
public static function closureMiddlewares($middlewares, Closure $caller): Closure
|
||||||
{
|
{
|
||||||
|
if (empty($middlewares)) {
|
||||||
|
return $caller;
|
||||||
|
}
|
||||||
return array_reduce(array_reverse($middlewares), function ($stack, $pipe) {
|
return array_reduce(array_reverse($middlewares), function ($stack, $pipe) {
|
||||||
return function ($passable) use ($stack, $pipe) {
|
return function ($passable) use ($stack, $pipe) {
|
||||||
if ($pipe instanceof MiddlewareInterface) {
|
if ($pipe instanceof MiddlewareInterface) {
|
||||||
return $pipe->onHandler($passable, $stack);
|
$pipe = [$pipe, 'onHandler'];
|
||||||
}
|
}
|
||||||
return call_user_func($pipe, $passable, $stack);
|
return call_user_func($pipe, $passable, $stack);
|
||||||
};
|
};
|
||||||
}, $caller);
|
}, $caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-105
@@ -161,64 +161,16 @@ class Node
|
|||||||
*/
|
*/
|
||||||
private function injectMiddleware(string $method, $handler, $_injectParameters): void
|
private function injectMiddleware(string $method, $handler, $_injectParameters): void
|
||||||
{
|
{
|
||||||
if (!($handler instanceof Closure)) {
|
$callback = (new Pipeline())->overall($this->router->getMiddleware())
|
||||||
$callback = $this->injectControllerMiddleware($method, $handler, $_injectParameters);
|
->through($this->middleware[$method] ?? [])
|
||||||
} else {
|
->through(MiddlewareManager::get($handler))
|
||||||
$callback = $this->injectClosureMiddleware($method, $handler, $_injectParameters);
|
->send($_injectParameters)
|
||||||
}
|
->then($handler);
|
||||||
|
|
||||||
HandlerProviders::add($method, $this->sourcePath, $callback);
|
HandlerProviders::add($method, $this->sourcePath, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $method
|
|
||||||
* @param $handler
|
|
||||||
* @param $_injectParameters
|
|
||||||
* @return mixed
|
|
||||||
* @throws NotFindClassException
|
|
||||||
* @throws ReflectionException
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
private function injectControllerMiddleware($method, $handler, $_injectParameters): mixed
|
|
||||||
{
|
|
||||||
$middleware = $this->middleware[$method] ?? [];
|
|
||||||
|
|
||||||
$allowMiddleware = $this->router->getMiddleware();
|
|
||||||
if (!empty($allowMiddleware)) {
|
|
||||||
array_unshift($middleware, $allowMiddleware);
|
|
||||||
}
|
|
||||||
MiddlewareManager::addMiddlewares($handler[0], $handler[1], $middleware);
|
|
||||||
return MiddlewareManager::callerMiddlewares(
|
|
||||||
$handler[0], $handler[1], $this->aopHandler($this->getAop($handler), $handler, $_injectParameters)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $method
|
|
||||||
* @param $handler
|
|
||||||
* @param $_injectParameters
|
|
||||||
* @return Closure
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
private function injectClosureMiddleware($method, $handler, $_injectParameters): Closure
|
|
||||||
{
|
|
||||||
$middleware = $this->middleware[$method] ?? [];
|
|
||||||
|
|
||||||
$allowMiddleware = $this->router->getMiddleware();
|
|
||||||
if (!empty($allowMiddleware)) {
|
|
||||||
array_unshift($middleware, $allowMiddleware);
|
|
||||||
}
|
|
||||||
if (!empty($middleware)) {
|
|
||||||
return MiddlewareManager::closureMiddlewares($middleware,
|
|
||||||
$this->normalHandler($handler, $_injectParameters)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return $this->normalHandler($handler, $_injectParameters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ReflectionException
|
* @throws ReflectionException
|
||||||
* @throws NotFindClassException
|
* @throws NotFindClassException
|
||||||
@@ -236,56 +188,6 @@ class Node
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param IAspect|null $reflect
|
|
||||||
* @param $handler
|
|
||||||
* @param $_injectParameters
|
|
||||||
* @return Closure
|
|
||||||
*/
|
|
||||||
#[Pure] private function aopHandler(?IAspect $reflect, $handler, $_injectParameters): Closure
|
|
||||||
{
|
|
||||||
if (is_null($reflect)) {
|
|
||||||
return $this->normalHandler($handler, $_injectParameters);
|
|
||||||
}
|
|
||||||
return static function () use ($reflect, $handler, $_injectParameters) {
|
|
||||||
return $reflect->invoke($handler, $_injectParameters);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws ReflectionException|NotFindClassException
|
|
||||||
*/
|
|
||||||
private function getAop($handler): ?IAspect
|
|
||||||
{
|
|
||||||
[$controller, $action] = $handler;
|
|
||||||
|
|
||||||
if (is_object($controller)) {
|
|
||||||
$controller = get_class($controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var Aspect $aspect */
|
|
||||||
$aspect = NoteManager::getSpecify_annotation(Aspect::class, $controller, $action);
|
|
||||||
if (empty($aspect)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return di($aspect->aspect);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $handler
|
|
||||||
* @param $_injectParameters
|
|
||||||
* @return Closure
|
|
||||||
*/
|
|
||||||
private function normalHandler($handler, $_injectParameters): Closure
|
|
||||||
{
|
|
||||||
return static function () use ($handler, $_injectParameters) {
|
|
||||||
return call_user_func($handler, ...$_injectParameters);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@@ -427,7 +329,7 @@ class Node
|
|||||||
if (empty($handlerProviders)) {
|
if (empty($handlerProviders)) {
|
||||||
throw new RequestException('<h2>HTTP 404 Not Found</h2><hr><i>Powered by Swoole</i>', 404);
|
throw new RequestException('<h2>HTTP 404 Not Found</h2><hr><i>Powered by Swoole</i>', 404);
|
||||||
}
|
}
|
||||||
return call_user_func($handlerProviders, request());
|
return $handlerProviders->interpreter();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Http\Route;
|
||||||
|
|
||||||
|
use Annotation\Aspect;
|
||||||
|
use Closure;
|
||||||
|
use Http\IInterface\MiddlewareInterface;
|
||||||
|
use Kiri\Di\NoteManager;
|
||||||
|
use Kiri\Kiri;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class Pipeline
|
||||||
|
{
|
||||||
|
protected $passable;
|
||||||
|
|
||||||
|
protected $overall;
|
||||||
|
|
||||||
|
protected $pipes = [];
|
||||||
|
|
||||||
|
|
||||||
|
protected $pipeline;
|
||||||
|
|
||||||
|
protected $exceptionHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始数据
|
||||||
|
* @param $passable
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function send($passable)
|
||||||
|
{
|
||||||
|
$this->passable = $passable;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $middle
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function overall($middle): static
|
||||||
|
{
|
||||||
|
$this->overall = $middle;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用栈
|
||||||
|
* @param $pipes
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function through($pipes)
|
||||||
|
{
|
||||||
|
if (empty($this->pipes)) {
|
||||||
|
$this->pipes = is_array($pipes) ? $pipes : func_get_args();
|
||||||
|
} else {
|
||||||
|
foreach ($pipes as $pipe) {
|
||||||
|
$this->pipes[] = $pipe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行
|
||||||
|
* @param Closure $destination
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function then(callable $destination)
|
||||||
|
{
|
||||||
|
$parameters = $this->passable;
|
||||||
|
if (!empty($this->overall)) {
|
||||||
|
array_unshift($this->pipes, $this->overall);
|
||||||
|
}
|
||||||
|
if (is_array($destination)) {
|
||||||
|
$destination = $this->aspect_caller($destination, $parameters);
|
||||||
|
}
|
||||||
|
$this->pipeline = array_reduce(array_reverse($this->pipes), $this->carry(),
|
||||||
|
static function () use ($destination, $parameters) {
|
||||||
|
return call_user_func($destination, ...$parameters);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return $this->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
private function clear()
|
||||||
|
{
|
||||||
|
$this->pipes = [];
|
||||||
|
$this->passable = null;
|
||||||
|
$this->overall = null;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $destination
|
||||||
|
* @param $parameters
|
||||||
|
* @return \Closure
|
||||||
|
*/
|
||||||
|
private function aspect_caller($destination, $parameters)
|
||||||
|
{
|
||||||
|
[$controller, $action] = $destination;
|
||||||
|
/** @var \Annotation\Aspect $aop */
|
||||||
|
$aop = NoteManager::getSpecify_annotation(Aspect::class, $controller::class, $action);
|
||||||
|
if (!empty($aop)) {
|
||||||
|
$aop = Kiri::getDi()->get($aop->aspect);
|
||||||
|
$destination = static function () use ($aop, $destination, $parameters) {
|
||||||
|
/** @var \Kiri\IAspect $aop */
|
||||||
|
$aop->invoke($destination, $parameters);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return $destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function interpreter(): mixed
|
||||||
|
{
|
||||||
|
return call_user_func($this->pipeline, request());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置异常处理器
|
||||||
|
* @param callable $handler
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function whenException($handler)
|
||||||
|
{
|
||||||
|
$this->exceptionHandler = $handler;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Closure
|
||||||
|
*/
|
||||||
|
protected function carry(): Closure
|
||||||
|
{
|
||||||
|
return static function ($stack, $pipe) {
|
||||||
|
return static function ($passable) use ($stack, $pipe) {
|
||||||
|
if ($pipe instanceof MiddlewareInterface) {
|
||||||
|
$pipe = [$pipe, 'OnHandler'];
|
||||||
|
}
|
||||||
|
return $pipe($passable, $stack);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常处理
|
||||||
|
* @param $passable
|
||||||
|
* @param $e
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
protected function handleException($passable, Throwable $e)
|
||||||
|
{
|
||||||
|
if ($this->exceptionHandler) {
|
||||||
|
return call_user_func($this->exceptionHandler, $passable, $e);
|
||||||
|
}
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user