diff --git a/src/Constrict/ConstrictResponse.php b/src/Constrict/ConstrictResponse.php index 2bdb31f..397b82d 100644 --- a/src/Constrict/ConstrictResponse.php +++ b/src/Constrict/ConstrictResponse.php @@ -71,6 +71,19 @@ class ConstrictResponse extends Message implements ResponseInterface } + /** + * @param string $content + * @param int $statusCode + * @param ContentType $contentType + * @return $this + */ + public function raw(string $content, int $statusCode = 200, ContentType $contentType = ContentType::JSON): static + { + $this->getBody()->write($content); + return $this->withContentType($contentType)->withStatus($statusCode); + } + + /** * @param string $content * @param int $statusCode diff --git a/src/ControllerInterpreter.php b/src/ControllerInterpreter.php index 87de649..4643df2 100644 --- a/src/ControllerInterpreter.php +++ b/src/ControllerInterpreter.php @@ -73,8 +73,12 @@ class ControllerInterpreter */ public function resolveMethod(object $class, string|\ReflectionMethod $reflectionMethod, ReflectionClass $reflectionClass): Handler { + $returnType = $reflectionMethod->getReturnType(); + if ($returnType instanceof \ReflectionUnionType) { + throw new Exception("Return type error, cannot be multi type."); + } if (empty($reflectionMethod)) { - return new Handler([$class, $reflectionMethod], [], $reflectionMethod->getReturnType()); + return new Handler([$class, $reflectionMethod], [], $returnType); } if (is_string($reflectionMethod)) { $reflectionMethod = $reflectionClass->getMethod($reflectionMethod); @@ -83,7 +87,7 @@ class ControllerInterpreter $container = \Kiri::getDi(); $parameters = $container->getMethodParams($reflectionMethod); - return new Handler([$class, $reflectionMethod->getName()], $parameters, $reflectionMethod->getReturnType()); + return new Handler([$class, $reflectionMethod->getName()], $parameters, $returnType); } } diff --git a/src/Format/ArrayFormat.php b/src/Format/ArrayFormat.php new file mode 100644 index 0000000..d645777 --- /dev/null +++ b/src/Format/ArrayFormat.php @@ -0,0 +1,26 @@ +withContentType(ContentType::JSON) + ->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE))); + } + + +} \ No newline at end of file diff --git a/src/Format/IFormat.php b/src/Format/IFormat.php new file mode 100644 index 0000000..cdc2820 --- /dev/null +++ b/src/Format/IFormat.php @@ -0,0 +1,16 @@ +withBody(new Stream('[object]')); + } + if (is_array($result)) { + return \response()->withContentType(ContentType::JSON)->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE))); + } else { + return \response()->withBody(new Stream($result)); + } + } + + +} \ No newline at end of file diff --git a/src/Format/OtherFormat.php b/src/Format/OtherFormat.php new file mode 100644 index 0000000..92d55dc --- /dev/null +++ b/src/Format/OtherFormat.php @@ -0,0 +1,23 @@ +withBody(new Stream($result)); + } + + +} \ No newline at end of file diff --git a/src/Format/ResponseFormat.php b/src/Format/ResponseFormat.php new file mode 100644 index 0000000..29110d1 --- /dev/null +++ b/src/Format/ResponseFormat.php @@ -0,0 +1,18 @@ + ArrayFormat::class, + 'mixed' => MixedFormat::class, + 'object' => MixedFormat::class, + 'int' => OtherFormat::class, + 'string' => OtherFormat::class, + 'bool' => OtherFormat::class, + 'void' => VoidFormat::class, + ]; + + + /** + * @var IFormat + */ + protected IFormat $format; + + /** * @param array|Closure $handler * @param array $parameter - * @param ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $responseType + * @param ReflectionNamedType $reflectionType + * @throws ReflectionException */ - public function __construct(public array|Closure $handler, public array $parameter, public ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $responseType) + public function __construct(public array|Closure $handler, public array $parameter, public ReflectionNamedType $reflectionType) { + $this->format = di($this->reflectionType->getName()); } @@ -79,32 +106,9 @@ class Handler implements RequestHandlerInterface */ public function handle(ServerRequestInterface $request): ResponseInterface { - // TODO: Implement handle() method. - if ($this->responseType->getName() !== 'void') { - return $this->typeEncode(); - } - call_user_func($this->handler, ...$this->parameter); - return \response(); - } + $data = call_user_func($this->handler, ...$this->parameter); - - /** - * @return ResponseInterface - */ - protected function typeEncode(): ResponseInterface - { - $result = call_user_func($this->handler, ...$this->parameter); - if ($result instanceof ResponseInterface) { - return $result; - } - if (is_object($result)) { - return \response()->withBody(new Stream('[object]')); - } - if (is_array($result)) { - return \response()->withContentType(ContentType::JSON)->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE))); - } else { - return \response()->withBody(new Stream($result)); - } + return call_user_func([$this->format, 'call'], $data); } } diff --git a/src/Response.php b/src/Response.php index beb10d9..d6fa3ab 100644 --- a/src/Response.php +++ b/src/Response.php @@ -390,6 +390,18 @@ class Response implements ResponseInterface return $this->__call__(__FUNCTION__); } + + /** + * @param string $content + * @param int $statusCode + * @param ContentType $contentType + * @return ResponseInterface + */ + public function raw(string $content, int $statusCode = 200, ContentType $contentType = ContentType::JSON): ResponseInterface + { + return $this->__call__(__FUNCTION__, $content, $statusCode, $contentType); + } + /** * Return an instance with the specified status code and, optionally, reason phrase. * diff --git a/src/SwooleHttpResponseEmitter.php b/src/SwooleHttpResponseEmitter.php index e2c3c70..21a0cd6 100644 --- a/src/SwooleHttpResponseEmitter.php +++ b/src/SwooleHttpResponseEmitter.php @@ -19,43 +19,58 @@ class SwooleHttpResponseEmitter implements ResponseEmitterInterface /** * @param Response $proxy * @param object $response + * @param object $request * @return void * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws ReflectionException */ - public function sender(ResponseInterface $proxy, object $response): void - { - // TODO: Implement sender() method. - $this->writeParams($proxy, $response); + public function sender(ResponseInterface $proxy, object $response, object $request): void + { + // TODO: Implement sender() method. + $this->writeParams($proxy, $response, $request); - $proxy->end($response); + $proxy->end($response); event(new OnAfterRequest()); } - /** - * @param Response $proxy - * @param object $response - * @return void - */ - private function writeParams(ResponseInterface $proxy, object $response): void - { - $response->setStatusCode($proxy->getStatusCode()); - foreach ($proxy->getHeaders() as $name => $header) { - $response->header($name, $header); - } - foreach ($proxy->getCookieParams() as $cookie) { - $response->setCookie(...$cookie); - } + /** + * @param Response $proxy + * @param object $response + * @param object $request + * @return void + */ + private function writeParams(ResponseInterface $proxy, object $response, object $request): void + { + $response->setStatusCode($proxy->getStatusCode()); + $headers = $proxy->getHeaders(); + if (count($headers) < 1) { + foreach ($headers as $name => $header) { + $response->header($name, $header); + } + } + $cookieParams = $proxy->getCookieParams(); + if (count($cookieParams) < 1) { + foreach ($cookieParams as $cookie) { + $response->setCookie(...$cookie); + } + } + $response->header('Run-Time', $this->getRunTime($request)); + $response->header('Server', 'swoole'); + $response->header('Swoole-Version', swoole_version()); + } - $request = \request(); - $response->header('Run-Time', microtime(true) - +$request->getServerParam('request_time_float')); - $response->header('Server', 'swoole'); - $response->header('Swoole-Version', swoole_version()); - } + /** + * @param object $request + * @return float + */ + protected function getRunTime(object $request): float + { + return microtime(true) - +$request->getServerParam('request_time_float'); + } } diff --git a/src/SwowHttpResponseEmitter.php b/src/SwowHttpResponseEmitter.php index c70ab27..3dda415 100644 --- a/src/SwowHttpResponseEmitter.php +++ b/src/SwowHttpResponseEmitter.php @@ -16,18 +16,30 @@ class SwowHttpResponseEmitter implements ResponseEmitterInterface /** * @param Response $proxy * @param object $response + * @param object $request * @return void * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws ReflectionException */ - public function sender(ResponseInterface $proxy, object $response): void + public function sender(ResponseInterface $proxy, object $response, object $request): void { // TODO: Implement sender() method. $proxy->withHeader('Server', 'Swow'); - $response->sendHttpResponse($proxy); + $proxy->withHeader('Run-Time', $this->getRunTime($request)); + $response->sendHttpResponse($proxy); event(new OnAfterRequest()); } + + /** + * @param object $request + * @return float + */ + protected function getRunTime(object $request): float + { + return microtime(true) - +$request->getServerParam('request_time_float'); + } + }