56 Commits

Author SHA1 Message Date
as2252258 0c2462feee eee 2025-07-10 10:30:20 +08:00
as2252258 4c4a21dd7a eee 2025-07-10 09:30:13 +08:00
as2252258 8623a036ed eee 2025-07-08 11:43:04 +08:00
as2252258 f38942f4f3 eee 2024-12-16 16:36:35 +08:00
as2252258 dc561cec9b eee 2024-12-16 16:29:35 +08:00
as2252258 daa02a6408 eee 2024-12-16 16:05:01 +08:00
as2252258 34ab8f145c eee 2024-12-16 15:55:29 +08:00
as2252258 ae20755bd7 eee 2024-12-16 15:47:00 +08:00
as2252258 011e95a3f2 eee 2024-12-16 15:44:56 +08:00
as2252258 5bda66b40d eee 2024-11-18 17:05:21 +08:00
as2252258 e82fad2fcb eee 2024-11-18 17:02:58 +08:00
as2252258 16eb6b11c5 eee 2024-11-18 16:11:16 +08:00
as2252258 227b6fa512 eee 2024-11-18 16:09:59 +08:00
as2252258 c06ab29054 eee 2024-11-18 14:21:43 +08:00
as2252258 3ccf08fdfb eee 2024-11-15 14:24:57 +08:00
as2252258 292ccc84de eee 2024-11-15 14:18:20 +08:00
as2252258 edc7371d9b eee 2024-11-15 14:16:37 +08:00
as2252258 8440104053 eee 2024-09-03 15:19:08 +08:00
as2252258 3bc65b8776 eee 2024-09-03 14:47:28 +08:00
as2252258 7aee7e158f eee 2024-08-29 17:56:12 +08:00
as2252258 e9989e36d9 eee 2024-08-29 17:40:22 +08:00
as2252258 814d6c6054 eee 2024-08-29 17:19:19 +08:00
as2252258 13a2d037c3 eee 2024-08-29 17:15:38 +08:00
as2252258 8811f2bcd6 eee 2024-08-29 17:14:37 +08:00
as2252258 080cd6ab92 eee 2024-08-29 17:09:26 +08:00
as2252258 c435af1156 eee 2024-08-29 17:01:08 +08:00
as2252258 337c52c744 eee 2024-08-29 16:28:49 +08:00
as2252258 47d864bbf7 eee 2024-08-29 16:25:25 +08:00
as2252258 4197b16132 eee 2024-08-29 16:24:45 +08:00
as2252258 dcf6940062 eee 2024-08-29 16:23:17 +08:00
as2252258 2baf2847ab eee 2024-08-29 16:19:24 +08:00
as2252258 3b5a4adbc9 eee 2024-08-29 16:17:05 +08:00
as2252258 e307accb7c eee 2024-08-29 16:11:13 +08:00
as2252258 e59b78d2b1 eee 2024-08-29 16:10:20 +08:00
as2252258 ac4315bcb9 eee 2024-08-29 16:08:11 +08:00
as2252258 1efb583194 eee 2024-08-29 16:04:07 +08:00
as2252258 dfeb79aaea eee 2024-08-29 15:58:42 +08:00
as2252258 2058849059 eee 2024-08-29 15:56:30 +08:00
as2252258 abb69cff20 eee 2024-08-29 15:55:06 +08:00
as2252258 b149fbf693 eee 2024-08-29 15:50:28 +08:00
as2252258 b2e641c159 eee 2024-08-29 13:46:16 +08:00
as2252258 be1badfa5c eee 2024-08-29 13:43:45 +08:00
as2252258 1795b59b88 eee 2024-08-29 12:00:10 +08:00
as2252258 6efd221585 eee 2024-04-18 00:58:13 +08:00
as2252258 ebc39a6938 eee 2024-04-18 00:38:09 +08:00
as2252258 26d32fbe7f eee 2024-04-18 00:37:43 +08:00
as2252258 b9940509a9 eee 2024-04-15 15:28:03 +08:00
as2252258 12848dd71d eee 2024-04-15 15:26:04 +08:00
as2252258 4e34436231 eee 2024-04-15 15:24:18 +08:00
as2252258 722b9060d0 eee 2024-04-15 15:24:04 +08:00
as2252258 92604bf0c1 eee 2024-04-15 15:22:28 +08:00
as2252258 4b383027f8 eee 2024-04-15 15:20:00 +08:00
as2252258 f644821230 eee 2024-04-15 15:16:42 +08:00
as2252258 67ff141afe eee 2024-04-15 15:15:08 +08:00
as2252258 7a4cce7343 Merge remote-tracking branch 'origin/main' 2024-03-01 14:47:32 +08:00
as2252258 adc310cf21 eee 2024-03-01 14:46:50 +08:00
48 changed files with 1257 additions and 1130 deletions
+1 -3
View File
@@ -28,14 +28,12 @@ class Delete extends AbstractRequestMethod implements InjectMethodInterface
*/ */
public function dispatch(string $class, string $method): void public function dispatch(string $class, string $method): void
{ {
$controller = \Kiri::getDi()->get($class);
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
$path = '/' . ltrim($this->path, '/'); $path = '/' . ltrim($this->path, '/');
if (!empty($this->version)) { if (!empty($this->version)) {
$path = '/' . trim($this->version) . $path; $path = '/' . trim($this->version) . $path;
} }
Router::addRoute(RequestMethod::REQUEST_DELETE, $path, [$controller, $method]); Router::addRoute(RequestMethod::REQUEST_DELETE, $path, [$class, $method]);
} }
+1 -3
View File
@@ -28,14 +28,12 @@ class Get extends AbstractRequestMethod implements InjectMethodInterface
*/ */
public function dispatch(string $class, string $method): void public function dispatch(string $class, string $method): void
{ {
$controller = \Kiri::getDi()->get($class);
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
$path = '/' . ltrim($this->path, '/'); $path = '/' . ltrim($this->path, '/');
if (!empty($this->version)) { if (!empty($this->version)) {
$path = '/' . trim($this->version) . $path; $path = '/' . trim($this->version) . $path;
} }
Router::addRoute(RequestMethod::REQUEST_GET, $path, [$controller, $method]); Router::addRoute(RequestMethod::REQUEST_GET, $path, [$class, $method]);
} }
} }
+1 -2
View File
@@ -29,13 +29,12 @@ class Head extends AbstractRequestMethod implements InjectMethodInterface
*/ */
public function dispatch(string $class, string $method): void public function dispatch(string $class, string $method): void
{ {
$controller = Kiri::getDi()->get($class);
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
$path = '/' . ltrim($this->path, '/'); $path = '/' . ltrim($this->path, '/');
if (!empty($this->version)) { if (!empty($this->version)) {
$path = '/' . trim($this->version) . $path; $path = '/' . trim($this->version) . $path;
} }
Router::addRoute(RequestMethod::REQUEST_HEAD, $path, [$controller, $method]); Router::addRoute(RequestMethod::REQUEST_HEAD, $path, [$class, $method]);
} }
+1 -3
View File
@@ -30,14 +30,12 @@ class Options extends AbstractRequestMethod implements InjectMethodInterface
*/ */
public function dispatch(string $class, string $method): void public function dispatch(string $class, string $method): void
{ {
$controller = Kiri::getDi()->get($class);
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
$path = '/' . ltrim($this->path, '/'); $path = '/' . ltrim($this->path, '/');
if (!empty($this->version)) { if (!empty($this->version)) {
$path = '/' . trim($this->version) . $path; $path = '/' . trim($this->version) . $path;
} }
Router::addRoute(RequestMethod::REQUEST_OPTIONS, $path, [$controller, $method]); Router::addRoute(RequestMethod::REQUEST_OPTIONS, $path, [$class, $method]);
} }
+1 -3
View File
@@ -30,13 +30,11 @@ class Post extends AbstractRequestMethod implements InjectMethodInterface
public function dispatch(string $class, string $method): void public function dispatch(string $class, string $method): void
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
$controller = Kiri::getDi()->get($class);
$path = '/' . ltrim($this->path, '/'); $path = '/' . ltrim($this->path, '/');
if (!empty($this->version)) { if (!empty($this->version)) {
$path = '/' . trim($this->version) . $path; $path = '/' . trim($this->version) . $path;
} }
Router::addRoute(RequestMethod::REQUEST_POST, $path, [$controller, $method]); Router::addRoute(RequestMethod::REQUEST_POST, $path, [$class, $method]);
} }
+1 -2
View File
@@ -32,13 +32,12 @@ class Put extends AbstractRequestMethod implements InjectMethodInterface
*/ */
public function dispatch(string $class, string $method): void public function dispatch(string $class, string $method): void
{ {
$controller = Kiri::getDi()->get($class);
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
$path = '/' . ltrim($this->path, '/'); $path = '/' . ltrim($this->path, '/');
if (!empty($this->version)) { if (!empty($this->version)) {
$path = '/' . trim($this->version) . $path; $path = '/' . trim($this->version) . $path;
} }
Router::addRoute(RequestMethod::REQUEST_PUT, $path, [$controller, $method]); Router::addRoute(RequestMethod::REQUEST_PUT, $path, [$class, $method]);
} }
} }
+1 -2
View File
@@ -28,11 +28,10 @@ class Route extends AbstractRequestMethod implements InjectMethodInterface
*/ */
public function dispatch(string $class, string $method): void public function dispatch(string $class, string $method): void
{ {
$controller = \Kiri::getDi()->get($class);
$path = '/' . ltrim($this->path, '/'); $path = '/' . ltrim($this->path, '/');
if (!empty($this->version)) { if (!empty($this->version)) {
$path = '/' . trim($this->version) . $path; $path = '/' . trim($this->version) . $path;
} }
Router::addRoute([$this->method], $path, [$controller, $method]); Router::addRoute([$this->method], $path, [$class, $method]);
} }
} }
+30 -29
View File
@@ -12,39 +12,40 @@ abstract class AbstractHandler
{ {
public int $offset = 0; public int $offset = 0;
public array $middlewares = [];
/** /**
* @param array $middlewares * @param array $middlewares
* @param Handler $handler * @param Handler $handler
* @throws *
*/ * @throws
public function __construct(array $middlewares, public Handler $handler) */
{ public function __construct(public array $middlewares, public Handler $handler)
foreach ($middlewares as $middleware) { {
$this->middlewares[] = di($middleware); }
}
}
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws
*/
public function execute(ServerRequestInterface $request): ResponseInterface
{
if (!isset($this->middlewares[$this->offset])) {
return $this->handler->handle($request);
}
/** @var MiddlewareInterface $middleware */ /**
$middleware = $this->middlewares[$this->offset]; * @param ServerRequestInterface $request
$this->offset += 1; *
* @return ResponseInterface
* @throws
*/
public function execute(ServerRequestInterface $request): ResponseInterface
{
if (!isset($this->middlewares[$this->offset])) {
return $this->handler->handle($request);
}
return $middleware->process($request, $this); $middleware = $this->middlewares[$this->offset];
} $this->offset += 1;
if (!($middleware instanceof MiddlewareInterface)) {
$middleware = \Kiri::getDi()->get($middleware);
}
return $middleware->process($request, $this);
}
} }
+22 -32
View File
@@ -5,50 +5,24 @@ namespace Kiri\Router\Base;
use Kiri; use Kiri;
use Kiri\Router\Response;
use Kiri\Router\Request; use Kiri\Router\Request;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Kiri\Di\Inject\Container; use Psr\Log\LoggerInterface;
/** /**
* Class WebController * Class WebController
* @package Kiri\Web * @package Kiri\Web
* @property RequestInterface $request
* @property ResponseInterface $response
* @property ContainerInterface $container
* @property Kiri\Error\StdoutLogger $logger
*/ */
abstract class Controller class Controller extends Kiri\Abstracts\Component
{ {
/**
* @var Request
*/
#[Container(RequestInterface::class)]
public RequestInterface $request;
/**
* @var Response
*/
#[Container(ResponseInterface::class)]
public ResponseInterface $response;
/**
* @var ContainerInterface
*/
#[Container(ContainerInterface::class)]
public ContainerInterface $container;
/**
* @var Kiri\Error\StdoutLogger
*/
#[Container(LoggerInterface::class)]
public Kiri\Error\StdoutLogger $logger;
/** /**
* @param Request $request * @param Request $request
* @return true * @return true
@@ -58,4 +32,20 @@ abstract class Controller
return true; return true;
} }
/**
* @param string $name
* @return mixed|ContainerInterface|RequestInterface|ResponseInterface|LoggerInterface
* @throws \Exception
*/
public function __get(string $name)
{
return match ($name) {
'request' => di(RequestInterface::class),
'response' => di(ResponseInterface::class),
'container' => di(ContainerInterface::class),
'logger' => di(LoggerInterface::class),
default => parent::__get($name)
}; // TODO: Change the autogenerated stub
}
} }
+2 -9
View File
@@ -18,14 +18,6 @@ use Psr\Http\Server\RequestHandlerInterface;
class CoreMiddleware implements MiddlewareInterface class CoreMiddleware implements MiddlewareInterface
{ {
/**
* @var Response
*/
#[Container(ResponseInterface::class)]
public ResponseInterface $response;
/** /**
* @param Request $request * @param Request $request
* @param RequestHandlerInterface $handler * @param RequestHandlerInterface $handler
@@ -34,7 +26,8 @@ class CoreMiddleware implements MiddlewareInterface
*/ */
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{ {
$this->response->withHeaders(['Access-Control-Allow-Headers' => '*', 'Access-Control-Request-Method' => '*', 'Access-Control-Allow-Origin' => '*']); $response = \Kiri::getDi()->get(ResponseInterface::class);
$response->withHeaders(['Access-Control-Allow-Headers' => '*', 'Access-Control-Request-Method' => '*', 'Access-Control-Allow-Origin' => '*']);
return $handler->handle($request); return $handler->handle($request);
} }
+30 -19
View File
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Kiri\Router\Base; namespace Kiri\Router\Base;
use Kiri; use Kiri;
use Kiri\Router\Validator\Validator;
use Kiri\Router\Validator\ValidatorMiddleware;
class Middleware class Middleware
{ {
@@ -12,36 +14,25 @@ class Middleware
/** /**
* @var array * @var array
*/ */
protected static array $manager = [];
protected static array $mapping = []; protected static array $mapping = [];
protected static array $validators = [];
/** /**
* @param string $className * @param string $className
* @param string $method * @param string $method
* @param string $middleware * @param string $middleware
* @return void * @return void
* @throws
*/ */
public static function set(string $className, string $method, string|object $middleware): void public static function set(string $className, string $method, string $middleware): void
{ {
$path = $className . '::' . $method; $path = $className . '::' . $method;
if (!isset(static::$manager[$path])) { if (!isset(static::$mapping[$path])) {
static::$manager[$path] = static::$mapping[$path] = []; static::$mapping[$path] = [];
} }
if (!in_array($middleware, static::$mapping[$path])) {
if (is_object($middleware)) { static::$mapping[$path][] = $middleware;
if (!in_array($middleware::class, static::$mapping[$path])) {
static::$manager[$path][] = $middleware;
static::$mapping[$path][] = $middleware::class;
}
} else {
if (!in_array($middleware, static::$mapping[$path])) {
static::$manager[$path][] = Kiri::getDi()->get($middleware);
static::$mapping[$path][] = $middleware;
}
} }
} }
@@ -53,8 +44,28 @@ class Middleware
*/ */
public static function get(string $className, string $method): array public static function get(string $className, string $method): array
{ {
return static::$manager[$className . '::' . $method] ?? []; return static::$mapping[$className . '::' . $method] ?? [];
} }
/**
* @param string $class
* @param string $method
* @param Validator $validators
*/
public static function setValidator(string $class, string $method, Validator $validators): void
{
self::$validators[$class . '::' . $method] = $validators;
}
/**
* @param string $class
* @param string $method
* @return Validator|null
*/
public static function getValidator(string $class, string $method): ?Validator
{
return static::$validators[$class . '::' . $method] ?? null;
}
} }
+32
View File
@@ -7,6 +7,8 @@ use Kiri\Core\Help;
use Kiri\Router\ContentType; use Kiri\Router\ContentType;
use Kiri\Router\StreamResponse; use Kiri\Router\StreamResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Swoole\Http\Response;
class ConstrictResponse extends Message implements ResponseInterface class ConstrictResponse extends Message implements ResponseInterface
{ {
@@ -18,11 +20,18 @@ class ConstrictResponse extends Message implements ResponseInterface
private string $reasonPhrase; private string $reasonPhrase;
/**
* @var array|mixed
*/
public array $headers = [];
/** /**
* @param ContentType|null $contentType * @param ContentType|null $contentType
*/ */
public function __construct(?ContentType $contentType = null) public function __construct(?ContentType $contentType = null)
{ {
$this->headers = \config('response.headers', $this->headers);
if ($contentType != null) { if ($contentType != null) {
$this->withHeader('Content-Type', $contentType->toString()); $this->withHeader('Content-Type', $contentType->toString());
} }
@@ -30,6 +39,25 @@ class ConstrictResponse extends Message implements ResponseInterface
} }
/**
* @param string $url
* @param array $params
* @param int $statusCode
* @return static
*/
public function redirectTo(string $url, array $params = [], int $statusCode = 302): static
{
if (!empty($params)) {
$url .= '?' . http_build_query($params);
}
$this->withHeader('Location', $url);
$this->withStatus($statusCode);
return $this;
}
/** /**
* @param ContentType $contentType * @param ContentType $contentType
* @return $this * @return $this
@@ -187,6 +215,10 @@ class ConstrictResponse extends Message implements ResponseInterface
*/ */
public function end(object $response): void public function end(object $response): void
{ {
/** @var Response $response */
if (count($this->headers) > 0) foreach ($this->headers as $key => $header) {
$response->header($key, $header);
}
$response->end($this->stream->getContents()); $response->end($this->stream->getContents());
} }
} }
+644 -643
View File
File diff suppressed because it is too large Load Diff
+35 -13
View File
@@ -5,22 +5,21 @@ namespace Kiri\Router;
use Closure; use Closure;
use Exception; use Exception;
use Kiri;
use Kiri\Router\Format\ArrayFormat;
use Kiri\Router\Format\MixedFormat;
use Kiri\Router\Format\OtherFormat;
use Kiri\Router\Format\ResponseFormat;
use Kiri\Router\Format\VoidFormat;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use ReflectionClass; use ReflectionClass;
use ReflectionFunction;
use ReflectionMethod; use ReflectionMethod;
class ControllerInterpreter class ControllerInterpreter
{ {
/**
* @param ContainerInterface $container
*/
public function __construct(public ContainerInterface $container)
{
}
/** /**
* @param object $class * @param object $class
* @param string|ReflectionMethod $method * @param string|ReflectionMethod $method
@@ -31,7 +30,7 @@ class ControllerInterpreter
public function addRouteByString(object $class, string|ReflectionMethod $method, ?ReflectionClass $reflection = null): Handler public function addRouteByString(object $class, string|ReflectionMethod $method, ?ReflectionClass $reflection = null): Handler
{ {
if (is_null($reflection)) { if (is_null($reflection)) {
$reflection = $this->container->getReflectionClass($class::class); $reflection = Kiri::getDi()->getReflectionClass($class::class);
} }
return $this->resolveMethod($class, $method, $reflection); return $this->resolveMethod($class, $method, $reflection);
} }
@@ -44,9 +43,13 @@ class ControllerInterpreter
*/ */
public function addRouteByClosure(Closure $method): Handler public function addRouteByClosure(Closure $method): Handler
{ {
$reflection = new \ReflectionFunction($method); $reflection = new ReflectionFunction($method);
return new Handler($method, $reflection); $parameters = Kiri::getDi()->getFunctionParams($method);
$returnType = $this->getReturnType($reflection);
return new Handler($method, $parameters, $returnType);
} }
@@ -60,7 +63,7 @@ class ControllerInterpreter
public function addRouteByObject(object $class, string|ReflectionMethod $method, ?ReflectionClass $reflection = null): Handler public function addRouteByObject(object $class, string|ReflectionMethod $method, ?ReflectionClass $reflection = null): Handler
{ {
if (is_null($reflection)) { if (is_null($reflection)) {
$reflection = $this->container->getReflectionClass($class::class); $reflection = Kiri::getDi()->getReflectionClass($class::class);
} }
return $this->resolveMethod($class, $method, $reflection); return $this->resolveMethod($class, $method, $reflection);
} }
@@ -79,7 +82,26 @@ class ControllerInterpreter
$reflectionMethod = $reflectionClass->getMethod($reflectionMethod); $reflectionMethod = $reflectionClass->getMethod($reflectionMethod);
} }
return new Handler([$class, $reflectionMethod->getName()], $reflectionMethod); $parameters = Kiri::getDi()->getMethodParams($reflectionMethod);
$returnType = $this->getReturnType($reflectionMethod);
return new Handler([$class::class, $reflectionMethod->getName()], $parameters, $returnType);
}
/**
* @param ReflectionMethod|ReflectionFunction $reflectionMethod
* @return string
*/
protected function getReturnType(ReflectionMethod|ReflectionFunction $reflectionMethod): string
{
return match ($reflectionMethod->getReturnType()?->getName()) {
'array' => ArrayFormat::class,
'mixed', 'object' => MixedFormat::class,
'int', 'string', 'bool' => OtherFormat::class,
'void' => VoidFormat::class,
default => ResponseFormat::class
};
} }
} }
+15 -13
View File
@@ -10,21 +10,23 @@ class ArrayFormat implements IFormat
{ {
/** /**
* @var ResponseInterface * @param ResponseInterface $response
*/ */
#[Container(ResponseInterface::class)] public function __construct(public ResponseInterface $response)
public ResponseInterface $response; {
}
/** /**
* @param $result * @param $result
* @return ResponseInterface *
*/ * @return ResponseInterface
public function call($result): ResponseInterface */
{ public function call($result): ResponseInterface
return $this->response->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE))); {
} return $this->response->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE)));
}
} }
+1
View File
@@ -7,6 +7,7 @@ use Psr\Http\Message\ResponseInterface;
interface IFormat interface IFormat
{ {
/** /**
* @param $result * @param $result
* @return ResponseInterface * @return ResponseInterface
+9 -8
View File
@@ -2,22 +2,23 @@
namespace Kiri\Router\Format; namespace Kiri\Router\Format;
use Kiri\Di\Inject\Container; use Kiri;
use Kiri\Router\Constrict\Stream; use Kiri\Router\Constrict\Stream;
use Kiri\Router\ContentType;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
class MixedFormat implements IFormat class MixedFormat implements IFormat
{ {
/**
* @var ResponseInterface /**
*/ * @param ResponseInterface $response
#[Container(ResponseInterface::class)] */
public ResponseInterface $response; public function __construct(public ResponseInterface $response)
{
}
/** /**
* @param mixed $result * @param mixed $result
* @return ResponseInterface * @return ResponseInterface
*/ */
+30 -29
View File
@@ -2,42 +2,43 @@
namespace Kiri\Router\Format; namespace Kiri\Router\Format;
use Kiri\Di\Inject\Container; use Kiri;
use Kiri\Router\Constrict\Stream; use Kiri\Router\Constrict\Stream;
use Kiri\Router\ContentType;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
class NoBody implements IFormat class NoBody implements IFormat
{ {
/** /**
* @var ResponseInterface * @param ResponseInterface $response
*/ */
#[Container(ResponseInterface::class)] public function __construct(public ResponseInterface $response)
public ResponseInterface $response; {
}
/** /**
* @param $result * @param $result
* @return ResponseInterface *
*/ * @return ResponseInterface
public function call($result): ResponseInterface */
{ public function call($result): ResponseInterface
// TODO: Implement call() method. {
if (request()->getMethod() === 'HEAD') { // TODO: Implement call() method.
return $this->response->withBody(new Stream()); if (request()->getMethod() === 'HEAD') {
} return $this->response->withBody(new Stream());
if ($result instanceof ResponseInterface) { }
return $result; if ($result instanceof ResponseInterface) {
} return $result;
if (is_object($result)) { }
return $this->response->withBody(new Stream('[object]')); if (is_object($result)) {
} return $this->response->withBody(new Stream('[object]'));
if (is_array($result)) { }
return $this->response->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE))); if (is_array($result)) {
} else { return $this->response->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE)));
return $this->response->withBody(new Stream((string)$result)); } else {
} return $this->response->withBody(new Stream((string)$result));
} }
}
} }
+4 -6
View File
@@ -9,14 +9,12 @@ use Psr\Http\Message\ResponseInterface;
class OtherFormat implements IFormat class OtherFormat implements IFormat
{ {
/**
* @var ResponseInterface
*/
#[Container(ResponseInterface::class)]
public ResponseInterface $response;
public function __construct(public ResponseInterface $response)
{
}
/** /**
* @param mixed $result * @param mixed $result
* @return ResponseInterface * @return ResponseInterface
*/ */
+1
View File
@@ -7,6 +7,7 @@ use Psr\Http\Message\ResponseInterface;
class ResponseFormat implements IFormat class ResponseFormat implements IFormat
{ {
/** /**
* @param $result * @param $result
* @return ResponseInterface * @return ResponseInterface
+16 -16
View File
@@ -9,22 +9,22 @@ class VoidFormat implements IFormat
{ {
/** /**
* @var ResponseInterface * @param ResponseInterface $response
*/ */
#[Container(ResponseInterface::class)] public function __construct(public ResponseInterface $response)
public ResponseInterface $response; {
}
/**
* @param $result
/** *
* @param $result * @return ResponseInterface
* @return ResponseInterface */
*/ public function call($result): ResponseInterface
public function call($result): ResponseInterface {
{ // TODO: Implement call() method.
// TODO: Implement call() method. return $this->response;
return $this->response; }
}
} }
+19 -49
View File
@@ -4,21 +4,13 @@ declare(strict_types=1);
namespace Kiri\Router; namespace Kiri\Router;
use Closure; use Closure;
use Kiri\Router\Format\ArrayFormat; use Kiri;
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;
use Kiri\Router\Format\OtherFormat;
use Kiri\Router\Format\ResponseFormat;
use Kiri\Router\Format\VoidFormat;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
use ReflectionFunction;
use ReflectionMethod;
class Handler implements RequestHandlerInterface class Handler implements RequestHandlerInterface
{ {
@@ -29,48 +21,24 @@ class Handler implements RequestHandlerInterface
protected mixed $format; protected mixed $format;
/**
* @var array
*/
protected array $methods = []; protected array $methods = [];
/**
* @var ContainerInterface
*/
protected ContainerInterface $container;
protected array $parameters;
/** /**
* @param array|Closure $handler * @param array|Closure $handler
* @param ReflectionMethod|ReflectionFunction $parameter * @param array $parameters
* @throws ContainerExceptionInterface * @param string|null $parameter
* @throws NotFoundExceptionInterface
*/ */
public function __construct(public array|Closure $handler, public ReflectionMethod|ReflectionFunction $parameter) public function __construct(public array|Closure $handler, public array $parameters, ?string $parameter)
{ {
$this->container = \Kiri::getDi(); if ($parameter !== null) {
if ($this->parameter->getReturnType() != null) { $this->format = Kiri::getDi()->get($parameter);
$this->format = $this->container->get($this->returnType($parameter));
} else { } else {
$this->format = $this->container->get(MixedFormat::class); $this->format = Kiri::getDi()->get(MixedFormat::class);
} }
$this->parameters = $this->container->getMethodParams($this->parameter);
}
/**
* @param $reflectionType
* @return string
*/
protected function returnType(ReflectionMethod $reflectionType): string
{
return match ($reflectionType->getReturnType()->getName()) {
'array' => ArrayFormat::class,
'mixed', 'object' => MixedFormat::class,
'int', 'string', 'bool' => OtherFormat::class,
'void' => VoidFormat::class,
default => ResponseFormat::class
};
} }
@@ -81,8 +49,8 @@ class Handler implements RequestHandlerInterface
*/ */
public function setRequestMethod(string $method): void public function setRequestMethod(string $method): void
{ {
if ($method == 'HEAD') { if ($method == 'HEAD' || $method == 'OPTIONS') {
$this->format = $this->container->get(NoBody::class); $this->format = Kiri::getDi()->get(NoBody::class);
} }
} }
@@ -102,7 +70,7 @@ class Handler implements RequestHandlerInterface
*/ */
public function implement(string $interface): bool public function implement(string $interface): bool
{ {
if (!$this->isClosure()) { if (!$this->handler instanceof Closure) {
return $this->handler[0] instanceof $interface; return $this->handler[0] instanceof $interface;
} }
return false; return false;
@@ -114,10 +82,10 @@ class Handler implements RequestHandlerInterface
*/ */
public function getClass(): ?string public function getClass(): ?string
{ {
if ($this->isClosure()) { if ($this->handler instanceof Closure) {
return null; return null;
} }
return $this->handler[0]::class; return $this->handler[0];
} }
@@ -126,7 +94,7 @@ class Handler implements RequestHandlerInterface
*/ */
public function getMethod(): ?string public function getMethod(): ?string
{ {
if ($this->isClosure()) { if ($this->handler instanceof Closure) {
return null; return null;
} }
return $this->handler[1]; return $this->handler[1];
@@ -140,7 +108,9 @@ class Handler implements RequestHandlerInterface
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface
{ {
$data = call_user_func($this->handler, ...$this->parameters); $controller = Kiri::getDi()->get($this->handler[0]);
$data = call_user_func([$controller, $this->handler[1]], ...$this->parameters);
/** 根据返回类型 */ /** 根据返回类型 */
return $this->format->call($data); return $this->format->call($data);
-1
View File
@@ -7,7 +7,6 @@ use Kiri\Router\Base\AbstractHandler;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
use ReflectionException;
class HttpRequestHandler extends AbstractHandler implements RequestHandlerInterface class HttpRequestHandler extends AbstractHandler implements RequestHandlerInterface
{ {
+1
View File
@@ -9,6 +9,7 @@ use Swoole\Http\Response;
interface OnRequestInterface interface OnRequestInterface
{ {
/** /**
* @param Request $request * @param Request $request
* @param Response $response * @param Response $response
+93
View File
@@ -0,0 +1,93 @@
<?php
declare(strict_types=1);
namespace Kiri\Router;
use Kiri\Abstracts\CoordinatorManager;
use Kiri\Coordinator;
use Kiri\Di\Inject\Container;
use Kiri\Di\Context;
use Kiri\Di\Interface\ResponseEmitterInterface;
use Kiri\Router\Base\ExceptionHandlerDispatcher;
use Kiri\Router\Constrict\ConstrictRequest as CQ;
use Kiri\Router\Constrict\ConstrictResponse;
use Kiri\Router\Interface\ExceptionHandlerInterface;
use Kiri\Router\Interface\OnRequestInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Throwable;
/**
* OnRequest event
*/
class OnRequest implements OnRequestInterface
{
/**
* @var RouterCollector
*/
public RouterCollector $router;
/**
* @var ExceptionHandlerInterface
*/
public ExceptionHandlerInterface $exception;
/**
* @var ResponseEmitterInterface
*/
public ResponseEmitterInterface $responseEmitter;
/**
* @var ConstrictResponse
*/
#[Container(ConstrictResponse::class)]
public ConstrictResponse $constrictResponse;
/**
* @param ResponseInterface $response
* @param DataGrip $dataGrip
*/
public function __construct(public ResponseInterface $response, DataGrip $dataGrip)
{
$this->responseEmitter = $this->response->emmit;
$exception = \config('exception.http');
if (!in_array(ExceptionHandlerInterface::class, class_implements($exception))) {
$exception = ExceptionHandlerDispatcher::class;
}
$this->exception = \Kiri::getDi()->get($exception);
$this->router = $dataGrip->get(ROUTER_TYPE_HTTP);
}
/**
* @param Request $request
* @param Response $response
* @throws
*/
public function onRequest(Request $request, Response $response): void
{
try {
/** @var CQ $PsrRequest */
Context::set(ResponseInterface::class, new ConstrictResponse($this->response->contentType));
$PsrRequest = Context::set(RequestInterface::class, CQ::builder($request));
CoordinatorManager::utility(Coordinator::WORKER_START)->yield();
$PsrResponse = $this->router->query($request->server['path_info'], $request->getMethod())->run($PsrRequest);
} catch (Throwable $throwable) {
$PsrResponse = $this->exception->emit($throwable, $this->constrictResponse);
} finally {
$this->responseEmitter->response($PsrResponse, $response, $PsrRequest);
}
}
}
+10
View File
@@ -68,6 +68,16 @@ class Response implements ResponseInterface
return $this->__call__(__FUNCTION__, $content, $statusCode); return $this->__call__(__FUNCTION__, $content, $statusCode);
} }
/**
* @param string $url
* @param array $params
* @param int $statusCode
* @return ResponseInterface
*/
public function redirectTo(string $url, array $params = [], int $statusCode = 302): ResponseInterface
{
return $this->__call__(__FUNCTION__, $url, $params, $statusCode);
}
/** /**
* @param array $content * @param array $content
+196 -175
View File
@@ -4,10 +4,15 @@ declare(strict_types=1);
namespace Kiri\Router; namespace Kiri\Router;
use Closure; use Closure;
use Kiri\Server\Events\OnWorkerStart;
use Kiri; use Kiri;
use Kiri\Abstracts\CoordinatorManager;
use Kiri\Coordinator;
use Kiri\Router\Validator\ValidatorMiddleware;
use Kiri\Router\Base\Middleware as MiddlewareManager; use Kiri\Router\Base\Middleware as MiddlewareManager;
use Kiri\Router\Constrict\RequestMethod; use Kiri\Router\Constrict\RequestMethod;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
/** /**
* *
@@ -22,214 +27,230 @@ class Router
{ {
const array METHODS = [RequestMethod::REQUEST_POST, RequestMethod::REQUEST_GET, RequestMethod::REQUEST_OPTIONS, RequestMethod::REQUEST_DELETE, RequestMethod::REQUEST_PUT, RequestMethod::REQUEST_HEAD]; const array METHODS = [RequestMethod::REQUEST_POST, RequestMethod::REQUEST_GET, RequestMethod::REQUEST_OPTIONS, RequestMethod::REQUEST_DELETE, RequestMethod::REQUEST_PUT, RequestMethod::REQUEST_HEAD];
/** /**
* @var string * @var string
*/ */
private static string $type = ROUTER_TYPE_HTTP; private static string $type = ROUTER_TYPE_HTTP;
/** /**
* @param string $name * @param string $name
* @param Closure $closure * @param Closure $closure
*/ */
public static function addServer(string $name, Closure $closure): void public static function addServer(string $name, Closure $closure): void
{ {
static::$type = $name; static::$type = $name;
$closure(); $closure();
static::$type = ROUTER_TYPE_HTTP; static::$type = ROUTER_TYPE_HTTP;
} }
/** /**
* @param Closure $handler * @param Closure $handler
*/ */
public static function jsonp(Closure $handler): void public static function jsonp(Closure $handler): void
{ {
static::$type = 'json-rpc'; static::$type = 'json-rpc';
$handler(); $handler();
static::$type = ROUTER_TYPE_HTTP; static::$type = ROUTER_TYPE_HTTP;
} }
/** /**
* @param string $route * @param string $route
* @param string $handler * @param string $handler
* @throws *
*/ * @throws
public static function post(string $route, string $handler): void */
{ public static function post(string $route, string $handler): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router->addRoute([RequestMethod::REQUEST_POST], $route, $handler); $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
} $router->addRoute([RequestMethod::REQUEST_POST], $route, $handler);
}
/** /**
* @param string $route * @param string $route
* @param string $handler * @param string $handler
* @throws *
*/ * @throws
public static function get(string $route, string $handler): void */
{ public static function get(string $route, string $handler): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router->addRoute([RequestMethod::REQUEST_GET], $route, $handler); $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
} $router->addRoute([RequestMethod::REQUEST_GET], $route, $handler);
}
/** /**
* @param string $route * @param string $route
* @param string $handler * @param string $handler
* @throws *
*/ * @throws
public static function options(string $route, string $handler): void */
{ public static function options(string $route, string $handler): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router->addRoute([RequestMethod::REQUEST_OPTIONS], $route, $handler); $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
} $router->addRoute([RequestMethod::REQUEST_OPTIONS], $route, $handler);
}
/** /**
* @param string $route * @param string $route
* @param string $handler * @param string $handler
* @throws *
*/ * @throws
public static function any(string $route, string $handler): void */
{ public static function any(string $route, string $handler): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router->addRoute(self::METHODS, $route, $handler); $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
} $router->addRoute(self::METHODS, $route, $handler);
}
/** /**
* @param string $route * @param string $route
* @param string $handler * @param string $handler
* @throws *
*/ * @throws
public static function delete(string $route, string $handler): void */
{ public static function delete(string $route, string $handler): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router->addRoute([RequestMethod::REQUEST_DELETE], $route, $handler); $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
} $router->addRoute([RequestMethod::REQUEST_DELETE], $route, $handler);
}
/** /**
* @param string $route * @param string $route
* @param string $handler * @param string $handler
* @throws *
*/ * @throws
public static function head(string $route, string $handler): void */
{ public static function head(string $route, string $handler): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router->addRoute([RequestMethod::REQUEST_HEAD], $route, $handler); $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
} $router->addRoute([RequestMethod::REQUEST_HEAD], $route, $handler);
}
/** /**
* @param string $route * @param string $route
* @param string $handler * @param string $handler
* @throws *
*/ * @throws
public static function put(string $route, string $handler): void */
{ public static function put(string $route, string $handler): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router->addRoute([RequestMethod::REQUEST_PUT], $route, $handler); $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
} $router->addRoute([RequestMethod::REQUEST_PUT], $route, $handler);
}
/** /**
* @param array|RequestMethod $methods * @param array|RequestMethod $methods
* @param string $route * @param string $route
* @param array|string $handler * @param string|array $handler
* @throws */
*/ public static function addRoute(array|RequestMethod $methods, string $route, string|array $handler): void
public static function addRoute(array|RequestMethod $methods, string $route, array|string $handler): void {
{ $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); if ($methods instanceof RequestMethod) {
if ($methods instanceof RequestMethod) { $methods = [$methods];
$methods = [$methods]; }
} $router->addRoute($methods, $route, $handler);
$router->addRoute($methods, $route, $handler); }
}
/** /**
* @param array $config * @param array $config
* @param Closure $closure * @param Closure $closure
* @throws *
*/ * @throws
public static function group(array $config, Closure $closure): void */
{ public static function group(array $config, Closure $closure): void
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); {
$router = Kiri::getDi()->get(DataGrip::class)->get(static::$type);
$router->groupTack[] = $config; $router->groupTack[] = $config;
call_user_func($closure); call_user_func($closure);
array_pop($router->groupTack); array_pop($router->groupTack);
} }
/** /**
* @throws * @throws
*/ */
public function scan_build_route(): void public function scan_build_route(): void
{ {
$this->read_dir_file(APP_PATH . 'routes'); $coordinator = CoordinatorManager::utility(Coordinator::WORKER_START);
$container = Kiri::getDi(); $this->read_dir_file(APP_PATH . 'routes');
$scanner = di(Kiri\Di\Scanner::class);
$scanner->load_directory(APP_PATH . 'app/Controller'); $container = Kiri::getDi();
$this->reset($container); $scanner = $container->get(Kiri\Di\Scanner::class);
} $scanner->load_directory(APP_PATH . 'app/Controller');
$this->reset($container);
$coordinator->done();
}
/** /**
* @param ContainerInterface $container * @param ContainerInterface $container
* @return void *
* @throws * @return void
*/ * @throws
public function reset(ContainerInterface $container): void */
{ public function reset(ContainerInterface $container): void
$router = $container->get(DataGrip::class)->get(static::$type); {
$middleware = $container->get(MiddlewareManager::class); $router = $container->get(DataGrip::class)->get(static::$type);
foreach ($router->getMethods() as $name => $method) { foreach ($router->getMethods() as $name => $method) {
$middlewares = $middleware->get($method->getClass(), $method->getMethod()); $middlewares = MiddlewareManager::get($method->getClass(), $method->getMethod());
$validator = MiddlewareManager::getValidator($method->getClass(), $method->getMethod());
$router->setHttpHandler($name, new HttpRequestHandler($middlewares, $method)); if (!is_null($validator)) {
} array_unshift($middlewares, new ValidatorMiddleware(di(ResponseInterface::class), $method->getClass(), $method->getMethod()));
} }
$router->setHttpHandler($name, new HttpRequestHandler($middlewares, $method));
}
}
/** /**
* @param $path * @param $path
* @return void *
* @throws * @return void
*/ * @throws
private function read_dir_file($path): void */
{ private function read_dir_file($path): void
$files = glob($path . '/*'); {
for ($i = 0; $i < count($files); $i++) { $files = glob($path . '/*');
$file = $files[$i]; for ($i = 0; $i < count($files); $i++) {
if (is_dir($file)) { $file = $files[$i];
$this->read_dir_file($file); if (is_dir($file)) {
} else { $this->read_dir_file($file);
$this->resolve_file($file); } else {
} $this->resolve_file($file);
} }
} }
}
/** /**
* @param $files * @param $files
* @throws *
*/ * @throws
private function resolve_file($files): void */
{ private function resolve_file($files): void
try { {
include "$files"; try {
} catch (\Throwable $throwable) { include "$files";
error($throwable); } catch (\Throwable $throwable) {
} error($throwable);
} }
}
} }
+10 -30
View File
@@ -6,19 +6,12 @@ namespace Kiri\Router;
use Closure; use Closure;
use Exception;
use Kiri;
use Kiri\Router\Base\NotFoundController; use Kiri\Router\Base\NotFoundController;
use Kiri\Router\Constrict\RequestMethod; use Kiri\Router\Constrict\RequestMethod;
use Kiri\Di\Inject\Container;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use ReflectionException;
use ReflectionMethod;
use Throwable; use Throwable;
use Traversable; use Traversable;
use Kiri\Router\Base\Middleware; use Kiri\Router\Base\Middleware;
use Kiri\Router\Format\ResponseFormat;
/** /**
@@ -64,29 +57,12 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
protected Handler $found; protected Handler $found;
/**
* @var ControllerInterpreter
*/
#[Container(ControllerInterpreter::class)]
public ControllerInterpreter $interpreter;
/**
* @var ContainerInterface
*/
#[Container(ContainerInterface::class)]
public ContainerInterface $container;
/** /**
* @throws * @throws
*/ */
public function __construct() public function __construct()
{ {
$found = di(NotFoundController::class); $this->found = new Handler([NotFoundController::class, 'fail'], [], ResponseFormat::class);
$reflection = new ReflectionMethod($found, 'fail');
$this->found = new Handler([$found, 'fail'], $reflection);
} }
@@ -138,9 +114,9 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
try { try {
$route = $this->_splicing_routing($route); $route = $this->_splicing_routing($route);
if ($closure instanceof Closure) { if ($closure instanceof Closure) {
$handler = $this->interpreter->addRouteByClosure($closure); $handler = di(ControllerInterpreter::class)->addRouteByClosure($closure);
} else { } else {
$handler = $this->resolve($closure, $this->interpreter); $handler = $this->resolve($closure, di(ControllerInterpreter::class));
} }
foreach ($method as $value) { foreach ($method as $value) {
if ($value instanceof RequestMethod) { if ($value instanceof RequestMethod) {
@@ -169,7 +145,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
foreach ($this->methods as $methodPath => $handler) { foreach ($this->methods as $methodPath => $handler) {
[$path, $method] = explode('_', $methodPath); [$path, $method] = explode('_', $methodPath);
$controller = $handler->isClosure() ? '\Closure' : $handler->getClass() . '::' . $handler->getMethod(); $controller = $handler instanceof Closure ? '\Closure' : $handler->getClass() . '::' . $handler->getMethod();
$array[] = [ $array[] = [
'path' => $path, 'path' => $path,
'method' => $method, 'method' => $method,
@@ -188,14 +164,18 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
*/ */
private function resolve(string|array $closure, ControllerInterpreter $interpreter): Handler private function resolve(string|array $closure, ControllerInterpreter $interpreter): Handler
{ {
$container = \Kiri::getDi();
if (is_array($closure)) { if (is_array($closure)) {
if (is_string($closure[0])) {
$closure[0] = $container->get($closure[0]);
}
return $interpreter->addRouteByString(... $closure); return $interpreter->addRouteByString(... $closure);
} }
if (!str_contains($closure, '@')) { if (!str_contains($closure, '@')) {
$closure .= '@'; $closure .= '@';
} }
[$className, $method] = explode('@', $closure); [$className, $method] = explode('@', $closure);
$class = $this->container->get($this->resetName($className)); $class = $container->get($this->resetName($className));
return $interpreter->addRouteByString($class, $method); return $interpreter->addRouteByString($class, $method);
} }
+6 -9
View File
@@ -3,16 +3,13 @@ declare(strict_types=1);
namespace Kiri\Router; namespace Kiri\Router;
use Kiri\Di\Inject\Container;
use Kiri\Di\Interface\ResponseEmitterInterface; use Kiri\Di\Interface\ResponseEmitterInterface;
use Kiri\Events\EventDispatch; use Kiri\Events\EventDispatch;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Server\Events\OnAfterRequest; use Kiri\Server\Events\OnAfterRequest;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use ReflectionException;
use SplPriorityQueue; use SplPriorityQueue;
use function swoole_version;
/** /**
@@ -35,12 +32,11 @@ class SwooleHttpResponseEmitter implements ResponseEmitterInterface
/** /**
* @param EventDispatch $dispatch * @param EventDispatch $dispatch
* @param EventProvider $provider
*/ */
public function __construct(readonly public EventDispatch $dispatch, readonly public EventProvider $provider) public function __construct(readonly public EventDispatch $dispatch)
{ {
$this->afterRequest = new OnAfterRequest(); $this->afterRequest = new OnAfterRequest();
$this->events = $this->provider->getListenersForEvent($this->afterRequest); $this->events = di(EventProvider::class)->getListenersForEvent($this->afterRequest);
} }
@@ -70,6 +66,7 @@ class SwooleHttpResponseEmitter implements ResponseEmitterInterface
*/ */
private function writeParams(ResponseInterface $proxy, object $response, object $request): void private function writeParams(ResponseInterface $proxy, object $response, object $request): void
{ {
/** @var \Swoole\Http\Response $response */
$response->setStatusCode($proxy->getStatusCode()); $response->setStatusCode($proxy->getStatusCode());
$headers = $proxy->getHeaders(); $headers = $proxy->getHeaders();
if (count($headers) > 0) foreach ($headers as $name => $header) { if (count($headers) > 0) foreach ($headers as $name => $header) {
@@ -79,9 +76,9 @@ class SwooleHttpResponseEmitter implements ResponseEmitterInterface
if (count($cookieParams) > 0) foreach ($cookieParams as $cookie) { if (count($cookieParams) > 0) foreach ($cookieParams as $cookie) {
$response->setCookie(...$cookie); $response->setCookie(...$cookie);
} }
$response->header('Run-Time', $this->getRunTime($request)); $response->header('Run-Time', $this->getRunTime($request) . '');
$response->header('Server', 'swoole'); $response->header('Server', 'swoole');
$response->header('Swoole-Version', \swoole_version()); $response->header('Swoole-Version', swoole_version());
} }
+1 -11
View File
@@ -7,22 +7,12 @@ use Kiri\Di\Interface\ResponseEmitterInterface;
use Kiri\Events\EventDispatch; use Kiri\Events\EventDispatch;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Server\Events\OnAfterRequest; use Kiri\Server\Events\OnAfterRequest;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use ReflectionException;
use SplPriorityQueue; use SplPriorityQueue;
class SwowHttpResponseEmitter implements ResponseEmitterInterface class SwowHttpResponseEmitter implements ResponseEmitterInterface
{ {
/**
* @var EventProvider
*/
#[Container(EventProvider::class)]
public EventProvider $provider;
/** /**
* @var EventDispatch * @var EventDispatch
*/ */
@@ -48,7 +38,7 @@ class SwowHttpResponseEmitter implements ResponseEmitterInterface
public function init(): void public function init(): void
{ {
$this->afterRequest = new OnAfterRequest(); $this->afterRequest = new OnAfterRequest();
$this->events = $this->provider->getListenersForEvent($this->afterRequest); $this->events = di(EventProvider::class)->getListenersForEvent($this->afterRequest);
} }
+1 -3
View File
@@ -54,9 +54,7 @@ class BindForm implements InjectParameterInterface
} }
} }
$middleware = \instance(ValidatorMiddleware::class); Middleware::setValidator($class, $method, $validator);
$middleware->validator = $validator;
Middleware::set($class, $method, $middleware);
return $validator->getFormData(); return $validator->getFormData();
} }
+4 -1
View File
@@ -64,6 +64,9 @@ class Binding implements RequestFilterInterface
{ {
// TODO: Implement dispatch() method. // TODO: Implement dispatch() method.
$array = []; $array = [];
if (count($this->rules) < 1) {
return $array;
}
foreach ($this->rules as $key => $rule) { foreach ($this->rules as $key => $rule) {
if (is_string($key)) { if (is_string($key)) {
$array[] = $this->getValidator($key, $rule); $array[] = $this->getValidator($key, $rule);
@@ -91,7 +94,7 @@ class Binding implements RequestFilterInterface
if (is_numeric($key)) { if (is_numeric($key)) {
$class = self::TYPES[$rule]; $class = self::TYPES[$rule];
} else { } else {
$class = array_merge(self::TYPES[$key], ['value' => $rule, 'field' => $key]); $class = array_merge(self::TYPES[$key], ['value' => $rule, 'field' => $key]);
} }
$isFirst = false; $isFirst = false;
if ($class['class'] === RequiredValidatorFilter::class) { if ($class['class'] === RequiredValidatorFilter::class) {
+3 -1
View File
@@ -3,7 +3,9 @@
namespace Kiri\Router\Validator; namespace Kiri\Router\Validator;
#[\Attribute(\Attribute::TARGET_PROPERTY)] use Attribute;
#[Attribute(Attribute::TARGET_PROPERTY)]
class Ignoring class Ignoring
{ {
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class BetweenValidatorFilter extends ValidatorFilter class BetweenValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class InValidatorFilter extends ValidatorFilter class InValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class LengthValidatorFilter extends ValidatorFilter class LengthValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class MaxLengthValidatorFilter extends ValidatorFilter class MaxLengthValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class MaxValidatorFilter extends ValidatorFilter class MaxValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class MinLengthValidatorFilter extends ValidatorFilter class MinLengthValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class MinValidatorFilter extends ValidatorFilter class MinValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class MustValidatorFilter extends ValidatorFilter class MustValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class NotBetweenValidatorFilter extends ValidatorFilter class NotBetweenValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class NotInValidatorFilter extends ValidatorFilter class NotInValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
@@ -6,6 +6,8 @@ namespace Kiri\Router\Validator\RequestFilter;
class PhoneValidatorFilter extends ValidatorFilter class PhoneValidatorFilter extends ValidatorFilter
{ {
const string REG = '/^1[356789]\d{9}$/'; const string REG = '/^1[356789]\d{9}$/';
@@ -5,6 +5,7 @@ namespace Kiri\Router\Validator\RequestFilter;
class RoundValidatorFilter extends ValidatorFilter class RoundValidatorFilter extends ValidatorFilter
{ {
/** /**
* @param mixed $value * @param mixed $value
* @return bool * @return bool
+4 -4
View File
@@ -15,11 +15,11 @@ class ArrayProxy extends TypesProxy
*/ */
public function dispatch(object $form, string $field, mixed $value): bool public function dispatch(object $form, string $field, mixed $value): bool
{ {
if (is_null($value)) { if (empty($value)) {
$form->{$field} = !$this->allowsNull ? [] : null; return ($form->{$field} = []) === [];
return true; } else {
return $value == ($form->{$field} = $value);
} }
return $value == ($form->{$field} = $value);
} }
} }
+3
View File
@@ -91,6 +91,9 @@ class Validator
*/ */
public function addRule(string $name, array $rule): void public function addRule(string $name, array $rule): void
{ {
if (count($rule) < 1) {
return;
}
if (!isset($this->rules[$name])) { if (!isset($this->rules[$name])) {
$this->rules[$name] = []; $this->rules[$name] = [];
} }
+15 -11
View File
@@ -3,7 +3,8 @@ declare(strict_types=1);
namespace Kiri\Router\Validator; namespace Kiri\Router\Validator;
use Kiri\Di\Inject\Container; use Kiri;
use Kiri\Router\Base\Middleware;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\MiddlewareInterface;
@@ -16,14 +17,14 @@ class ValidatorMiddleware implements MiddlewareInterface
{ {
public Validator $validator; /**
* @param ResponseInterface $response
* @param string $class
/** * @param string $method
* @var ResponseInterface */
*/ public function __construct(public ResponseInterface $response ,public string $class, public string $method)
#[Container(ResponseInterface::class)] {
public ResponseInterface $response; }
/** /**
@@ -34,8 +35,11 @@ class ValidatorMiddleware implements MiddlewareInterface
*/ */
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{ {
if (!$this->validator->run($request)) { $validator = Middleware::getValidator($this->class, $this->method);
return $this->response->html($this->validator->error(), 415); if (!$validator->run($request)) {
Kiri::getLogger()->println($request->getUri()->getPath() . ' `' . $validator->error() . '`');
return $this->response->html($validator->error(), 415);
} else { } else {
return $handler->handle($request); return $handler->handle($request);
} }