上一回讲到给Server增加了10个swoole监听事件.在增加完swoole的事件后,框架调用Swoft的trigger()办法触发了几种用户注册的生命周期事件.接着框架调用server的start()办法,正式开始承受用户申请.
本章将从onRequest事件着手,逐渐剖析Swoole原生的Request及Response封装成Swoft中应用的Swoft\Http\Message\Request和Swoft\Http\Message\Response的过程.
先看onRequest代码:
public function onRequest(Request $request, Response $response): void{ $psrRequest = ServerRequest::new($request); $psrResponse = ServerResponse::new($response); $this->dispatcher->dispatch($psrRequest, $psrResponse);}
此办法是swoole的onRequest回调函数,所以参数传进来的Request和Response别离对应的类型是Swoole\Http\Request
和Swoole\Http\Response
.
能够看到,在收到参数后,框架干的第一件事就是调用Swoft\Http\Message\Request
和Swoft\Http\Message\Response
的new办法,生成与之对应的合乎psr标准的对象.
接着,框架将新生成的request和response对象作为参数传递给调度函数,由调度函数去执行具体的业务逻辑并返回后果给客户端.
实现细节之(Swoft\Http\Message\Request::new
):
此办法以及外面用到的Uri::new办法都是获取PROTOTYPE模式的bean
public static function new(CoRequest $coRequest): self{ //此处获取的bean是一个新的对象,因为以后类的bean注解 //为PROTOTYPE模式 //@Bean(name="httpRequest", scope=Bean::PROTOTYPE) /** @var Request $self */ $self = BeanFactory::getBean('httpRequest'); // Server params // 获取Swoole原生Request对象的server参数 $serverParams = $coRequest->server; // 将Swoole原生Request对象中的header设置到新获取的bean对象上 // Set headers $self->initializeHeaders($headers = $coRequest->header ?: []); // 设置申请形式 $self->method = $serverParams['request_method'] ?? ''; // 绑定原生Request对象到新的bean对象上 $self->coRequest = $coRequest; // 设置GET申请参数 $self->queryParams = $coRequest->get ?: []; // 设置COOKIE $self->cookieParams = $coRequest->cookie ?: []; // 设置SERVER参数 $self->serverParams = $serverParams; // 将申请的URI设置为requestTarget $self->requestTarget = $serverParams['request_uri'] ?? ''; // 设置URI // Save $self->uriPath = $serverParams['request_uri'] ?? ''; // 设置QUERY_STRING $self->uriQuery = $serverParams['query_string'] ?? ''; // 如果URI中还蕴含?号,阐明还须要解决 if (strpos($self->uriPath, '?') !== false) { // Split $parts = explode('?', $self->uriPath, 2); $self->uriPath = $parts[0]; $self->uriQuery = $parts[1] ?? $self->uriQuery; } // 调用Uri类结构Uri对象并绑定给新的bean对象 /** @var Uri $uri */ $self->uri = Uri::new('', [ 'host' => $headers['host'] ?? '', 'path' => $self->uriPath, 'query' => $self->uriQuery, 'https' => $serverParams['https'] ?? '', 'http_host' => $serverParams['http_host'] ?? '', 'server_name' => $serverParams['server_name'] ?? '', 'server_addr' => $serverParams['server_addr'] ?? '', 'server_port' => $serverParams['server_port'] ?? '', ]); // 如果以后headers外面没有host数据,则通过Uri对象去更新 // // Update host by Uri info if (!isset($headers['host'])) { $self->updateHostByUri(); } return $self;}
Uri::new的实现:
public static function new(string $uri = '', array $params = []): self{ /** @var Uri $instance */ $instance = Swoft::getBean(self::class); // Save some params $instance->params = $params; // Weak type check to also accept null until we can add scalar type hints if ($uri === '') { return $instance; } // If params is empty, padding defaults data if (!$params) { $instance->params = self::DEFAULT_PARAMS; } $parts = parse_url($uri); if ($parts === false) { throw new InvalidArgumentException("Unable to parse URI: $uri"); } $instance->applyParts($parts); return $instance;}
实现细节之(Swoft\Http\Message\Response::new
):
此办法依然是获取PROTOTYPE模式的bean,申请初期只是很单纯的设置了是否发送的状态以及绑定原生Response对象,并未做过多设置.
public static function new(CoResponse $coResponse): self{ /** @var Response $self */ $self = BeanFactory::getBean('httpResponse'); // $self = bean('httpResponse'); $self->sent = false; $self->coResponse = $coResponse; return $self;}