mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Support swow psr7-plus interface for http-message
. (#5828)
This commit is contained in:
parent
ebbf469e9b
commit
6bdb3863f4
@ -16,6 +16,7 @@
|
||||
|
||||
- [ ] Support v2 and v3 for socketio-server.
|
||||
- [ ] Support [Psr7Plus](https://github.com/swow/psr7-plus).
|
||||
- [#5828](https://github.com/hyperf/hyperf/pull/5828) Support swow psr7-plus interface for `http-message`.
|
||||
- [x] Support [pest](https://github.com/pestphp/pest).
|
||||
- [x] Added `hyperf/helper` component.
|
||||
- [#5815](https://github.com/hyperf/hyperf/pull/5815) Added alias as `mysql` for `pdo` in `hyperf/db`.
|
||||
|
@ -79,6 +79,7 @@
|
||||
"smarty/smarty": "^3.1",
|
||||
"squizlabs/php_codesniffer": "^3.4",
|
||||
"swoole/ide-helper": "dev-master",
|
||||
"swow/psr7-plus": "^1.0",
|
||||
"swow/swow": "^1.0",
|
||||
"sy-records/think-template": "^2.0",
|
||||
"symfony/console": "^5.0|^6.0",
|
||||
|
@ -16,7 +16,8 @@
|
||||
"hyperf/support": "~3.1.0",
|
||||
"hyperf/utils": "~3.1.0",
|
||||
"laminas/laminas-mime": "^2.7",
|
||||
"psr/http-message": "^1.0|^2.0"
|
||||
"psr/http-message": "^1.0|^2.0",
|
||||
"swow/psr7-plus": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/container": "Required to replace RequestParserInterface."
|
||||
|
@ -55,7 +55,7 @@ trait MessageTrait
|
||||
*
|
||||
* @param string $version HTTP protocol version
|
||||
*/
|
||||
public function withProtocolVersion($version): static
|
||||
public function withProtocolVersion(mixed $version): static
|
||||
{
|
||||
if ($this->protocol === $version) {
|
||||
return $this;
|
||||
@ -100,7 +100,7 @@ trait MessageTrait
|
||||
* name using a case-insensitive string comparison. Returns false if
|
||||
* no matching header name is found in the message.
|
||||
*/
|
||||
public function hasHeader($name): bool
|
||||
public function hasHeader(mixed $name): bool
|
||||
{
|
||||
return isset($this->headerNames[strtolower($name)]);
|
||||
}
|
||||
@ -117,7 +117,7 @@ trait MessageTrait
|
||||
* header. If the header does not appear in the message, this method MUST
|
||||
* return an empty array.
|
||||
*/
|
||||
public function getHeader($name): array
|
||||
public function getHeader(mixed $name): array
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
@ -146,7 +146,7 @@ trait MessageTrait
|
||||
* concatenated together using a comma. If the header does not appear in
|
||||
* the message, this method MUST return an empty string.
|
||||
*/
|
||||
public function getHeaderLine($name): string
|
||||
public function getHeaderLine(mixed $name): string
|
||||
{
|
||||
return implode(', ', $this->getHeader($name));
|
||||
}
|
||||
@ -163,7 +163,7 @@ trait MessageTrait
|
||||
* @param string|string[] $value header value(s)
|
||||
* @throws InvalidArgumentException for invalid header names or values
|
||||
*/
|
||||
public function withHeader($name, $value): static
|
||||
public function withHeader(mixed $name, mixed $value): static
|
||||
{
|
||||
if (! is_array($value)) {
|
||||
$value = [$value];
|
||||
@ -204,7 +204,7 @@ trait MessageTrait
|
||||
* @param string|string[] $value header value(s)
|
||||
* @throws InvalidArgumentException for invalid header names or values
|
||||
*/
|
||||
public function withAddedHeader($name, $value): static
|
||||
public function withAddedHeader(mixed $name, mixed $value): static
|
||||
{
|
||||
if (! is_array($value)) {
|
||||
$value = [$value];
|
||||
@ -234,7 +234,7 @@ trait MessageTrait
|
||||
*
|
||||
* @param string $name case-insensitive header field name to remove
|
||||
*/
|
||||
public function withoutHeader($name): static
|
||||
public function withoutHeader(mixed $name): static
|
||||
{
|
||||
$normalized = strtolower($name);
|
||||
|
||||
@ -324,7 +324,92 @@ trait MessageTrait
|
||||
}
|
||||
}
|
||||
|
||||
private function setHeaders(array $headers): static
|
||||
public function setProtocolVersion(string $version): static
|
||||
{
|
||||
$this->protocol = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHeader(string $name, mixed $value): static
|
||||
{
|
||||
if (! is_array($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
|
||||
$value = $this->trimHeaderValues($value);
|
||||
$normalized = strtolower($name);
|
||||
|
||||
if (isset($this->headerNames[$normalized])) {
|
||||
unset($this->headers[$this->headerNames[$normalized]]);
|
||||
}
|
||||
$this->headerNames[$normalized] = $name;
|
||||
$this->headers[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addHeader(string $name, mixed $value): static
|
||||
{
|
||||
if (! is_array($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
|
||||
$value = $this->trimHeaderValues($value);
|
||||
$normalized = strtolower($name);
|
||||
|
||||
if (isset($this->headerNames[$normalized])) {
|
||||
$name = $this->headerNames[$normalized];
|
||||
$this->headers[$name] = array_merge($this->headers[$name], $value);
|
||||
} else {
|
||||
$this->headerNames[$normalized] = $name;
|
||||
$this->headers[$name] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unsetHeader(string $name): static
|
||||
{
|
||||
$normalized = strtolower($name);
|
||||
|
||||
if (! isset($this->headerNames[$normalized])) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$name = $this->headerNames[$normalized];
|
||||
|
||||
unset($this->headers[$name], $this->headerNames[$normalized]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStandardHeaders(): array
|
||||
{
|
||||
$headers = $this->getHeaders();
|
||||
if (! $this->hasHeader('connection')) {
|
||||
$headers['Connection'] = [$this->shouldKeepAlive() ? 'keep-alive' : 'close'];
|
||||
}
|
||||
if (! $this->hasHeader('content-length')) {
|
||||
$headers['Content-Length'] = [(string) ($this->getBody()->getSize() ?? 0)];
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
public function shouldKeepAlive(): bool
|
||||
{
|
||||
return strtolower($this->getHeaderLine('Connection')) === 'keep-alive';
|
||||
}
|
||||
|
||||
public function setBody(StreamInterface $body): static
|
||||
{
|
||||
$this->stream = $body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, array<string>|string> $headers
|
||||
*/
|
||||
public function setHeaders(array $headers): static
|
||||
{
|
||||
$this->headerNames = $this->headers = [];
|
||||
foreach ($headers as $header => $value) {
|
||||
|
@ -17,8 +17,9 @@ use InvalidArgumentException;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Swow\Psr7\Message\RequestPlusInterface;
|
||||
|
||||
class Request implements RequestInterface
|
||||
class Request implements RequestInterface, RequestPlusInterface
|
||||
{
|
||||
use MessageTrait;
|
||||
|
||||
@ -62,6 +63,11 @@ class Request implements RequestInterface
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the message's request target.
|
||||
* Retrieves the message's request-target either as it will appear (for
|
||||
@ -102,9 +108,9 @@ class Request implements RequestInterface
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
|
||||
* request-target forms allowed in request messages)
|
||||
* @param mixed $requestTarget
|
||||
* @param string $requestTarget
|
||||
*/
|
||||
public function withRequestTarget($requestTarget): static
|
||||
public function withRequestTarget(mixed $requestTarget): static
|
||||
{
|
||||
if (preg_match('#\s#', $requestTarget)) {
|
||||
throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
|
||||
@ -137,7 +143,7 @@ class Request implements RequestInterface
|
||||
* @param string $method case-sensitive method
|
||||
* @throws InvalidArgumentException for invalid HTTP methods
|
||||
*/
|
||||
public function withMethod($method): static
|
||||
public function withMethod(mixed $method): static
|
||||
{
|
||||
$method = strtoupper($method);
|
||||
$methods = ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'HEAD'];
|
||||
@ -203,6 +209,58 @@ class Request implements RequestInterface
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function setMethod(string $method): static
|
||||
{
|
||||
$method = strtoupper($method);
|
||||
$methods = ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'HEAD'];
|
||||
if (! in_array($method, $methods)) {
|
||||
throw new InvalidArgumentException('Invalid Method');
|
||||
}
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUri(UriInterface|string $uri, ?bool $preserveHost = null): static
|
||||
{
|
||||
$this->uri = $uri;
|
||||
|
||||
if (! $preserveHost) {
|
||||
$this->updateHostFromUri();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRequestTarget(string $requestTarget): static
|
||||
{
|
||||
if (preg_match('#\s#', $requestTarget)) {
|
||||
throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
|
||||
}
|
||||
|
||||
$this->requestTarget = $requestTarget;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toString(bool $withoutBody = false): string
|
||||
{
|
||||
$headerString = '';
|
||||
if (! $withoutBody) {
|
||||
foreach ($this->getStandardHeaders() as $key => $values) {
|
||||
foreach ($values as $value) {
|
||||
$headerString .= sprintf("%s: %s\r\n", $key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sprintf(
|
||||
"%s %s HTTP/%s\r\n%s\r\n%s",
|
||||
$this->getMethod(),
|
||||
$this->getUri()->getPath(),
|
||||
$this->getProtocolVersion(),
|
||||
$headerString,
|
||||
$this->getBody()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Host Header according to Uri.
|
||||
*
|
||||
|
@ -13,8 +13,9 @@ namespace Hyperf\HttpMessage\Base;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Swow\Psr7\Message\ResponsePlusInterface;
|
||||
|
||||
class Response implements ResponseInterface
|
||||
class Response implements ResponseInterface, ResponsePlusInterface
|
||||
{
|
||||
use MessageTrait;
|
||||
|
||||
@ -122,10 +123,9 @@ class Response implements ResponseInterface
|
||||
*
|
||||
* @param string $name the attribute name
|
||||
* @param mixed $default default value to return if the attribute does not exist
|
||||
* @return mixed
|
||||
* @see getAttributes()
|
||||
*/
|
||||
public function getAttribute($name, $default = null)
|
||||
public function getAttribute(string $name, mixed $default = null): mixed
|
||||
{
|
||||
return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
@ -142,7 +142,7 @@ class Response implements ResponseInterface
|
||||
* @param mixed $value the value of the attribute
|
||||
* @see getAttributes()
|
||||
*/
|
||||
public function withAttribute($name, $value): static
|
||||
public function withAttribute(string $name, mixed $value): static
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->attributes[$name] = $value;
|
||||
@ -331,4 +331,32 @@ class Response implements ResponseInterface
|
||||
{
|
||||
return in_array($this->statusCode, [204, 304]);
|
||||
}
|
||||
|
||||
public function toString(bool $withoutBody = false): string
|
||||
{
|
||||
$headerString = '';
|
||||
foreach ($this->getStandardHeaders() as $key => $values) {
|
||||
foreach ($values as $value) {
|
||||
$headerString .= sprintf("%s: %s\r\n", $key, $value);
|
||||
}
|
||||
}
|
||||
return sprintf(
|
||||
"HTTP/%s %s %s\r\n%s\r\n%s",
|
||||
$this->getProtocolVersion(),
|
||||
$this->getStatusCode(),
|
||||
$this->getReasonPhrase(),
|
||||
$headerString,
|
||||
$this->getBody()
|
||||
);
|
||||
}
|
||||
|
||||
public function setStatus(int $code, string $reasonPhrase = ''): static
|
||||
{
|
||||
$this->statusCode = $code;
|
||||
if (! $reasonPhrase && isset(self::$phrases[$code])) {
|
||||
$reasonPhrase = self::$phrases[$code];
|
||||
}
|
||||
$this->reasonPhrase = $reasonPhrase;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,9 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Swoole;
|
||||
use Swow\Psr7\Message\ServerRequestPlusInterface;
|
||||
|
||||
class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestInterface
|
||||
class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestInterface, ServerRequestPlusInterface
|
||||
{
|
||||
protected ?Swoole\Http\Request $swooleRequest = null;
|
||||
|
||||
@ -221,7 +222,7 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI
|
||||
* @return null|array|object The deserialized body parameters, if any.
|
||||
* These will typically be an array or object.
|
||||
*/
|
||||
public function getParsedBody()
|
||||
public function getParsedBody(): array|object|null
|
||||
{
|
||||
return $this->parsedBody;
|
||||
}
|
||||
@ -315,10 +316,9 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI
|
||||
*
|
||||
* @param string $name the attribute name
|
||||
* @param mixed $default default value to return if the attribute does not exist
|
||||
* @return mixed
|
||||
* @see getAttributes()
|
||||
*/
|
||||
public function getAttribute($name, $default = null)
|
||||
public function getAttribute(mixed $name, mixed $default = null): mixed
|
||||
{
|
||||
return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
@ -335,7 +335,7 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI
|
||||
* @param mixed $value the value of the attribute
|
||||
* @see getAttributes()
|
||||
*/
|
||||
public function withAttribute($name, $value): static
|
||||
public function withAttribute(mixed $name, mixed $value): static
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->attributes[$name] = $value;
|
||||
@ -417,6 +417,53 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setServerParams(array $serverParams): static
|
||||
{
|
||||
$this->serverParams = $serverParams;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setQueryParams(array $query): static
|
||||
{
|
||||
$this->queryParams = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCookieParams(array $cookies): static
|
||||
{
|
||||
$this->cookieParams = $cookies;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setParsedBody(object|array|null $data): static
|
||||
{
|
||||
$this->parsedBody = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUploadedFiles(array $uploadedFiles): static
|
||||
{
|
||||
$this->uploadedFiles = $uploadedFiles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAttribute(string $name, mixed $value): static
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unsetAttribute(string $name): static
|
||||
{
|
||||
if (array_key_exists($name, $this->attributes) === false) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
unset($this->attributes[$name]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected static function normalizeParsedBody(array $data = [], ?RequestInterface $request = null): array
|
||||
{
|
||||
if (! $request) {
|
||||
|
@ -59,7 +59,7 @@ class Response extends \Hyperf\HttpMessage\Base\Response implements Chunkable
|
||||
* Returns an instance with specified trailer.
|
||||
* @param string $value
|
||||
*/
|
||||
public function withTrailer(string $key, $value): static
|
||||
public function withTrailer(string $key, mixed $value): static
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->trailers[$key] = $value;
|
||||
|
@ -14,8 +14,9 @@ namespace Hyperf\HttpMessage\Uri;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Stringable;
|
||||
use Swow\Psr7\Message\UriPlusInterface;
|
||||
|
||||
class Uri implements UriInterface, Stringable
|
||||
class Uri implements UriInterface, Stringable, UriPlusInterface
|
||||
{
|
||||
/**
|
||||
* Absolute http and https URIs require a host per RFC 7230 Section 2.7
|
||||
@ -71,6 +72,9 @@ class Uri implements UriInterface, Stringable
|
||||
*/
|
||||
private string $fragment = '';
|
||||
|
||||
/** @var null|array<string, string> */
|
||||
private ?array $queryParams = null;
|
||||
|
||||
/**
|
||||
* @param string $uri URI to parse
|
||||
*/
|
||||
@ -149,13 +153,19 @@ class Uri implements UriInterface, Stringable
|
||||
*/
|
||||
public function getAuthority(): string
|
||||
{
|
||||
if ($this->host === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$authority = $this->host;
|
||||
if ($this->userInfo !== '') {
|
||||
$authority = $this->userInfo . '@' . $authority;
|
||||
}
|
||||
|
||||
if ($this->port !== null) {
|
||||
$authority .= ':' . $this->port;
|
||||
}
|
||||
|
||||
return $authority;
|
||||
}
|
||||
|
||||
@ -284,7 +294,7 @@ class Uri implements UriInterface, Stringable
|
||||
* @return static a new instance with the specified scheme
|
||||
* @throws InvalidArgumentException for invalid or unsupported schemes
|
||||
*/
|
||||
public function withScheme($scheme): static
|
||||
public function withScheme(mixed $scheme): static
|
||||
{
|
||||
$scheme = $this->filterScheme($scheme);
|
||||
if ($this->scheme === $scheme) {
|
||||
@ -310,7 +320,7 @@ class Uri implements UriInterface, Stringable
|
||||
* @param null|string $password the password associated with $user
|
||||
* @return static a new instance with the specified user information
|
||||
*/
|
||||
public function withUserInfo($user, $password = null): static
|
||||
public function withUserInfo(mixed $user, mixed $password = null): static
|
||||
{
|
||||
$info = $user;
|
||||
if ($password !== '') {
|
||||
@ -320,9 +330,9 @@ class Uri implements UriInterface, Stringable
|
||||
return $this;
|
||||
}
|
||||
$clone = clone $this;
|
||||
$clone->userInfo = $user;
|
||||
$clone->userInfo = $info;
|
||||
$clone->validateState();
|
||||
return $this;
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -335,7 +345,7 @@ class Uri implements UriInterface, Stringable
|
||||
* @return static a new instance with the specified host
|
||||
* @throws InvalidArgumentException for invalid hostnames
|
||||
*/
|
||||
public function withHost($host): static
|
||||
public function withHost(mixed $host): static
|
||||
{
|
||||
$host = $this->filterHost($host);
|
||||
if ($this->host === $host) {
|
||||
@ -391,7 +401,7 @@ class Uri implements UriInterface, Stringable
|
||||
* @return static a new instance with the specified path
|
||||
* @throws InvalidArgumentException for invalid paths
|
||||
*/
|
||||
public function withPath($path): static
|
||||
public function withPath(mixed $path): static
|
||||
{
|
||||
$path = $this->filterPath($path);
|
||||
if ($this->path === $path) {
|
||||
@ -415,7 +425,7 @@ class Uri implements UriInterface, Stringable
|
||||
* @return static a new instance with the specified query string
|
||||
* @throws InvalidArgumentException for invalid query strings
|
||||
*/
|
||||
public function withQuery($query): static
|
||||
public function withQuery(mixed $query): static
|
||||
{
|
||||
$query = $this->filterQueryAndFragment($query);
|
||||
if ($this->query === $query) {
|
||||
@ -475,7 +485,7 @@ class Uri implements UriInterface, Stringable
|
||||
* @param string $fragment the fragment to use with the new instance
|
||||
* @return static a new instance with the specified fragment
|
||||
*/
|
||||
public function withFragment($fragment): static
|
||||
public function withFragment(mixed $fragment): static
|
||||
{
|
||||
$fragment = $this->filterQueryAndFragment($fragment);
|
||||
if ($this->fragment === $fragment) {
|
||||
@ -539,6 +549,122 @@ class Uri implements UriInterface, Stringable
|
||||
return self::$defaultPorts[$this->getScheme()] ?? null;
|
||||
}
|
||||
|
||||
public function setScheme(string $scheme): static
|
||||
{
|
||||
$scheme = $this->filterScheme($scheme);
|
||||
if ($this->scheme === $scheme) {
|
||||
return $this;
|
||||
}
|
||||
$this->scheme = $scheme;
|
||||
// TODO add method
|
||||
$this->removeDefaultPort();
|
||||
$this->validateState();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUserInfo(string $user, string $password = ''): static
|
||||
{
|
||||
$info = $user;
|
||||
if ($password !== '') {
|
||||
$info .= ':' . $password;
|
||||
}
|
||||
$this->userInfo = $info;
|
||||
$this->validateState();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHost(string $host): static
|
||||
{
|
||||
$this->host = $this->filterHost($host);
|
||||
$this->validateState();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPort(?int $port): static
|
||||
{
|
||||
$port = $this->filterPort($port);
|
||||
if ($this->port === $port) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->port = $port;
|
||||
$this->validateState();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPath(string $path): static
|
||||
{
|
||||
$path = $this->filterPath($path);
|
||||
if ($this->path === $path) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->path = $path;
|
||||
$this->validateState();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setQuery(string $query): static
|
||||
{
|
||||
$query = $this->filterQueryAndFragment($query);
|
||||
$this->query = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQueryParams(): array
|
||||
{
|
||||
if (! isset($this->queryParams)) {
|
||||
$query = $this->query;
|
||||
if ($query === '') {
|
||||
$this->queryParams = [];
|
||||
} else {
|
||||
parse_str($query, $this->queryParams);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->queryParams;
|
||||
}
|
||||
|
||||
public function setQueryParams(array $queryParams): static
|
||||
{
|
||||
$this->query = http_build_query($queryParams);
|
||||
$this->queryParams = $queryParams;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withQueryParams(array $queryParams): static
|
||||
{
|
||||
return (clone $this)->setQueryParams($queryParams);
|
||||
}
|
||||
|
||||
public function setFragment(string $fragment): static
|
||||
{
|
||||
$fragment = $this->filterQueryAndFragment($fragment);
|
||||
$this->fragment = $fragment;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function build(string $scheme, string $authority, string $path, string $query, string $fragment): string
|
||||
{
|
||||
$schemeSuffix = $scheme !== '' ? ':' : '';
|
||||
$authorityPrefix = $authority !== '' ? '//' : '';
|
||||
$pathPrefix = '';
|
||||
if ($path !== '' && ! str_starts_with($path, '/') && $authority !== '') {
|
||||
// If the path is rootless and an authority is present, the path MUST be prefixed by "/"
|
||||
$pathPrefix = '/';
|
||||
}
|
||||
$queryPrefix = $query !== '' ? '?' : '';
|
||||
$fragmentPrefix = $fragment !== '' ? '#' : '';
|
||||
|
||||
return $scheme . $schemeSuffix . $authorityPrefix . $authority . $pathPrefix . $path . $queryPrefix . $query . $fragmentPrefix . $fragment;
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return static::build($this->scheme, $this->getAuthority(), $this->path, $this->query, $this->fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common state validate method.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user