Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 28973df8b6 |
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.4",
|
"php": ">=8.5",
|
||||||
"composer-runtime-api": "^2.0",
|
"composer-runtime-api": "^2.0",
|
||||||
"psr/http-server-middleware": "^1.0",
|
"psr/http-server-middleware": "^1.0",
|
||||||
"psr/http-message": "^1.0"
|
"psr/http-message": "^1.0"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace Kiri\Router;
|
|||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Kiri;
|
use Kiri;
|
||||||
|
use Kiri\Router\Annotate\Defer;
|
||||||
use Kiri\Router\Format\IFormat;
|
use Kiri\Router\Format\IFormat;
|
||||||
use Kiri\Router\Format\MixedFormat;
|
use Kiri\Router\Format\MixedFormat;
|
||||||
use Kiri\Router\Format\NoBody;
|
use Kiri\Router\Format\NoBody;
|
||||||
@@ -32,6 +33,11 @@ class Handler implements RequestHandlerInterface
|
|||||||
*/
|
*/
|
||||||
protected array $middlewares = [];
|
protected array $middlewares = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Defer[]
|
||||||
|
*/
|
||||||
|
protected array $deferred = [];
|
||||||
|
|
||||||
protected ?string $sourceFile = null;
|
protected ?string $sourceFile = null;
|
||||||
|
|
||||||
protected string $sourceKind = 'attribute';
|
protected string $sourceKind = 'attribute';
|
||||||
@@ -152,6 +158,25 @@ class Handler implements RequestHandlerInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Defer[] $deferred
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setDeferred(array $deferred): void
|
||||||
|
{
|
||||||
|
$this->deferred = $deferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Defer[]
|
||||||
|
*/
|
||||||
|
public function getDeferred(): array
|
||||||
|
{
|
||||||
|
return $this->deferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ServerRequestInterface $request
|
* @param ServerRequestInterface $request
|
||||||
* @return ResponseInterface
|
* @return ResponseInterface
|
||||||
@@ -163,8 +188,35 @@ class Handler implements RequestHandlerInterface
|
|||||||
|
|
||||||
$data = call_user_func([$controller, $this->handler[1]], ...$this->parameters);
|
$data = call_user_func([$controller, $this->handler[1]], ...$this->parameters);
|
||||||
|
|
||||||
|
$this->executeDeferred();
|
||||||
|
|
||||||
/** 根据返回类型 */
|
/** 根据返回类型 */
|
||||||
return $this->format->call($data);
|
return $this->format->call($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function executeDeferred(): void
|
||||||
|
{
|
||||||
|
foreach ($this->deferred as $defer) {
|
||||||
|
try {
|
||||||
|
$callback = $defer->callback;
|
||||||
|
$params = $defer->params;
|
||||||
|
|
||||||
|
if (is_array($callback)) {
|
||||||
|
[$class, $method] = $callback;
|
||||||
|
$instance = Kiri::getDi()->get($class);
|
||||||
|
call_user_func([$instance, $method], ...$params);
|
||||||
|
} else {
|
||||||
|
$instance = Kiri::getDi()->get($callback);
|
||||||
|
call_user_func([$instance, '__invoke'], ...$params);
|
||||||
|
}
|
||||||
|
} catch (\Throwable $throwable) {
|
||||||
|
\Kiri::getLogger()->error('Defer callback failed: ' . $throwable->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ namespace Kiri\Router;
|
|||||||
|
|
||||||
class RouteEntry
|
class RouteEntry
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param array $deferred Array of ['callback' => string|array, 'params' => array]
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public readonly string $requestMethod,
|
public readonly string $requestMethod,
|
||||||
public readonly string $path,
|
public readonly string $path,
|
||||||
@@ -14,6 +17,7 @@ class RouteEntry
|
|||||||
public readonly array $middlewares = [],
|
public readonly array $middlewares = [],
|
||||||
public readonly ?string $sourceFile = null,
|
public readonly ?string $sourceFile = null,
|
||||||
public readonly string $sourceKind = 'attribute',
|
public readonly string $sourceKind = 'attribute',
|
||||||
|
public readonly array $deferred = [],
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-3
@@ -6,6 +6,8 @@ namespace Kiri\Router;
|
|||||||
|
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Kiri\Router\Annotate\Defer;
|
||||||
|
use Kiri\Router\Annotate\DeferRegistry;
|
||||||
use Kiri\Router\Base\NotFoundController;
|
use Kiri\Router\Base\NotFoundController;
|
||||||
use Kiri\Router\Constrict\RequestMethod;
|
use Kiri\Router\Constrict\RequestMethod;
|
||||||
use Psr\Http\Server\MiddlewareInterface;
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
@@ -236,6 +238,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|||||||
|
|
||||||
$this->methods[$method . '_' . $path] = $handler;
|
$this->methods[$method . '_' . $path] = $handler;
|
||||||
$handler->setMiddlewares($this->registerMiddleware($handler->getClass(), $handler->getMethod()));
|
$handler->setMiddlewares($this->registerMiddleware($handler->getClass(), $handler->getMethod()));
|
||||||
|
$handler->setDeferred(DeferRegistry::get($handler->getClass(), $handler->getMethod()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -256,6 +259,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|||||||
$middlewares = $handler instanceof Handler ? $handler->getMiddlewares() : $handler->middlewares;
|
$middlewares = $handler instanceof Handler ? $handler->getMiddlewares() : $handler->middlewares;
|
||||||
$sourceFile = $handler instanceof Handler ? $handler->getSourceFile() : $handler->sourceFile;
|
$sourceFile = $handler instanceof Handler ? $handler->getSourceFile() : $handler->sourceFile;
|
||||||
$sourceKind = $handler instanceof Handler ? $handler->getSourceKind() : $handler->sourceKind;
|
$sourceKind = $handler instanceof Handler ? $handler->getSourceKind() : $handler->sourceKind;
|
||||||
|
$deferred = $handler instanceof Handler ? $this->serializeDeferred($handler->getDeferred()) : ($handler->deferred ?? []);
|
||||||
|
|
||||||
$entries[] = [
|
$entries[] = [
|
||||||
'request_method' => $requestMethod,
|
'request_method' => $requestMethod,
|
||||||
@@ -265,6 +269,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|||||||
'middlewares' => $middlewares,
|
'middlewares' => $middlewares,
|
||||||
'source_file' => $sourceFile,
|
'source_file' => $sourceFile,
|
||||||
'source_kind' => $sourceKind,
|
'source_kind' => $sourceKind,
|
||||||
|
'deferred' => $deferred,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,6 +319,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|||||||
middlewares: is_array($entry['middlewares'] ?? null) ? $entry['middlewares'] : [],
|
middlewares: is_array($entry['middlewares'] ?? null) ? $entry['middlewares'] : [],
|
||||||
sourceFile: is_string($sourceFile) ? $this->normalizePath($sourceFile) : null,
|
sourceFile: is_string($sourceFile) ? $this->normalizePath($sourceFile) : null,
|
||||||
sourceKind: is_string($entry['source_kind'] ?? null) ? $entry['source_kind'] : 'attribute',
|
sourceKind: is_string($entry['source_kind'] ?? null) ? $entry['source_kind'] : 'attribute',
|
||||||
|
deferred: is_array($entry['deferred'] ?? null) ? $entry['deferred'] : [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,10 +379,11 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $response
|
* @param string $class
|
||||||
* @param array $middlewares
|
* @param string $method
|
||||||
* @return array
|
* @return Defer[]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function appendMiddleware(array $response, array $middlewares): array
|
private function appendMiddleware(array $response, array $middlewares): array
|
||||||
{
|
{
|
||||||
foreach ($middlewares as $middleware) {
|
foreach ($middlewares as $middleware) {
|
||||||
@@ -448,6 +455,39 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Defer[] $deferred
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function serializeDeferred(array $deferred): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($deferred as $defer) {
|
||||||
|
$result[] = [
|
||||||
|
'callback' => $defer->callback,
|
||||||
|
'params' => $defer->params,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return Defer[]
|
||||||
|
*/
|
||||||
|
private function deserializeDeferred(array $data): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($data as $item) {
|
||||||
|
if (isset($item['callback'])) {
|
||||||
|
$result[] = new Defer($item['callback'], $item['params'] ?? []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private function normalizePath(string $path): string
|
private function normalizePath(string $path): string
|
||||||
{
|
{
|
||||||
$resolved = realpath($path) ?: $path;
|
$resolved = realpath($path) ?: $path;
|
||||||
@@ -464,6 +504,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|||||||
$handler->setMiddlewares($method->middlewares);
|
$handler->setMiddlewares($method->middlewares);
|
||||||
$handler->setSourceFile($method->sourceFile);
|
$handler->setSourceFile($method->sourceFile);
|
||||||
$handler->setSourceKind($method->sourceKind);
|
$handler->setSourceKind($method->sourceKind);
|
||||||
|
$handler->setDeferred($this->deserializeDeferred($method->deferred));
|
||||||
$method = $handler;
|
$method = $handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user