diff --git a/composer.json b/composer.json index 55ace45..5631d74 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "symfony/process": "^5.2" }, "provide": { - "psr/http-message-implementation": "1.0", + "psr/http-message-implementation": "2.0", "psr/http-factory-implementation": "1.0" }, "scripts": { diff --git a/composer.lock b/composer.lock index e72c438..2fb4152 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f9394aa4c519ac102a8998c5564a32f3", + "content-hash": "b05ceaccda26818c3c14d1bc0ada3173", "packages": [], "packages-dev": [ { @@ -4381,7 +4381,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -4389,6 +4389,6 @@ "ext-curl": "*", "ext-mbstring": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/src/Message/Factory/Factory.php b/src/Message/Factory/Factory.php index f4e75c1..b0b79ad 100644 --- a/src/Message/Factory/Factory.php +++ b/src/Message/Factory/Factory.php @@ -182,7 +182,7 @@ public function createUriFromArray(array $server): Uri } if (isset($server['SERVER_PORT'])) { - $uri = $uri->withPort($server['SERVER_PORT']); + $uri = $uri->withPort((int) $server['SERVER_PORT']); } if (isset($server['REQUEST_URI'])) { diff --git a/src/Message/MessageTrait.php b/src/Message/MessageTrait.php index 6094af1..317d4da 100644 --- a/src/Message/MessageTrait.php +++ b/src/Message/MessageTrait.php @@ -40,7 +40,7 @@ public function getProtocolVersion(): string * * @return self */ - public function withProtocolVersion($version): self + public function withProtocolVersion(string $version): self { $this->validateProtocolVersion($version); @@ -69,12 +69,8 @@ public function getHeaders(): array * * @return bool */ - public function hasHeader($name): bool + public function hasHeader(string $name): bool { - if (!\is_string($name)) { - throw new \InvalidArgumentException('Header name must be a string'); - } - return isset($this->headerNames[\mb_strtolower($name)]); } @@ -85,12 +81,8 @@ public function hasHeader($name): bool * * @return array */ - public function getHeader($name): array + public function getHeader(string $name): array { - if (!\is_string($name)) { - throw new \InvalidArgumentException('Header name must be a string'); - } - $name = \mb_strtolower($name); if (!isset($this->headerNames[$name])) { @@ -109,7 +101,7 @@ public function getHeader($name): array * * @return string */ - public function getHeaderLine($name): string + public function getHeaderLine(string $name): string { return \implode(', ', $this->getHeader($name)); } @@ -122,9 +114,9 @@ public function getHeaderLine($name): string * * @return self */ - public function withHeader($name, $value): self + public function withHeader(string $name, $value): self { - if (!\is_string($name) || $name === '') { + if ($name === '') { throw new \InvalidArgumentException('Header name must be non-empty string'); } @@ -149,9 +141,9 @@ public function withHeader($name, $value): self * * @return self */ - public function withAddedHeader($name, $value): self + public function withAddedHeader(string $name, $value): self { - if (!\is_string($name) || $name === '') { + if ($name === '') { throw new \InvalidArgumentException('Header name must be non-empty string'); } @@ -168,9 +160,9 @@ public function withAddedHeader($name, $value): self * * @return self */ - public function withoutHeader($name): self + public function withoutHeader(string $name): self { - if (!\is_string($name) || $name === '') { + if ($name === '') { throw new \InvalidArgumentException('Header name must be non-empty string'); } @@ -240,8 +232,8 @@ protected function setHeaders(array $headers): void } /** - * @param string $header - * @param mixed $values + * @param string|array $header + * @param mixed $values * * @throws \InvalidArgumentException * @@ -278,35 +270,35 @@ protected function validateAndTrimHeader($header, $values): array } /** - * Because of PHP 8.4. + * @param string $protocolVersion * - * @param $string - * @param string $characters + * @throws \InvalidArgumentException * * @return string */ - protected function trim($string, string $characters = " \n\r\t\v\0"): string + protected function validateProtocolVersion(string $protocolVersion): string { - if (\PHP_MAJOR_VERSION >= 8 && \PHP_MINOR_VERSION >= 4) { - return \mb_trim((string) $string, $characters); + if (!\in_array($protocolVersion, static::$validProtocols, true)) { + throw new \InvalidArgumentException('Protocol Version must be ' . \implode(' or ', static::$validProtocols)); } - return \trim((string) $string, $characters); + return $protocolVersion; } /** - * @param string $protocolVersion + * Because of PHP 8.4. * - * @throws \InvalidArgumentException + * @param $string + * @param string $characters * * @return string */ - protected function validateProtocolVersion(string $protocolVersion): string + protected function trim($string, string $characters = " \n\r\t\v\0"): string { - if (!\in_array($protocolVersion, static::$validProtocols, true)) { - throw new \InvalidArgumentException('Protocol Version must be ' . \implode(' or ', static::$validProtocols)); + if (\PHP_MAJOR_VERSION >= 8 && \PHP_MINOR_VERSION >= 4) { + return \mb_trim((string) $string, $characters); } - return $protocolVersion; + return \trim((string) $string, $characters); } } diff --git a/src/Message/RequestTrait.php b/src/Message/RequestTrait.php index b53db83..a625d8a 100644 --- a/src/Message/RequestTrait.php +++ b/src/Message/RequestTrait.php @@ -96,13 +96,13 @@ public function getRequestTarget(): string } /** - * @param $requestTarget + * @param string $requestTarget * * @throws \InvalidArgumentException * * @return self */ - public function withRequestTarget($requestTarget): self + public function withRequestTarget(string $requestTarget): self { if (\preg_match('#\s#', $requestTarget)) { throw new \InvalidArgumentException('Invalid request target provided; cannot contain whitespace'); @@ -129,7 +129,7 @@ public function getMethod(): string * * @return self */ - public function withMethod($method): self + public function withMethod(string $method): self { $method = $this->filterMethod($method); @@ -155,12 +155,8 @@ public function getUri(): UriInterface * * @return self */ - public function withUri(UriInterface $uri, $preserveHost = false): self + public function withUri(UriInterface $uri, bool $preserveHost = false): self { - if (!\is_bool($preserveHost)) { - throw new \InvalidArgumentException('Preserve Host must be a boolean'); - } - if ($this->uri === $uri) { return $this; } @@ -182,12 +178,8 @@ public function withUri(UriInterface $uri, $preserveHost = false): self * * @return string */ - protected function filterMethod($method): string + protected function filterMethod(string $method): string { - if (!\is_string($method)) { - throw new \InvalidArgumentException('Method must be a string'); - } - if (!\in_array($method, static::$methods, true)) { throw new \InvalidArgumentException(\sprintf('Method %s is invalid', $method)); } diff --git a/src/Message/Response.php b/src/Message/Response.php index 6d11e20..8fc5067 100644 --- a/src/Message/Response.php +++ b/src/Message/Response.php @@ -233,12 +233,8 @@ public function getStatusCode(): int * * @return Response */ - public function withStatus($code, $reasonPhrase = ''): self + public function withStatus(int $code, string $reasonPhrase = ''): self { - if (!\is_int($code)) { - throw new \InvalidArgumentException('Status code has to be an integer'); - } - if (!isset(static::PHRASES[$code])) { throw new \InvalidArgumentException('Status code has to be an integer between 100 and 799'); } diff --git a/src/Message/ServerRequest.php b/src/Message/ServerRequest.php index dcdbaad..fcc81d9 100644 --- a/src/Message/ServerRequest.php +++ b/src/Message/ServerRequest.php @@ -182,12 +182,8 @@ public function getAttributes(): array * * @return mixed|null */ - public function getAttribute($name, $default = null) + public function getAttribute(string $name, $default = null) { - if (!\is_string($name)) { - throw new \InvalidArgumentException('Name must be a string'); - } - if (!\array_key_exists($name, $this->attributes)) { return $default; } @@ -203,12 +199,8 @@ public function getAttribute($name, $default = null) * * @return self */ - public function withAttribute($name, $value): self + public function withAttribute(string $name, $value): self { - if (!\is_string($name)) { - throw new \InvalidArgumentException('Name must be a string'); - } - $new = clone $this; $new->attributes[$name] = $value; @@ -222,12 +214,8 @@ public function withAttribute($name, $value): self * * @return self */ - public function withoutAttribute($name): self + public function withoutAttribute(string $name): self { - if (!\is_string($name)) { - throw new \InvalidArgumentException('Name must be a string'); - } - if (!\array_key_exists($name, $this->attributes)) { return $this; } diff --git a/src/Message/Stream.php b/src/Message/Stream.php index bcdf355..b161067 100644 --- a/src/Message/Stream.php +++ b/src/Message/Stream.php @@ -162,16 +162,8 @@ public function isSeekable(): bool * @throws \InvalidArgumentException * @throws \RuntimeException */ - public function seek($offset, $whence = \SEEK_SET): void + public function seek(int $offset, int $whence = \SEEK_SET): void { - if (!\is_int($offset)) { - throw new \InvalidArgumentException('Offset must be a int'); - } - - if (!\is_int($whence)) { - throw new \InvalidArgumentException('Whence must be a int'); - } - if (!$this->seekable) { throw new \RuntimeException('Stream is not seekable'); } @@ -208,12 +200,8 @@ public function isWritable(): bool * * @return int */ - public function write($string) + public function write(string $string): int { - if (!\is_string($string)) { - throw new \InvalidArgumentException('Data must be a string'); - } - if (!$this->writable) { throw new \RuntimeException('Cannot write to a non-writable stream'); } @@ -241,19 +229,15 @@ public function isReadable(): bool } /** - * @param $length + * @param int $length * * @throws \InvalidArgumentException * @throws \RuntimeException * * @return string */ - public function read($length): string + public function read(int $length): string { - if (!\is_int($length)) { - throw new \InvalidArgumentException('Length must be a int'); - } - if (!$this->readable) { throw new \RuntimeException('Cannot read from non-readable stream'); } @@ -318,14 +302,10 @@ public function getContents(): string * * @throws \InvalidArgumentException * - * @return array|null + * @return array|mixed|null */ - public function getMetadata($key = null) + public function getMetadata(?string $key = null) { - if (!$this->isStringOrNull($key)) { - throw new \InvalidArgumentException('Key must be a string or NULL'); - } - if (!isset($this->stream)) { return $key ? null : []; } @@ -428,14 +408,4 @@ public function __destruct() { $this->close(); } - - /** - * @param $param - * - * @return bool - */ - protected function isStringOrNull($param): bool - { - return $param === null || \is_string($param); - } } diff --git a/src/Message/UploadedFile.php b/src/Message/UploadedFile.php index dd5be84..fa44ead 100644 --- a/src/Message/UploadedFile.php +++ b/src/Message/UploadedFile.php @@ -43,7 +43,7 @@ class UploadedFile implements UploadedFileInterface /** * @param StreamInterface|string|resource $streamOrFile - * @param int $size + * @param int|null $size * @param int $errorStatus * @param string|null $clientFilename * @param string|null $clientMediaType @@ -52,10 +52,10 @@ class UploadedFile implements UploadedFileInterface */ public function __construct( $streamOrFile, - $size, - $errorStatus, - $clientFilename = null, - $clientMediaType = null + ?int $size, + int $errorStatus, + ?string $clientFilename = null, + ?string $clientMediaType = null ) { $this->setError($errorStatus); $this->setSize($size); @@ -90,7 +90,7 @@ public function getStream(): StreamInterface * @throws \InvalidArgumentException * @throws \RuntimeException */ - public function moveTo($targetPath): void + public function moveTo(string $targetPath): void { $this->validateActive(); @@ -187,12 +187,8 @@ protected function setStreamOrFile($streamOrFile): void * * @throws \InvalidArgumentException */ - protected function setError($error): void + protected function setError(int $error): void { - if (!\is_int($error)) { - throw new \InvalidArgumentException('Upload file error status must be an integer'); - } - if (!isset(static::ERRORS[$error])) { throw new \InvalidArgumentException('Invalid error status for UploadedFile'); } @@ -201,29 +197,15 @@ protected function setError($error): void } /** - * @param int $size + * @param int|null $size * * @throws \InvalidArgumentException */ - protected function setSize($size): void + protected function setSize(?int $size): void { - if (!\is_int($size)) { - throw new \InvalidArgumentException('Upload file size must be an integer'); - } - $this->size = $size; } - /** - * @param $param - * - * @return bool - */ - protected function isStringOrNull($param): bool - { - return $param === null || \is_string($param); - } - /** * @param $param * @@ -239,12 +221,8 @@ protected function isStringNotEmpty($param): bool * * @throws \InvalidArgumentException */ - protected function setClientFilename($clientFilename): void + protected function setClientFilename(?string $clientFilename): void { - if (!$this->isStringOrNull($clientFilename)) { - throw new \InvalidArgumentException('Upload file client filename must be a string or null'); - } - $this->clientFilename = $clientFilename; } @@ -253,12 +231,8 @@ protected function setClientFilename($clientFilename): void * * @throws \InvalidArgumentException */ - protected function setClientMediaType($clientMediaType): void + protected function setClientMediaType(?string $clientMediaType): void { - if (!$this->isStringOrNull($clientMediaType)) { - throw new \InvalidArgumentException('Upload file client media type must be a string or null'); - } - $this->clientMediaType = $clientMediaType; } diff --git a/src/Message/Uri.php b/src/Message/Uri.php index 422e06e..7b75a23 100644 --- a/src/Message/Uri.php +++ b/src/Message/Uri.php @@ -139,7 +139,7 @@ public function getFragment(): string * * @return self */ - public function withScheme($scheme): self + public function withScheme(string $scheme): self { $scheme = $this->filterScheme($scheme); @@ -162,7 +162,7 @@ public function withScheme($scheme): self * * @return self */ - public function withUserInfo($user, $password = null): self + public function withUserInfo(string $user, ?string $password = null): self { $info = $this->filterUser($user); $password = $this->filterPass($password); @@ -188,7 +188,7 @@ public function withUserInfo($user, $password = null): self * * @return self */ - public function withHost($host): self + public function withHost(string $host): self { $host = $this->filterHost($host); @@ -209,7 +209,7 @@ public function withHost($host): self * * @return self */ - public function withPort($port): self + public function withPort(?int $port): self { $port = $this->filterPort($port); @@ -230,7 +230,7 @@ public function withPort($port): self * * @return self */ - public function withPath($path): self + public function withPath(string $path): self { $path = $this->filterPath($path); @@ -251,7 +251,7 @@ public function withPath($path): self * * @return self */ - public function withQuery($query): self + public function withQuery(string $query): self { $query = $this->filterQueryAndFragment($query); @@ -272,7 +272,7 @@ public function withQuery($query): self * * @return self */ - public function withFragment($fragment): self + public function withFragment(string $fragment): self { $fragment = $this->filterQueryAndFragment($fragment); @@ -401,23 +401,6 @@ protected static function createUriString( return $uri; } - /** - * Because of PHP 8.4. - * - * @param $string - * @param string $characters - * - * @return string - */ - protected static function ltrim($string, string $characters = " \n\r\t\v\0"): string - { - if (\PHP_MAJOR_VERSION >= 8 && \PHP_MINOR_VERSION >= 4) { - return \mb_ltrim((string) $string, $characters); - } - - return \ltrim((string) $string, $characters); - } - /** * @param string $scheme * @param int $port @@ -436,12 +419,8 @@ protected static function isNonStandardPort(string $scheme, int $port): bool * * @return string */ - protected function filterScheme($scheme): string + protected function filterScheme(string $scheme): string { - if (!\is_string($scheme)) { - throw new \InvalidArgumentException('Scheme must be a string'); - } - return \mb_strtolower($scheme); } @@ -452,12 +431,8 @@ protected function filterScheme($scheme): string * * @return string */ - protected function filterUser($user): string + protected function filterUser(string $user): string { - if (!\is_string($user)) { - throw new \InvalidArgumentException('User must be a string'); - } - return $user; } @@ -468,12 +443,8 @@ protected function filterUser($user): string * * @return string */ - protected function filterPass($pass): ?string + protected function filterPass(?string $pass): ?string { - if ($pass !== null && !\is_string($pass)) { - throw new \InvalidArgumentException('Password must be a string or NULL'); - } - return $pass; } @@ -484,12 +455,8 @@ protected function filterPass($pass): ?string * * @return string */ - protected function filterHost($host): string + protected function filterHost(string $host): string { - if (!\is_string($host)) { - throw new \InvalidArgumentException('Host must be a string'); - } - return \mb_strtolower($host); } @@ -500,13 +467,12 @@ protected function filterHost($host): string * * @return int|null */ - protected function filterPort($port): ?int + protected function filterPort(?int $port): ?int { if ($port === null) { return null; } - $port = (int) $port; if ($port < 1 || $port > 65535) { throw new \InvalidArgumentException(\sprintf('Invalid port: %d. Must be between 1 and 65535', $port)); } @@ -525,12 +491,8 @@ protected function filterPort($port): ?int * * @return string */ - protected function filterPath($path): string + protected function filterPath(string $path): string { - if (!\is_string($path)) { - throw new \InvalidArgumentException('Path must be a string'); - } - return \preg_replace_callback( static::getPatternForFilteringPath(), [__CLASS__, 'rawurlencodeMatchZero'], @@ -545,12 +507,8 @@ protected function filterPath($path): string * * @return string */ - protected function filterQueryAndFragment($str): string + protected function filterQueryAndFragment(string $str): string { - if (!\is_string($str)) { - throw new \InvalidArgumentException('Query and fragment must be a string'); - } - return \preg_replace_callback( static::getPatternForFilteringQueryAndFragment(), [__CLASS__, 'rawurlencodeMatchZero'], @@ -583,4 +541,21 @@ protected static function getPatternForFilteringQueryAndFragment(): string { return '/(?:[^' . static::CHAR_UNRESERVED . static::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/'; } + + /** + * Because of PHP 8.4. + * + * @param $string + * @param string $characters + * + * @return string + */ + protected static function ltrim($string, string $characters = " \n\r\t\v\0"): string + { + if (\PHP_MAJOR_VERSION >= 8 && \PHP_MINOR_VERSION >= 4) { + return \mb_ltrim((string) $string, $characters); + } + + return \ltrim((string) $string, $characters); + } } diff --git a/src/Psr/Message/MessageInterface.php b/src/Psr/Message/MessageInterface.php index 40108a2..a83c985 100644 --- a/src/Psr/Message/MessageInterface.php +++ b/src/Psr/Message/MessageInterface.php @@ -23,7 +23,7 @@ interface MessageInterface * * @return string HTTP protocol version. */ - public function getProtocolVersion(); + public function getProtocolVersion(): string; /** * Return an instance with the specified HTTP protocol version. @@ -38,7 +38,7 @@ public function getProtocolVersion(); * @param string $version HTTP protocol version * @return static */ - public function withProtocolVersion($version); + public function withProtocolVersion(string $version): MessageInterface; /** * Retrieves all message header values. @@ -65,7 +65,7 @@ public function withProtocolVersion($version); * key MUST be a header name, and each value MUST be an array of strings * for that header. */ - public function getHeaders(); + public function getHeaders(): array; /** * Checks if a header exists by the given case-insensitive name. @@ -75,7 +75,7 @@ public function getHeaders(); * name using a case-insensitive string comparison. Returns false if * no matching header name is found in the message. */ - public function hasHeader($name); + public function hasHeader(string $name): bool; /** * Retrieves a message header value by the given case-insensitive name. @@ -91,7 +91,7 @@ public function hasHeader($name); * header. If the header does not appear in the message, this method MUST * return an empty array. */ - public function getHeader($name); + public function getHeader(string $name): array; /** * Retrieves a comma-separated string of the values for a single header. @@ -112,7 +112,7 @@ public function getHeader($name); * 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); + public function getHeaderLine(string $name): string; /** * Return an instance with the provided value replacing the specified header. @@ -129,7 +129,7 @@ public function getHeaderLine($name); * @return static * @throws \InvalidArgumentException for invalid header names or values. */ - public function withHeader($name, $value); + public function withHeader(string $name, $value): MessageInterface; /** * Return an instance with the specified header appended with the given value. @@ -147,7 +147,7 @@ public function withHeader($name, $value); * @return static * @throws \InvalidArgumentException for invalid header names or values. */ - public function withAddedHeader($name, $value); + public function withAddedHeader(string $name, $value): MessageInterface; /** * Return an instance without the specified header. @@ -161,14 +161,14 @@ public function withAddedHeader($name, $value); * @param string $name Case-insensitive header field name to remove. * @return static */ - public function withoutHeader($name); + public function withoutHeader(string $name): MessageInterface; /** * Gets the body of the message. * * @return StreamInterface Returns the body as a stream. */ - public function getBody(); + public function getBody(): StreamInterface; /** * Return an instance with the specified message body. @@ -183,5 +183,5 @@ public function getBody(); * @return static * @throws \InvalidArgumentException When the body is not valid. */ - public function withBody(StreamInterface $body); -} \ No newline at end of file + public function withBody(StreamInterface $body): MessageInterface; +} diff --git a/src/Psr/Message/RequestInterface.php b/src/Psr/Message/RequestInterface.php index 5b1c9c0..33f85e5 100644 --- a/src/Psr/Message/RequestInterface.php +++ b/src/Psr/Message/RequestInterface.php @@ -39,7 +39,7 @@ interface RequestInterface extends MessageInterface * * @return string */ - public function getRequestTarget(); + public function getRequestTarget(): string; /** * Return an instance with the specific request-target. @@ -55,17 +55,18 @@ public function getRequestTarget(); * * @link 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 * @return static */ - public function withRequestTarget($requestTarget); + public function withRequestTarget(string $requestTarget): RequestInterface; + /** * Retrieves the HTTP method of the request. * * @return string Returns the request method. */ - public function getMethod(); + public function getMethod(): string; /** * Return an instance with the provided HTTP method. @@ -82,7 +83,7 @@ public function getMethod(); * @return static * @throws \InvalidArgumentException for invalid HTTP methods. */ - public function withMethod($method); + public function withMethod(string $method): RequestInterface; /** * Retrieves the URI instance. @@ -93,7 +94,7 @@ public function withMethod($method); * @return UriInterface Returns a UriInterface instance * representing the URI of the request. */ - public function getUri(); + public function getUri(): UriInterface; /** * Returns an instance with the provided URI. @@ -125,5 +126,5 @@ public function getUri(); * @param bool $preserveHost Preserve the original state of the Host header. * @return static */ - public function withUri(UriInterface $uri, $preserveHost = false); -} \ No newline at end of file + public function withUri(UriInterface $uri, bool $preserveHost = false): RequestInterface; +} diff --git a/src/Psr/Message/ResponseInterface.php b/src/Psr/Message/ResponseInterface.php index 5f7344b..e9299a9 100644 --- a/src/Psr/Message/ResponseInterface.php +++ b/src/Psr/Message/ResponseInterface.php @@ -27,7 +27,7 @@ interface ResponseInterface extends MessageInterface * * @return int Status code. */ - public function getStatusCode(); + public function getStatusCode(): int; /** * Return an instance with the specified status code and, optionally, reason phrase. @@ -49,7 +49,7 @@ public function getStatusCode(); * @return static * @throws \InvalidArgumentException For invalid status code arguments. */ - public function withStatus($code, $reasonPhrase = ''); + public function withStatus(int $code, string $reasonPhrase = ''): ResponseInterface; /** * Gets the response reason phrase associated with the status code. @@ -64,5 +64,5 @@ public function withStatus($code, $reasonPhrase = ''); * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml * @return string Reason phrase; must return an empty string if none present. */ - public function getReasonPhrase(); -} \ No newline at end of file + public function getReasonPhrase(): string; +} diff --git a/src/Psr/Message/ServerRequestInterface.php b/src/Psr/Message/ServerRequestInterface.php index 42baf11..8625d0e 100644 --- a/src/Psr/Message/ServerRequestInterface.php +++ b/src/Psr/Message/ServerRequestInterface.php @@ -51,7 +51,7 @@ interface ServerRequestInterface extends RequestInterface * * @return array */ - public function getServerParams(); + public function getServerParams(): array; /** * Retrieve cookies. @@ -63,7 +63,7 @@ public function getServerParams(); * * @return array */ - public function getCookieParams(); + public function getCookieParams(): array; /** * Return an instance with the specified cookies. @@ -82,7 +82,7 @@ public function getCookieParams(); * @param array $cookies Array of key/value pairs representing cookies. * @return static */ - public function withCookieParams(array $cookies); + public function withCookieParams(array $cookies): ServerRequestInterface; /** * Retrieve query string arguments. @@ -96,7 +96,7 @@ public function withCookieParams(array $cookies); * * @return array */ - public function getQueryParams(); + public function getQueryParams(): array; /** * Return an instance with the specified query string arguments. @@ -120,7 +120,7 @@ public function getQueryParams(); * $_GET. * @return static */ - public function withQueryParams(array $query); + public function withQueryParams(array $query): ServerRequestInterface; /** * Retrieve normalized file upload data. @@ -134,7 +134,7 @@ public function withQueryParams(array $query); * @return array An array tree of UploadedFileInterface instances; an empty * array MUST be returned if no data is present. */ - public function getUploadedFiles(); + public function getUploadedFiles(): array; /** * Create a new instance with the specified uploaded files. @@ -147,7 +147,7 @@ public function getUploadedFiles(); * @return static * @throws \InvalidArgumentException if an invalid structure is provided. */ - public function withUploadedFiles(array $uploadedFiles); + public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface; /** * Retrieve any parameters provided in the request body. @@ -194,7 +194,7 @@ public function getParsedBody(); * @throws \InvalidArgumentException if an unsupported argument type is * provided. */ - public function withParsedBody($data); + public function withParsedBody($data): ServerRequestInterface; /** * Retrieve attributes derived from the request. @@ -207,7 +207,7 @@ public function withParsedBody($data); * * @return array Attributes derived from the request. */ - public function getAttributes(); + public function getAttributes(): array; /** * Retrieve a single derived request attribute. @@ -224,7 +224,7 @@ public function getAttributes(); * @param mixed $default Default value to return if the attribute does not exist. * @return mixed */ - public function getAttribute($name, $default = null); + public function getAttribute(string $name, $default = null); /** * Return an instance with the specified derived request attribute. @@ -241,7 +241,7 @@ public function getAttribute($name, $default = null); * @param mixed $value The value of the attribute. * @return static */ - public function withAttribute($name, $value); + public function withAttribute(string $name, $value): ServerRequestInterface; /** * Return an instance that removes the specified derived request attribute. @@ -257,5 +257,5 @@ public function withAttribute($name, $value); * @param string $name The attribute name. * @return static */ - public function withoutAttribute($name); -} \ No newline at end of file + public function withoutAttribute(string $name): ServerRequestInterface; +} diff --git a/src/Psr/Message/StreamInterface.php b/src/Psr/Message/StreamInterface.php index c7b3368..a62aabb 100644 --- a/src/Psr/Message/StreamInterface.php +++ b/src/Psr/Message/StreamInterface.php @@ -25,14 +25,14 @@ interface StreamInterface * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring * @return string */ - public function __toString(); + public function __toString(): string; /** * Closes the stream and any underlying resources. * * @return void */ - public function close(); + public function close(): void; /** * Separates any underlying resources from the stream. @@ -48,7 +48,7 @@ public function detach(); * * @return int|null Returns the size in bytes if known, or null if unknown. */ - public function getSize(); + public function getSize(): ?int; /** * Returns the current position of the file read/write pointer @@ -56,21 +56,21 @@ public function getSize(); * @return int Position of the file pointer * @throws \RuntimeException on error. */ - public function tell(); + public function tell(): int; /** * Returns true if the stream is at the end of the stream. * * @return bool */ - public function eof(); + public function eof(): bool; /** * Returns whether or not the stream is seekable. * * @return bool */ - public function isSeekable(); + public function isSeekable(): bool; /** * Seek to a position in the stream. @@ -84,7 +84,7 @@ public function isSeekable(); * SEEK_END: Set position to end-of-stream plus offset. * @throws \RuntimeException on failure. */ - public function seek($offset, $whence = SEEK_SET); + public function seek(int $offset, int $whence = SEEK_SET): void; /** * Seek to the beginning of the stream. @@ -96,14 +96,14 @@ public function seek($offset, $whence = SEEK_SET); * @link http://www.php.net/manual/en/function.fseek.php * @throws \RuntimeException on failure. */ - public function rewind(); + public function rewind(): void; /** * Returns whether or not the stream is writable. * * @return bool */ - public function isWritable(); + public function isWritable(): bool; /** * Write data to the stream. @@ -112,14 +112,14 @@ public function isWritable(); * @return int Returns the number of bytes written to the stream. * @throws \RuntimeException on failure. */ - public function write($string); + public function write(string $string): int; /** * Returns whether or not the stream is readable. * * @return bool */ - public function isReadable(); + public function isReadable(): bool; /** * Read data from the stream. @@ -131,7 +131,7 @@ public function isReadable(); * if no bytes are available. * @throws \RuntimeException if an error occurs. */ - public function read($length); + public function read(int $length): string; /** * Returns the remaining contents in a string @@ -140,7 +140,7 @@ public function read($length); * @throws \RuntimeException if unable to read or an error occurs while * reading. */ - public function getContents(); + public function getContents(): string; /** * Get stream metadata as an associative array or retrieve a specific key. @@ -149,10 +149,10 @@ public function getContents(); * stream_get_meta_data() function. * * @link http://php.net/manual/en/function.stream-get-meta-data.php - * @param string $key Specific metadata to retrieve. + * @param string|null $key Specific metadata to retrieve. * @return array|mixed|null Returns an associative array if no key is * provided. Returns a specific key value if a key is provided and the * value is found, or null if the key is not found. */ - public function getMetadata($key = null); -} \ No newline at end of file + public function getMetadata(?string $key = null); +} diff --git a/src/Psr/Message/UploadedFileFactoryInterface.php b/src/Psr/Message/UploadedFileFactoryInterface.php index 03270e3..d7adbf0 100644 --- a/src/Psr/Message/UploadedFileFactoryInterface.php +++ b/src/Psr/Message/UploadedFileFactoryInterface.php @@ -15,10 +15,10 @@ interface UploadedFileFactoryInterface * * @param StreamInterface $stream Underlying stream representing the * uploaded file content. - * @param int $size in bytes + * @param int|null $size in bytes * @param int $error PHP file upload error - * @param string $clientFilename Filename as provided by the client, if any. - * @param string $clientMediaType Media type as provided by the client, if any. + * @param string|null $clientFilename Filename as provided by the client, if any. + * @param string|null $clientMediaType Media type as provided by the client, if any. * * @return UploadedFileInterface * @@ -26,9 +26,9 @@ interface UploadedFileFactoryInterface */ public function createUploadedFile( StreamInterface $stream, - int $size = null, + ?int $size = null, int $error = \UPLOAD_ERR_OK, - string $clientFilename = null, - string $clientMediaType = null + ?string $clientFilename = null, + ?string $clientMediaType = null ): UploadedFileInterface; -} \ No newline at end of file +} diff --git a/src/Psr/Message/UploadedFileInterface.php b/src/Psr/Message/UploadedFileInterface.php index eba5756..f13ed10 100644 --- a/src/Psr/Message/UploadedFileInterface.php +++ b/src/Psr/Message/UploadedFileInterface.php @@ -28,7 +28,7 @@ interface UploadedFileInterface * @throws \RuntimeException in cases when no stream is available or can be * created. */ - public function getStream(); + public function getStream(): StreamInterface; /** * Move the uploaded file to a new location. @@ -62,7 +62,7 @@ public function getStream(); * @throws \RuntimeException on any error during the move operation, or on * the second or subsequent call to the method. */ - public function moveTo($targetPath); + public function moveTo(string $targetPath): void; /** * Retrieve the file size. @@ -73,7 +73,7 @@ public function moveTo($targetPath); * * @return int|null The file size in bytes or null if unknown. */ - public function getSize(); + public function getSize(): ?int; /** * Retrieve the error associated with the uploaded file. @@ -89,7 +89,7 @@ public function getSize(); * @see http://php.net/manual/en/features.file-upload.errors.php * @return int One of PHP's UPLOAD_ERR_XXX constants. */ - public function getError(); + public function getError(): int; /** * Retrieve the filename sent by the client. @@ -104,7 +104,7 @@ public function getError(); * @return string|null The filename sent by the client or null if none * was provided. */ - public function getClientFilename(); + public function getClientFilename(): ?string; /** * Retrieve the media type sent by the client. @@ -119,5 +119,5 @@ public function getClientFilename(); * @return string|null The media type sent by the client or null if none * was provided. */ - public function getClientMediaType(); -} \ No newline at end of file + public function getClientMediaType(): ?string; +} diff --git a/src/Psr/Message/UriInterface.php b/src/Psr/Message/UriInterface.php index 6adb8fc..15e2cf2 100644 --- a/src/Psr/Message/UriInterface.php +++ b/src/Psr/Message/UriInterface.php @@ -1,4 +1,5 @@ getMethod()); } - public function testWithUriPreserveHostMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Preserve Host must be a boolean'); - - $r = new Request('GET', 'https://foo.com:8124/bar'); - $r->withUri(new Uri(), null); - } - - public function testWithMethodMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Method must be a string'); - - $r = new Request('GET', 'https://foo.com:8124/bar'); - $r->withMethod(null); - } - public function testWithMethodMustBeValidMethod(): void { $this->expectException(\InvalidArgumentException::class); diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index 899cfb3..cd61609 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -46,17 +46,6 @@ public function testConstructStatusCantBeNumericString(): void new Response('-404.4'); } - public function testWithStatusCantBeNumericString(): void - { - $r = new Response(404); - static::assertSame(404, $r->getStatusCode()); - static::assertSame('Not Found', $r->getReasonPhrase()); - - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Status code has to be an integer'); - $r->withStatus('201'); - } - public function testCanConstructWithHeaders(): void { $r = new Response(200, ['Foo' => 'Bar']); @@ -131,6 +120,15 @@ public function testRaiseExceptionConstructWithProtocolVersion(): void new Response(200, [], null, '1000'); } + public function testRaiseWithInvalidStatusCode(): void + { + $r = new Response(); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Status code has to be an integer between 100 and 799'); + $r->withStatus(1); + } + public function testWithStatusCodeAndNoReason(): void { $r = (new Response())->withStatus(201); @@ -269,33 +267,6 @@ public function trimmedHeaderValues(): array ]; } - public function testHasHeaderMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Header name must be a string'); - - $r = new Response(); - static::assertSame($r, $r->hasHeader(null)); - } - - public function testGetHeaderMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Header name must be a string'); - - $r = new Response(); - static::assertSame($r, $r->getHeader(null)); - } - - public function testGetHeaderLineMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Header name must be a string'); - - $r = new Response(); - static::assertSame($r, $r->getHeaderLine(null)); - } - public function testWithHeaderNameMustHaveCorrectType(): void { $this->expectException(\InvalidArgumentException::class); @@ -389,24 +360,6 @@ public function testHeaderValuesAreTrimmed(Response $r): void static::assertSame(['Foo'], $r->getHeader('OWS')); } - public function testWithStatusCodeMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Status code has to be an integer'); - - $r = new Response(); - $r->withStatus([]); - } - - public function testWithStatusReasonPhraseMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Status code has to be an integer between 100 and 799'); - - $r = new Response(); - $r->withStatus(9, []); - } - /** * @runInSeparateProcess */ diff --git a/tests/ServerRequestTest.php b/tests/ServerRequestTest.php index 4ef0aac..ea987bf 100644 --- a/tests/ServerRequestTest.php +++ b/tests/ServerRequestTest.php @@ -546,30 +546,6 @@ public function testNullAttribute(): void static::assertSame('different-default', $requestWithoutAttribute->getAttribute('name', 'different-default')); } - public function testGetAttributeMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Name must be a string'); - - (new ServerRequest('GET', '/'))->getAttribute([]); - } - - public function testWithAttributeMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Name must be a string'); - - (new ServerRequest('GET', '/'))->withAttribute([], null); - } - - public function testWithoutAttributeMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Name must be a string'); - - (new ServerRequest('GET', '/'))->withoutAttribute([]); - } - public function testWithParsedBodyMustHaveCorrectType(): void { $this->expectException(\InvalidArgumentException::class); diff --git a/tests/StreamTest.php b/tests/StreamTest.php index f40902b..7844f9b 100644 --- a/tests/StreamTest.php +++ b/tests/StreamTest.php @@ -179,26 +179,6 @@ public function testCloseClearProperties(): void static::assertNull($stream->getMetadata('key')); } - public function testSeekRaiseExceptionOffset(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Offset must be a int'); - - $handle = \fopen('php://temp', 'w+'); - $stream = Stream::create($handle); - $stream->seek('string'); - } - - public function testSeekRaiseExceptionWhence(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Whence must be a int'); - - $handle = \fopen('php://temp', 'w+'); - $stream = Stream::create($handle); - $stream->seek(1, 'string'); - } - public function testSeekRaiseExceptionUnableToSeek(): void { $this->expectException(\RuntimeException::class); @@ -209,36 +189,6 @@ public function testSeekRaiseExceptionUnableToSeek(): void $stream->seek(1, 90909090); } - public function testWriteRaiseExceptionData(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Data must be a string'); - - $handle = \fopen('php://temp', 'w+'); - $stream = Stream::create($handle); - $stream->write(0); - } - - public function testReadRaiseExceptionLength(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Length must be a int'); - - $handle = \fopen('php://temp', 'w+'); - $stream = Stream::create($handle); - $stream->read('string'); - } - - public function testGetMetadataRaiseExceptionKey(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Key must be a string or NULL'); - - $handle = \fopen('php://temp', 'w+'); - $stream = Stream::create($handle); - $stream->getMetadata(45); - } - public function testGetMetadataKeyNonExist(): void { $handle = \fopen('php://temp', 'w+'); diff --git a/tests/UploadedFileTest.php b/tests/UploadedFileTest.php index 8a7054c..c109f6d 100644 --- a/tests/UploadedFileTest.php +++ b/tests/UploadedFileTest.php @@ -50,39 +50,9 @@ public function testRaisesExceptionOnInvalidStreamOrFile($streamOrFile): void new UploadedFile($streamOrFile, 0, \UPLOAD_ERR_OK); } - public function invalidSizes(): array - { - return [ - 'null' => [null], - 'float' => [1.1], - 'array' => [[1]], - 'object' => [(object) [1]], - ]; - } - - /** - * @dataProvider invalidSizes - * - * @param $size - */ - public function testRaisesExceptionOnInvalidSize($size): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('size'); - - new UploadedFile(\fopen('php://temp', 'wb+'), $size, \UPLOAD_ERR_OK); - } - public function invalidErrorStatuses(): array { return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], - 'float' => [1.1], - 'string' => ['1'], - 'array' => [[1]], - 'object' => [(object) [1]], 'negative' => [-1], 'too-big' => [9], ]; @@ -101,44 +71,6 @@ public function testRaisesExceptionOnInvalidErrorStatus($status): void new UploadedFile(\fopen('php://temp', 'wb+'), 0, $status); } - public function invalidFilenamesAndMediaTypes(): array - { - return [ - 'true' => [true], - 'false' => [false], - 'int' => [1], - 'float' => [1.1], - 'array' => [['string']], - 'object' => [(object) ['string']], - ]; - } - - /** - * @dataProvider invalidFilenamesAndMediaTypes - * - * @param $filename - */ - public function testRaisesExceptionOnInvalidClientFilename($filename): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('filename'); - - new UploadedFile(\fopen('php://temp', 'wb+'), 0, \UPLOAD_ERR_OK, $filename); - } - - /** - * @dataProvider invalidFilenamesAndMediaTypes - * - * @param $mediaType - */ - public function testRaisesExceptionOnInvalidClientMediaType($mediaType): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('media type'); - - new UploadedFile(\fopen('php://temp', 'wb+'), 0, \UPLOAD_ERR_OK, 'foobar.baz', $mediaType); - } - public function testGetStreamWithFile(): void { $stream = Stream::createFromFile(__DIR__ . \DIRECTORY_SEPARATOR . 'noise.jpg'); @@ -184,14 +116,7 @@ public function testSuccessful(): void public function invalidMovePaths(): array { return [ - 'null' => [null], - 'true' => [true], - 'false' => [false], - 'int' => [1], - 'float' => [1.1], 'empty' => [''], - 'array' => [['filename']], - 'object' => [(object) ['filename']], ]; } diff --git a/tests/UriTest.php b/tests/UriTest.php index 195933a..3a44278 100644 --- a/tests/UriTest.php +++ b/tests/UriTest.php @@ -137,62 +137,6 @@ public function testParseUriPortCannotBeZero(): void new Uri('//example.com:-1'); } - public function testSchemeMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Scheme must be a string'); - - (new Uri())->withScheme([]); - } - - public function testUserInfoUserMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('User must be a string'); - - (new Uri())->withUserInfo([]); - } - - public function testUserInfoPasswordMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Password must be a string or NULL'); - - (new Uri())->withUserInfo('', []); - } - - public function testHostMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Host must be a string'); - - (new Uri())->withHost([]); - } - - public function testPathMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Path must be a string'); - - (new Uri())->withPath([]); - } - - public function testQueryMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Query and fragment must be a string'); - - (new Uri())->withQuery([]); - } - - public function testFragmentMustHaveCorrectType(): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Query and fragment must be a string'); - - (new Uri())->withFragment([]); - } - public function testCanParseFalseyUriParts(): void { $uri = new Uri('0://0:0@0/0?0#0'); @@ -353,14 +297,6 @@ public function testStandardPortIsNullIfSchemeChanges(): void static::assertNull($uri->getPort()); } - public function testPortPassedAsStringIsCastedToInt(): void - { - $uri = (new Uri('//example.com'))->withPort('8080'); - - static::assertSame(8080, $uri->getPort(), 'Port is returned as integer'); - static::assertSame('example.com:8080', $uri->getAuthority()); - } - public function testPortCanBeRemoved(): void { $uri = (new Uri('http://example.com:8080'))->withPort(null);