method = $method; $this->uri = Uri::from($uri); $this->stream = $stream ?? Stream::fromMemory(); $this->setHeaders($headers ); } public function getRequestTarget(): string { if ( isset($this->target) ) { return $this->target; } $query = $this->uri->getQuery() ?: null; $target = $this->uri->getPath() . ( $query ? "?{$query}" : "" ); return $target ?: '/'; } public function withRequestTarget($requestTarget) { return (clone $this)->setRequestTarget($requestTarget); } public function setRequestTarget(string $target) : static { $this->target = $target; return $this; } public function getMethod() { return $this->method->value; } public function withMethod($method) { return (clone $this)->setMethod($method); } protected function setMethod(string $method) : static { $this->method = MethodEnum::from($method); return $this; } public function getUri() : UriInterface { return $this->uri; } public function withUri(UriInterface $uri, $preserveHost = false) { return (clone $this)->setUri($uri, $preserveHost); } protected function setUri(UriInterface|string $uri, bool $preserveHost = false) : static { $this->uri = Uri::from($uri); if ( ! $preserveHost || ! $this->hasHeader('Host') ) { $this->headers['Host'] = [ $this->renderHostHeader() ]; } return $this; } protected function renderHostHeader(UriInterface $fromUri = null) : string { $fromUri ??= $this->uri; $port = $fromUri->getPort(); return implode('', [ $fromUri->getHost(), $port && ! in_array($port, Uri::IGNORE_HTTP_PORT) ? ":{$port}" : "" ]); } public function withQueryParams(array $query) : static { return (clone $this)->addQueryParams($query); } protected function addQueryParams(array $query) : static { $rebuilt = http_build_query(array_merge($this->getQueryParams(), $query), "", null, PHP_QUERY_RFC3986); $this->getUri()->withQuery($rebuilt); return $this; } public function getServerParams() : array { return []; } public function getCookieParams() : array { return $this->cookies; } public function withCookieParams(array $cookies) : static { return (clone $this)->setCookies($cookies); } protected function setCookies(array $cookies) : static { $this->cookies = $cookies; return $this; } public function getQueryParams() : array { parse_str($this->getUri()->getQuery(), $query); return $query; } public function getUploadedFiles() : array { return $this->files; } public function withUploadedFiles(array $uploadedFiles) : static { return (clone $this)->setUploadedFiles($uploadedFiles); } protected function setUploadedFiles(array $uploadedFiles) : static { $this->files = $uploadedFiles; return $this; } public function getParsedBody() : null|array|object { $raw = $this->getBody()->getContents(); $contentType = $this->getHeader('Content-Type')[0] ?? "application/x-www-form-urlencoded"; switch($contentType) { case "application/x-www-form-urlencoded": parse_str($raw, $result); return $result; case "multipart/form-data": return []; case "application/json": return JsonStream::fromJsonEncoded( $raw )->decode(); } return [ sprintf("Unsupported content type: %s", $contentType) ]; } public function withParsedBody(mixed $data) : static { return (clone $this)->setBody( JsonStream::fromContent($data) ); } public function getAttributes() : array { // TODO: Implement getAttributes() method. } public function getAttribute($name, $default = null) : mixed { // TODO: Implement getAttribute() method. } public function withAttribute($name, $value) : static { // TODO: Implement withAttribute() method. } public function withoutAttribute($name): static { // TODO: Implement withoutAttribute() method. } }