1 Commits

Author SHA1 Message Date
as2252258 28973df8b6 eee 2026-06-12 23:57:20 +08:00
4 changed files with 101 additions and 4 deletions
+1 -1
View File
@@ -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"
+52
View File
@@ -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());
}
}
}
} }
+4
View File
@@ -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
View File
@@ -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;
} }