From 355aabfa71efcc49a57cdaaf5f6c24fddc85de43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=93=AD=E6=98=95?= <715557344@qq.com> Date: Tue, 23 Nov 2021 19:43:58 +0800 Subject: [PATCH] Upgrade the minimum php version to 8.0 for http-message. --- src/contract/src/Arrayable.php | 17 +++ src/http-message/src/Base/MessageTrait.php | 31 ++-- src/http-message/src/Base/Request.php | 30 ++-- src/http-message/src/Base/Response.php | 31 ++-- src/http-message/src/Cookie/Cookie.php | 93 ++++-------- src/http-message/src/Cookie/CookieJar.php | 39 ++--- .../src/Cookie/CookieJarInterface.php | 10 +- src/http-message/src/Cookie/FileCookieJar.php | 33 ++--- .../src/Cookie/SessionCookieJar.php | 23 +-- src/http-message/src/Cookie/SetCookie.php | 100 ++++++------- .../src/Exception/HttpException.php | 12 +- src/http-message/src/Server/Request.php | 99 ++++--------- .../src/Server/Request/JsonParser.php | 10 +- .../src/Server/Request/Parser.php | 2 +- .../src/Server/Request/XmlParser.php | 2 +- src/http-message/src/Server/Response.php | 16 +-- .../src/Server/ResponseProxyTrait.php | 9 +- .../src/Stream/SwooleFileStream.php | 30 ++-- src/http-message/src/Stream/SwooleStream.php | 23 +-- src/http-message/src/Upload/UploadedFile.php | 119 +++------------ src/http-message/src/Uri/Uri.php | 136 +++++------------- .../tests/Stub/Server/RequestStub.php | 2 +- src/utils/src/Contracts/Arrayable.php | 5 +- 23 files changed, 268 insertions(+), 604 deletions(-) create mode 100644 src/contract/src/Arrayable.php diff --git a/src/contract/src/Arrayable.php b/src/contract/src/Arrayable.php new file mode 100644 index 000000000..08fe706b7 --- /dev/null +++ b/src/contract/src/Arrayable.php @@ -0,0 +1,17 @@ + $value) { @@ -314,7 +302,7 @@ trait MessageTrait * @throws \RuntimeException * @return array|string wanted part or all parts as array($firstName => firstPart, partname => value) */ - public function getHeaderField($name, $wantedPart = '0', $firstName = '0') + public function getHeaderField(string $name, string $wantedPart = '0', string $firstName = '0') { return Decode::splitHeaderField($this->getHeaderLine($name), $wantedPart, $firstName); } @@ -338,10 +326,7 @@ trait MessageTrait } } - /** - * @return static - */ - private function setHeaders(array $headers) + private function setHeaders(array $headers): static { $this->headerNames = $this->headers = []; foreach ($headers as $header => $value) { @@ -374,7 +359,7 @@ trait MessageTrait * @return string[] Trimmed header values * @see https://tools.ietf.org/html/rfc7230#section-3.2.4 */ - private function trimHeaderValues(array $values) + private function trimHeaderValues(array $values): array { return array_map(function ($value) { return trim((string) $value, " \t"); diff --git a/src/http-message/src/Base/Request.php b/src/http-message/src/Base/Request.php index 1b83ab174..9ea86f846 100755 --- a/src/http-message/src/Base/Request.php +++ b/src/http-message/src/Base/Request.php @@ -21,27 +21,13 @@ class Request implements RequestInterface { use MessageTrait; - /** - * @var array - */ - protected $server = []; + protected array $server = []; - /** - * @var UriInterface - */ - protected $uri; + protected UriInterface $uri; - /** - * Http Method. - * - * @var string - */ - protected $method; + protected string $method; - /** - * @var string - */ - protected $requestTarget; + protected ?string $requestTarget = null; /** * @param string $method HTTP method @@ -52,9 +38,9 @@ class Request implements RequestInterface */ public function __construct( string $method, - $uri, + string|UriInterface $uri, array $headers = [], - $body = null, + mixed $body = null, string $version = '1.1' ) { if (! $uri instanceof UriInterface) { @@ -185,7 +171,7 @@ class Request implements RequestInterface * default if the URI contains a host component. If the URI does not * contain a host component, any pre-existing Host header MUST be carried * over to the returned request. - * You can opt-in to preserving the original state of the Host header by + * You can opt in to preserving the original state of the Host header by * setting `$preserveHost` to `true`. When `$preserveHost` is set to * `true`, this method interacts with the Host header in the following ways: * - If the Host header is missing or empty, and the new URI contains @@ -226,7 +212,7 @@ class Request implements RequestInterface * * @see http://tools.ietf.org/html/rfc7230#section-5.4 */ - private function updateHostFromUri() + private function updateHostFromUri(): void { $host = $this->uri->getHost(); diff --git a/src/http-message/src/Base/Response.php b/src/http-message/src/Base/Response.php index 7a957fa2f..df3c78cac 100755 --- a/src/http-message/src/Base/Response.php +++ b/src/http-message/src/Base/Response.php @@ -17,23 +17,17 @@ class Response implements ResponseInterface { use MessageTrait; - /** - * @var string - */ - protected $reasonPhrase = ''; + protected string $reasonPhrase = ''; + + protected int $statusCode = 200; + + protected string $charset = 'utf-8'; /** - * @var int + * Map of standard HTTP status code/reason phrases. + * @var array */ - protected $statusCode = 200; - - /** - * @var string - */ - protected $charset = 'utf-8'; - - /** @var array Map of standard HTTP status code/reason phrases */ - private static $phrases + private static array $phrases = [ 100 => 'Continue', 101 => 'Switching Protocols', @@ -95,10 +89,7 @@ class Response implements ResponseInterface 511 => 'Network Authentication Required', ]; - /** - * @var array - */ - private $attributes = []; + private array $attributes = []; public function __toString() { @@ -115,7 +106,7 @@ class Response implements ResponseInterface * * @return array attributes derived from the request */ - public function getAttributes() + public function getAttributes(): array { return $this->attributes; } @@ -332,7 +323,7 @@ class Response implements ResponseInterface 303, 307, 308, - ]) && ($location === null ?: $location == $this->getHeaderLine('Location')); + ]) && ($location === null || $location == $this->getHeaderLine('Location')); } /** diff --git a/src/http-message/src/Cookie/Cookie.php b/src/http-message/src/Cookie/Cookie.php index e0deef7c7..2fb7c5b52 100755 --- a/src/http-message/src/Cookie/Cookie.php +++ b/src/http-message/src/Cookie/Cookie.php @@ -11,7 +11,9 @@ declare(strict_types=1); */ namespace Hyperf\HttpMessage\Cookie; -class Cookie +use Stringable; + +class Cookie implements Stringable { public const SAMESITE_LAX = 'lax'; @@ -19,23 +21,11 @@ class Cookie public const SAMESITE_NONE = 'none'; - protected $name; + protected int $expire; - protected $value; + protected string $path; - protected $domain; - - protected $expire; - - protected $path; - - protected $secure; - - protected $httpOnly; - - private $raw; - - private $sameSite; + private ?string $sameSite = null; /** * @param string $name The name of the cookie @@ -51,14 +41,14 @@ class Cookie * @throws \InvalidArgumentException */ public function __construct( - string $name, - string $value = '', + protected string $name, + protected string $value = '', $expire = 0, string $path = '/', - string $domain = '', - bool $secure = false, - bool $httpOnly = true, - bool $raw = false, + protected string $domain = '', + protected bool $secure = false, + protected bool $httpOnly = true, + protected bool $raw = false, ?string $sameSite = null ) { // from PHP source code @@ -81,14 +71,8 @@ class Cookie } } - $this->name = $name; - $this->value = $value; - $this->domain = $domain; $this->expire = 0 < $expire ? (int) $expire : 0; $this->path = empty($path) ? '/' : $path; - $this->secure = (bool) $secure; - $this->httpOnly = (bool) $httpOnly; - $this->raw = (bool) $raw; if ($sameSite !== null) { $sameSite = strtolower($sameSite); @@ -110,7 +94,7 @@ class Cookie { $str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())) . '='; - if ((string) $this->getValue() === '') { + if ($this->getValue() === '') { $str .= 'deleted; expires=' . gmdate('D, d-M-Y H:i:s T', time() - 31536001) . '; max-age=-31536001'; } else { $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue()); @@ -148,11 +132,8 @@ class Cookie /** * Creates cookie from raw header string. - * - * @param string $cookie - * @param bool $decode */ - public static function fromString($cookie, $decode = false) + public static function fromString(string $cookie, bool $decode = false): self { $data = [ 'expires' => 0, @@ -164,7 +145,7 @@ class Cookie 'samesite' => null, ]; foreach (explode(';', $cookie) as $part) { - if (strpos($part, '=') === false) { + if (! str_contains($part, '=')) { $key = trim($part); $value = true; } else { @@ -205,110 +186,88 @@ class Cookie /** * Gets the name of the cookie. - * - * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** * Gets the value of the cookie. - * - * @return string */ - public function getValue() + public function getValue(): string { return $this->value; } /** * Gets the domain that the cookie is available to. - * - * @return null|string */ - public function getDomain() + public function getDomain(): string { return $this->domain; } /** * Gets the time the cookie expires. - * - * @return int */ - public function getExpiresTime() + public function getExpiresTime(): int { return $this->expire; } /** * Gets the max-age attribute. - * - * @return int */ - public function getMaxAge() + public function getMaxAge(): int { return $this->expire !== 0 ? $this->expire - time() : 0; } /** * Gets the path on the server in which the cookie will be available on. - * - * @return string */ - public function getPath() + public function getPath(): string { return $this->path; } /** * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client. - * - * @return bool */ - public function isSecure() + public function isSecure(): bool { return $this->secure; } /** * Checks whether the cookie will be made accessible only through the HTTP protocol. - * - * @return bool */ - public function isHttpOnly() + public function isHttpOnly(): bool { return $this->httpOnly; } /** * Whether this cookie is about to be cleared. - * - * @return bool */ - public function isCleared() + public function isCleared(): bool { return $this->expire < time(); } /** * Checks if the cookie value should be sent with no url encoding. - * - * @return bool */ - public function isRaw() + public function isRaw(): bool { return $this->raw; } /** * Gets the SameSite attribute. - * - * @return null|string */ - public function getSameSite() + public function getSameSite(): ?string { return $this->sameSite; } diff --git a/src/http-message/src/Cookie/CookieJar.php b/src/http-message/src/Cookie/CookieJar.php index b2b1ad37e..fa4797b8b 100755 --- a/src/http-message/src/Cookie/CookieJar.php +++ b/src/http-message/src/Cookie/CookieJar.php @@ -19,11 +19,11 @@ use Psr\Http\Message\ResponseInterface; */ class CookieJar implements CookieJarInterface { - /** @var SetCookie[] Loaded cookie data */ - private $cookies = []; - - /** @var bool */ - private $strictMode; + /** + * Loaded cookie data. + * @var SetCookie[] + */ + private array $cookies = []; /** * @param bool $strictMode set to true to throw exceptions when invalid @@ -32,10 +32,8 @@ class CookieJar implements CookieJarInterface * arrays that can be used with the SetCookie * constructor */ - public function __construct($strictMode = false, $cookieArray = []) + public function __construct(private $strictMode = false, $cookieArray = []) { - $this->strictMode = $strictMode; - foreach ($cookieArray as $cookie) { if (! ($cookie instanceof SetCookie)) { $cookie = new SetCookie($cookie); @@ -49,10 +47,8 @@ class CookieJar implements CookieJarInterface * * @param array $cookies Cookies to create the jar from * @param string $domain Domain to set the cookies to - * - * @return self */ - public static function fromArray(array $cookies, $domain) + public static function fromArray(array $cookies, string $domain): self { $cookieJar = new self(); foreach ($cookies as $name => $value) { @@ -73,12 +69,9 @@ class CookieJar implements CookieJarInterface * * @param SetCookie $cookie being evaluated * @param bool $allowSessionCookies If we should persist session cookies - * @return bool */ - public static function shouldPersist( - SetCookie $cookie, - $allowSessionCookies = false - ) { + public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = false): bool + { if ($cookie->getExpires() || $allowSessionCookies) { if (! $cookie->getDiscard()) { return true; @@ -94,7 +87,7 @@ class CookieJar implements CookieJarInterface * @param string $name cookie name to search for * @return null|SetCookie cookie that was found or null if not found */ - public function getCookieByName(string $name) + public function getCookieByName(string $name): ?SetCookie { foreach ($this->cookies as $cookie) { if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) { @@ -104,7 +97,7 @@ class CookieJar implements CookieJarInterface return null; } - public function toArray() + public function toArray(): array { return array_map(function (SetCookie $cookie) { return $cookie->toArray(); @@ -235,7 +228,7 @@ class CookieJar implements CookieJarInterface if (! $sc->getDomain()) { $sc->setDomain($request->getUri()->getHost()); } - if (strpos($sc->getPath(), '/') !== 0) { + if (! str_starts_with($sc->getPath(), '/')) { $sc->setPath($this->getCookiePathFromRequest($request)); } $this->setCookie($sc); @@ -271,16 +264,14 @@ class CookieJar implements CookieJarInterface * Computes cookie path following RFC 6265 section 5.1.4. * * @see https://tools.ietf.org/html/rfc6265#section-5.1.4 - * - * @return string */ - private function getCookiePathFromRequest(RequestInterface $request) + private function getCookiePathFromRequest(RequestInterface $request): string { $uriPath = $request->getUri()->getPath(); if ($uriPath === '') { return '/'; } - if (strpos($uriPath, '/') !== 0) { + if (! str_starts_with($uriPath, '/')) { return '/'; } if ($uriPath === '/') { @@ -297,7 +288,7 @@ class CookieJar implements CookieJarInterface * If a cookie already exists and the server asks to set it again with a * null value, the cookie must be deleted. */ - private function removeCookieIfEmpty(SetCookie $cookie) + private function removeCookieIfEmpty(SetCookie $cookie): void { $cookieValue = $cookie->getValue(); if ($cookieValue === null || $cookieValue === '') { diff --git a/src/http-message/src/Cookie/CookieJarInterface.php b/src/http-message/src/Cookie/CookieJarInterface.php index bfb6ed2f3..61a395d46 100755 --- a/src/http-message/src/Cookie/CookieJarInterface.php +++ b/src/http-message/src/Cookie/CookieJarInterface.php @@ -11,6 +11,7 @@ declare(strict_types=1); */ namespace Hyperf\HttpMessage\Cookie; +use Hyperf\Contract\Arrayable; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -24,7 +25,7 @@ use Psr\Http\Message\ResponseInterface; * * @see http://docs.python.org/2/library/cookielib.html Inspiration */ -interface CookieJarInterface extends \Countable, \IteratorAggregate +interface CookieJarInterface extends \Countable, \IteratorAggregate, Arrayable { /** * Create a request with added cookie headers. @@ -84,11 +85,4 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate * to RFC 2965. */ public function clearSessionCookies(); - - /** - * Converts the cookie jar to an array. - * - * @return array - */ - public function toArray(); } diff --git a/src/http-message/src/Cookie/FileCookieJar.php b/src/http-message/src/Cookie/FileCookieJar.php index e6f83fa63..fbce89705 100755 --- a/src/http-message/src/Cookie/FileCookieJar.php +++ b/src/http-message/src/Cookie/FileCookieJar.php @@ -11,33 +11,26 @@ declare(strict_types=1); */ namespace Hyperf\HttpMessage\Cookie; +use Hyperf\Utils\Codec\Json; + /** * Persists non-session cookies using a JSON formatted file. */ class FileCookieJar extends CookieJar { - /** @var string filename */ - private $filename; - - /** @var bool Control whether to persist session cookies or not. */ - private $storeSessionCookies; - /** * Create a new FileCookieJar object. * - * @param string $cookieFile File to store the cookie data - * @param bool $storeSessionCookies set to true to store session cookies - * in the cookie jar + * @param string $filename File to store the cookie data + * @param bool $storeSessionCookies Control whether to persist session cookies or not. + * Set to true to store session cookies in the cookie jar. * * @throws \RuntimeException if the file cannot be found or created */ - public function __construct($cookieFile, $storeSessionCookies = false) + public function __construct(private string $filename, private bool $storeSessionCookies = false) { - $this->filename = $cookieFile; - $this->storeSessionCookies = $storeSessionCookies; - - if (file_exists($cookieFile)) { - $this->load($cookieFile); + if (file_exists($filename)) { + $this->load($filename); } } @@ -55,7 +48,7 @@ class FileCookieJar extends CookieJar * @param string $filename File to save * @throws \RuntimeException if the file cannot be found or created */ - public function save($filename) + public function save(string $filename): void { $json = []; foreach ($this as $cookie) { @@ -65,7 +58,7 @@ class FileCookieJar extends CookieJar } } - $jsonStr = \GuzzleHttp\json_encode($json); + $jsonStr = Json::encode($json); if (file_put_contents($filename, $jsonStr) === false) { throw new \RuntimeException("Unable to save file {$filename}"); } @@ -79,7 +72,7 @@ class FileCookieJar extends CookieJar * @param string $filename cookie file to load * @throws \RuntimeException if the file cannot be loaded */ - public function load($filename) + public function load(string $filename): void { $json = file_get_contents($filename); if ($json === false) { @@ -89,9 +82,9 @@ class FileCookieJar extends CookieJar return; } - $data = \GuzzleHttp\json_decode($json, true); + $data = Json::decode($json); if (is_array($data)) { - foreach (json_decode($json, true) as $cookie) { + foreach ($data as $cookie) { $this->setCookie(new SetCookie($cookie)); } } elseif (strlen($data)) { diff --git a/src/http-message/src/Cookie/SessionCookieJar.php b/src/http-message/src/Cookie/SessionCookieJar.php index 1fd1c9f70..949602f1c 100755 --- a/src/http-message/src/Cookie/SessionCookieJar.php +++ b/src/http-message/src/Cookie/SessionCookieJar.php @@ -12,32 +12,21 @@ declare(strict_types=1); namespace Hyperf\HttpMessage\Cookie; /** - * Persists cookies in the client session. + * Persists cookies in the client session for FPM. */ class SessionCookieJar extends CookieJar { - /** - * @var string session key - */ - private $sessionKey; - - /** - * @var bool control whether to persist session cookies or not - */ - private $storeSessionCookies; - /** * Create a new SessionCookieJar object. * * @param string $sessionKey Session key name to store the cookie * data in session - * @param bool $storeSessionCookies set to true to store session cookies + * @param bool $storeSessionCookies Control whether to persist session cookies or not. + * set to true to store session cookies * in the cookie jar */ - public function __construct($sessionKey, $storeSessionCookies = false) + public function __construct(private string $sessionKey, private bool $storeSessionCookies = false) { - $this->sessionKey = $sessionKey; - $this->storeSessionCookies = $storeSessionCookies; $this->load(); } @@ -52,7 +41,7 @@ class SessionCookieJar extends CookieJar /** * Save cookies to the client session. */ - public function save() + public function save(): void { $json = []; foreach ($this as $cookie) { @@ -68,7 +57,7 @@ class SessionCookieJar extends CookieJar /** * Load the contents of the client session into the data array. */ - protected function load() + protected function load(): void { if (! isset($_SESSION[$this->sessionKey])) { return; diff --git a/src/http-message/src/Cookie/SetCookie.php b/src/http-message/src/Cookie/SetCookie.php index 125625414..7b89e0c8b 100755 --- a/src/http-message/src/Cookie/SetCookie.php +++ b/src/http-message/src/Cookie/SetCookie.php @@ -11,13 +11,15 @@ declare(strict_types=1); */ namespace Hyperf\HttpMessage\Cookie; +use Hyperf\Contract\Arrayable; +use Stringable; + /** * Set-Cookie object. */ -class SetCookie +class SetCookie implements Stringable, Arrayable { - /** @var array */ - private static $defaults = [ + private static array $defaults = [ 'Name' => null, 'Value' => null, 'Domain' => null, @@ -29,8 +31,10 @@ class SetCookie 'HttpOnly' => false, ]; - /** @var array Cookie data */ - private $data; + /** + * Array of cookie data provided by a Cookie parser. + */ + private array $data; /** * @param array $data Array of cookie data provided by a Cookie parser @@ -67,10 +71,8 @@ class SetCookie * Create a new SetCookie object from a string. * * @param string $cookie Set-Cookie header string - * - * @return self */ - public static function fromString($cookie) + public static function fromString(string $cookie): self { // Create the default return array $data = self::$defaults; @@ -107,17 +109,15 @@ class SetCookie return new self($data); } - public function toArray() + public function toArray(): array { return $this->data; } /** * Get the cookie name. - * - * @return string */ - public function getName() + public function getName(): ?string { return $this->data['Name']; } @@ -127,17 +127,15 @@ class SetCookie * * @param string $name Cookie name */ - public function setName($name) + public function setName(?string $name) { $this->data['Name'] = $name; } /** * Get the cookie value. - * - * @return null|string */ - public function getValue() + public function getValue(): ?string { return $this->data['Value']; } @@ -147,17 +145,15 @@ class SetCookie * * @param null|string $value Cookie value */ - public function setValue($value) + public function setValue(?string $value) { $this->data['Value'] = $value; } /** * Get the domain. - * - * @return null|string */ - public function getDomain() + public function getDomain(): ?string { return $this->data['Domain']; } @@ -167,17 +163,15 @@ class SetCookie * * @param string $domain */ - public function setDomain($domain) + public function setDomain(?string $domain) { $this->data['Domain'] = $domain; } /** * Get the path. - * - * @return string */ - public function getPath() + public function getPath(): string { return $this->data['Path']; } @@ -187,17 +181,15 @@ class SetCookie * * @param string $path Path of the cookie */ - public function setPath($path) + public function setPath(string $path) { $this->data['Path'] = $path; } /** * Maximum lifetime of the cookie in seconds. - * - * @return null|int */ - public function getMaxAge() + public function getMaxAge(): ?int { return $this->data['Max-Age']; } @@ -205,9 +197,9 @@ class SetCookie /** * Set the max-age of the cookie. * - * @param int $maxAge Max age of the cookie in seconds + * @param null|int $maxAge Max age of the cookie in seconds */ - public function setMaxAge($maxAge) + public function setMaxAge(?int $maxAge) { $this->data['Max-Age'] = $maxAge; } @@ -225,7 +217,7 @@ class SetCookie /** * Set the unix timestamp for which the cookie will expire. * - * @param int|string $timestamp Unix timestamp + * @param float|int|string $timestamp Unix timestamp */ public function setExpires($timestamp) { @@ -235,61 +227,55 @@ class SetCookie } /** - * Get whether or not this is a secure cookie. - * - * @return null|bool + * Get whether this is a secure cookie. */ - public function getSecure() + public function getSecure(): bool { return $this->data['Secure']; } /** - * Set whether or not the cookie is secure. + * Set whether the cookie is secure. * * @param bool $secure Set to true or false if secure */ - public function setSecure($secure) + public function setSecure(bool $secure) { $this->data['Secure'] = $secure; } /** - * Get whether or not this is a session cookie. - * - * @return null|bool + * Get whether this is a session cookie. */ - public function getDiscard() + public function getDiscard(): bool { return $this->data['Discard']; } /** - * Set whether or not this is a session cookie. + * Set whether this is a session cookie. * * @param bool $discard Set to true or false if this is a session cookie */ - public function setDiscard($discard) + public function setDiscard(bool $discard) { $this->data['Discard'] = $discard; } /** - * Get whether or not this is an HTTP only cookie. - * - * @return bool + * Get whether this is an HTTP only cookie. */ - public function getHttpOnly() + public function getHttpOnly(): bool { return $this->data['HttpOnly']; } /** - * Set whether or not this is an HTTP only cookie. + * Set whether this is an HTTP only cookie. * * @param bool $httpOnly Set to true or false if this is HTTP only */ - public function setHttpOnly($httpOnly) + public function setHttpOnly(bool $httpOnly) { $this->data['HttpOnly'] = $httpOnly; } @@ -308,10 +294,8 @@ class SetCookie * path is a %x2F ("/") character. * * @param string $requestPath Path to check against - * - * @return bool */ - public function matchesPath($requestPath) + public function matchesPath(string $requestPath): bool { $cookiePath = $this->getPath(); @@ -321,7 +305,7 @@ class SetCookie } // Ensure that the cookie-path is a prefix of the request path. - if (strpos($requestPath, $cookiePath) !== 0) { + if (! str_starts_with($requestPath, $cookiePath)) { return false; } @@ -338,10 +322,8 @@ class SetCookie * Check if the cookie matches a domain value. * * @param string $domain Domain to check against - * - * @return bool */ - public function matchesDomain($domain) + public function matchesDomain(string $domain): bool { // Remove the leading '.' as per spec in RFC 6265. // http://tools.ietf.org/html/rfc6265#section-5.2.3 @@ -363,10 +345,8 @@ class SetCookie /** * Check if the cookie is expired. - * - * @return bool */ - public function isExpired() + public function isExpired(): bool { return $this->getExpires() && time() > $this->getExpires(); } @@ -376,7 +356,7 @@ class SetCookie * * @return bool|string Returns true if valid or an error message if invalid */ - public function validate() + public function validate(): bool|string { // Names must not be empty, but can be 0 $name = $this->getName(); diff --git a/src/http-message/src/Exception/HttpException.php b/src/http-message/src/Exception/HttpException.php index c0684f9e2..c95acc279 100644 --- a/src/http-message/src/Exception/HttpException.php +++ b/src/http-message/src/Exception/HttpException.php @@ -17,20 +17,14 @@ use RuntimeException; class HttpException extends RuntimeException { /** - * @var int HTTP status - */ - public $statusCode; - - /** - * @param int $status HTTP status + * @param int $statusCode HTTP status * @param null|string $message error message * @param int $code error code */ - public function __construct($status, $message = '', $code = 0, \Throwable $previous = null) + public function __construct(public int $statusCode, $message = '', $code = 0, \Throwable $previous = null) { - $this->statusCode = $status; if (is_null($message)) { - $message = Response::getReasonPhraseByCode($status); + $message = Response::getReasonPhraseByCode($statusCode); } parent::__construct($message, $code, $previous); diff --git a/src/http-message/src/Server/Request.php b/src/http-message/src/Server/Request.php index 9d479dc7a..da7644ef3 100755 --- a/src/http-message/src/Server/Request.php +++ b/src/http-message/src/Server/Request.php @@ -20,62 +20,41 @@ use Hyperf\Utils\ApplicationContext; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\UploadedFileInterface; +use Psr\Http\Message\UriInterface; +use Swoole; class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestInterface { - /** - * @var \Swoole\Http\Request - */ - protected $swooleRequest; + protected ?Swoole\Http\Request $swooleRequest = null; - /** - * @var null|RequestParserInterface - */ - protected static $parser; + protected static ?RequestParserInterface $parser = null; - /** - * @var array - */ - private $attributes = []; + private array $attributes = []; - /** - * @var array - */ - private $cookieParams = []; + private array $cookieParams = []; /** * @var null|array|object */ private $parsedBody; - /** - * @var array - */ - private $queryParams = []; + private array $queryParams = []; - /** - * @var array - */ - private $serverParams = []; + private array $serverParams = []; - /** - * @var array - */ - private $uploadedFiles = []; + private array $uploadedFiles = []; /** * the body of parser. - * - * @var mixed */ - private $bodyParams; + private mixed $bodyParams; /** * Load a swoole request, and transfer to a psr-7 request object. * * @return \Hyperf\HttpMessage\Server\Request */ - public static function loadFromSwooleRequest(\Swoole\Http\Request $swooleRequest) + public static function loadFromSwooleRequest(Swoole\Http\Request $swooleRequest) { $server = $swooleRequest->server; $method = $server['request_method'] ?? 'GET'; @@ -108,10 +87,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI /** * Return an instance with the specified server params. - * - * @return static */ - public function withServerParams(array $serverParams) + public function withServerParams(array $serverParams): static { $clone = clone $this; $clone->serverParams = $serverParams; @@ -141,9 +118,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI * updated cookie values. * * @param array $cookies array of key/value pairs representing cookies - * @return static */ - public function withCookieParams(array $cookies) + public function withCookieParams(array $cookies): static { $clone = clone $this; $clone->cookieParams = $cookies; @@ -168,10 +144,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI * * @param string $name the name of param * @param mixed $value the value of param - * - * @return static */ - public function addQueryParam(string $name, $value) + public function addQueryParam(string $name, mixed $value): static { $clone = clone $this; $clone->queryParams[$name] = $value; @@ -260,10 +234,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI * * @param string $name the name of param * @param mixed $value the value of param - * - * @return static */ - public function addParserBody(string $name, $value) + public function addParserBody(string $name, mixed $value): static { if (is_array($this->parsedBody)) { $clone = clone $this; @@ -276,10 +248,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI /** * return parser result of body. - * - * @return mixed */ - public function getBodyParams() + public function getBodyParams(): mixed { return $this->bodyParams; } @@ -316,12 +286,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI /** * init body params from parser result. - * - * @param mixed $data - * - * @return static */ - public function withBodyParams($data) + public function withBodyParams(mixed $data): static { $clone = clone $this; $clone->bodyParams = $data; @@ -407,10 +373,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI /** * Get the URL (no query string) for the request. - * - * @return string */ - public function url() + public function url(): string { return rtrim(preg_replace('/\?.*/', '', (string) $this->getUri()), '/'); } @@ -427,10 +391,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI /** * Determine if the request is the result of an ajax call. - * - * @return bool */ - public function isAjax() + public function isAjax(): bool { return $this->isXmlHttpRequest(); } @@ -445,26 +407,23 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI * * @return bool true if the request is an XMLHttpRequest, false otherwise */ - public function isXmlHttpRequest() + public function isXmlHttpRequest(): bool { return $this->getHeaderLine('X-Requested-With') == 'XMLHttpRequest'; } - public function getSwooleRequest(): \Swoole\Http\Request + public function getSwooleRequest(): Swoole\Http\Request { return $this->swooleRequest; } - /** - * @return $this - */ - public function setSwooleRequest(\Swoole\Http\Request $swooleRequest) + public function setSwooleRequest(Swoole\Http\Request $swooleRequest): static { $this->swooleRequest = $swooleRequest; return $this; } - protected static function normalizeParsedBody(array $data = [], ?RequestInterface $request = null) + protected static function normalizeParsedBody(array $data = [], ?RequestInterface $request = null): array { if (! $request) { return $data; @@ -510,9 +469,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI * * @param array $files A array which respect $_FILES structure * @throws \InvalidArgumentException for unrecognized values - * @return array */ - private static function normalizeFiles(array $files) + private static function normalizeFiles(array $files): array { $normalized = []; @@ -523,7 +481,6 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI $normalized[$key] = self::createUploadedFileFromSpec($value); } elseif (is_array($value)) { $normalized[$key] = self::normalizeFiles($value); - continue; } else { throw new BadRequestHttpException('Invalid value in files specification'); } @@ -538,9 +495,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI * delegate to normalizeNestedFileSpec() and return that return value. * * @param array $value $_FILES struct - * @return array|UploadedFileInterface */ - private static function createUploadedFileFromSpec(array $value) + private static function createUploadedFileFromSpec(array $value): array|UploadedFileInterface { if (is_array($value['tmp_name'])) { return self::normalizeNestedFileSpec($value); @@ -556,7 +512,7 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI * * @return UploadedFileInterface[] */ - private static function normalizeNestedFileSpec(array $files = []) + private static function normalizeNestedFileSpec(array $files = []): array { $normalizedFiles = []; @@ -577,9 +533,8 @@ class Request extends \Hyperf\HttpMessage\Base\Request implements ServerRequestI /** * Get a Uri populated with values from $swooleRequest->server. * @throws \InvalidArgumentException - * @return \Psr\Http\Message\UriInterface */ - private static function getUriFromGlobals(\Swoole\Http\Request $swooleRequest) + private static function getUriFromGlobals(Swoole\Http\Request $swooleRequest): UriInterface { $server = $swooleRequest->server; $header = $swooleRequest->header; diff --git a/src/http-message/src/Server/Request/JsonParser.php b/src/http-message/src/Server/Request/JsonParser.php index e8c3775a3..fee3b69ee 100644 --- a/src/http-message/src/Server/Request/JsonParser.php +++ b/src/http-message/src/Server/Request/JsonParser.php @@ -18,15 +18,9 @@ use InvalidArgumentException; class JsonParser implements RequestParserInterface { - /** - * @var bool - */ - public $asArray = true; + public bool $asArray = true; - /** - * @var bool - */ - public $throwException = true; + public bool $throwException = true; public function parse(string $rawBody, string $contentType): array { diff --git a/src/http-message/src/Server/Request/Parser.php b/src/http-message/src/Server/Request/Parser.php index ccbaa25c5..cffd77ce9 100644 --- a/src/http-message/src/Server/Request/Parser.php +++ b/src/http-message/src/Server/Request/Parser.php @@ -15,7 +15,7 @@ use Hyperf\HttpMessage\Server\RequestParserInterface; class Parser implements RequestParserInterface { - protected $parsers = []; + protected array $parsers = []; public function __construct() { diff --git a/src/http-message/src/Server/Request/XmlParser.php b/src/http-message/src/Server/Request/XmlParser.php index 49467d194..bf6615ae7 100644 --- a/src/http-message/src/Server/Request/XmlParser.php +++ b/src/http-message/src/Server/Request/XmlParser.php @@ -18,7 +18,7 @@ use InvalidArgumentException; class XmlParser implements RequestParserInterface { - public $throwException = true; + public bool $throwException = true; public function parse(string $rawBody, string $contentType): array { diff --git a/src/http-message/src/Server/Response.php b/src/http-message/src/Server/Response.php index 73a7cb608..fb8442c2a 100755 --- a/src/http-message/src/Server/Response.php +++ b/src/http-message/src/Server/Response.php @@ -16,20 +16,14 @@ use Hyperf\HttpMessage\Stream\SwooleStream; class Response extends \Hyperf\HttpMessage\Base\Response { - /** - * @var array - */ - protected $cookies = []; + protected array $cookies = []; - /** - * @var array - */ - protected $trailers = []; + protected array $trailers = []; /** * Returns an instance with body content. */ - public function withContent(string $content): self + public function withContent(string $content): static { $new = clone $this; $new->stream = new SwooleStream($content); @@ -39,7 +33,7 @@ class Response extends \Hyperf\HttpMessage\Base\Response /** * Returns an instance with specified cookies. */ - public function withCookie(Cookie $cookie): self + public function withCookie(Cookie $cookie): static { $clone = clone $this; $clone->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; @@ -58,7 +52,7 @@ class Response extends \Hyperf\HttpMessage\Base\Response * Returns an instance with specified trailer. * @param string $value */ - public function withTrailer(string $key, $value): self + public function withTrailer(string $key, $value): static { $new = clone $this; $new->trailers[$key] = $value; diff --git a/src/http-message/src/Server/ResponseProxyTrait.php b/src/http-message/src/Server/ResponseProxyTrait.php index 7c5778609..8d7f42524 100644 --- a/src/http-message/src/Server/ResponseProxyTrait.php +++ b/src/http-message/src/Server/ResponseProxyTrait.php @@ -18,10 +18,7 @@ use RuntimeException; trait ResponseProxyTrait { - /** - * @var null|ResponseInterface - */ - protected $response; + protected ?ResponseInterface $response = null; public function setResponse(ResponseInterface $response) { @@ -115,7 +112,7 @@ trait ResponseProxyTrait /** * Returns an instance with specified cookies. */ - public function withCookie(Cookie $cookie): self + public function withCookie(Cookie $cookie): static { $response = $this->getResponse(); if (! method_exists($response, 'withCookie')) { @@ -142,7 +139,7 @@ trait ResponseProxyTrait * Returns an instance with specified trailer. * @param string $value */ - public function withTrailer(string $key, $value): self + public function withTrailer(string $key, $value): static { $response = $this->getResponse(); if (! method_exists($response, 'withTrailer')) { diff --git a/src/http-message/src/Stream/SwooleFileStream.php b/src/http-message/src/Stream/SwooleFileStream.php index 1b266ce09..0e11a16e1 100644 --- a/src/http-message/src/Stream/SwooleFileStream.php +++ b/src/http-message/src/Stream/SwooleFileStream.php @@ -13,18 +13,14 @@ namespace Hyperf\HttpMessage\Stream; use Hyperf\HttpServer\Exception\Http\FileException; use Psr\Http\Message\StreamInterface; +use SplFileInfo; +use Stringable; -class SwooleFileStream implements StreamInterface, FileInterface +class SwooleFileStream implements StreamInterface, FileInterface, Stringable { - /** - * @var int - */ - protected $size; + protected int $size; - /** - * @var \SplFileInfo - */ - protected $file; + protected SplFileInfo $file; /** * SwooleFileStream constructor. @@ -33,8 +29,8 @@ class SwooleFileStream implements StreamInterface, FileInterface */ public function __construct($file) { - if (! $file instanceof \SplFileInfo) { - $file = new \SplFileInfo($file); + if (! $file instanceof SplFileInfo) { + $file = new SplFileInfo($file); } if (! $file->isReadable()) { throw new FileException('File must be readable.'); @@ -58,7 +54,7 @@ class SwooleFileStream implements StreamInterface, FileInterface { try { return $this->getContents(); - } catch (\Throwable $e) { + } catch (\Throwable) { return ''; } } @@ -117,7 +113,7 @@ class SwooleFileStream implements StreamInterface, FileInterface } /** - * Returns whether or not the stream is seekable. + * Returns whether the stream is seekable. * * @return bool */ @@ -158,7 +154,7 @@ class SwooleFileStream implements StreamInterface, FileInterface } /** - * Returns whether or not the stream is writable. + * Returns whether the stream is writable. * * @return bool */ @@ -180,7 +176,7 @@ class SwooleFileStream implements StreamInterface, FileInterface } /** - * Returns whether or not the stream is readable. + * Returns whether the stream is readable. * * @return bool */ @@ -192,8 +188,8 @@ class SwooleFileStream implements StreamInterface, FileInterface /** * Read data from the stream. * - * @param int $length Read up to $length bytes from the object and return - * them. Fewer than $length bytes may be returned if underlying stream + * @param int $length Read up to $length bytes from the object and return them. + * Fewer than $length bytes may be returned if underlying stream * call returns fewer bytes. * @throws \RuntimeException if an error occurs * @return string returns the data read from the stream, or an empty string diff --git a/src/http-message/src/Stream/SwooleStream.php b/src/http-message/src/Stream/SwooleStream.php index 621e74396..3f15e0aa8 100755 --- a/src/http-message/src/Stream/SwooleStream.php +++ b/src/http-message/src/Stream/SwooleStream.php @@ -12,30 +12,19 @@ declare(strict_types=1); namespace Hyperf\HttpMessage\Stream; use Psr\Http\Message\StreamInterface; +use Stringable; -class SwooleStream implements StreamInterface +class SwooleStream implements StreamInterface, Stringable { - /** - * @var string - */ - protected $contents; + protected int $size; - /** - * @var int - */ - protected $size; - - /** - * @var bool - */ - protected $writable; + protected bool $writable; /** * SwooleStream constructor. */ - public function __construct(string $contents = '') + public function __construct(protected string $contents = '') { - $this->contents = $contents; $this->size = strlen($this->contents); $this->writable = true; } @@ -55,7 +44,7 @@ class SwooleStream implements StreamInterface { try { return $this->getContents(); - } catch (\Throwable $e) { + } catch (\Throwable) { return ''; } } diff --git a/src/http-message/src/Upload/UploadedFile.php b/src/http-message/src/Upload/UploadedFile.php index 303f4ef1d..8e1dd6537 100755 --- a/src/http-message/src/Upload/UploadedFile.php +++ b/src/http-message/src/Upload/UploadedFile.php @@ -20,7 +20,7 @@ class UploadedFile extends \SplFileInfo implements UploadedFileInterface /** * @var int[] */ - private static $errors = [ + private static array $errors = [ UPLOAD_ERR_OK, UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, @@ -31,53 +31,30 @@ class UploadedFile extends \SplFileInfo implements UploadedFileInterface UPLOAD_ERR_EXTENSION, ]; - /** - * @var null|string - */ - private $clientFilename; + private ?string $tmpFile = null; - /** - * @var null|string - */ - private $clientMediaType; - - /** - * @var int - */ - private $error; - - /** - * @var string - */ - private $tmpFile; - - /** - * @var bool - */ - private $moved = false; - - /** - * @var null|int - */ - private $size; + private bool $moved = false; /** * @var null|string */ private $mimeType; + /** + * @param int $size The file size + * @param int $error The error associated with the uploaded file + * @param null|string $clientFilename The filename sent by the client + * @param null|string $clientMediaType The media type sent by the client + */ public function __construct( string $tmpFile, - ?int $size, - int $errorStatus, - ?string $clientFilename = null, - ?string $clientMediaType = null + private int $size, + private int $error, + private ?string $clientFilename = null, + private ?string $clientMediaType = null ) { - $this->setError($errorStatus) - ->setSize($size) - ->setClientFilename($clientFilename) - ->setClientMediaType($clientMediaType); - $this->isOk() && $this->setFile($tmpFile); + $this->checkError($this->error); + $this->isOk() && $this->tmpFile = $tmpFile; parent::__construct($tmpFile); } @@ -120,7 +97,7 @@ class UploadedFile extends \SplFileInfo implements UploadedFileInterface } /** - * Determire if the temp file is moved. + * Determine if the temp file is moved. */ public function isMoved(): bool { @@ -200,7 +177,7 @@ class UploadedFile extends \SplFileInfo implements UploadedFileInterface * * @return null|int the file size in bytes or null if unknown */ - public function getSize(): ?int + public function getSize() { return $this->size; } @@ -264,71 +241,11 @@ class UploadedFile extends \SplFileInfo implements UploadedFileInterface ]; } - /** - * Depending on the value set file or stream variable. - */ - private function setFile(string $file): self - { - $this->tmpFile = $file; - return $this; - } - - /** - * @throws \InvalidArgumentException If invalid error status for UploadedFile - */ - private function setError(int $error): self + private function checkError(int $error): void { if (in_array($error, UploadedFile::$errors) === false) { throw new \InvalidArgumentException('Invalid error status for UploadedFile'); } - - $this->error = $error; - return $this; - } - - /** - * @param null|int $size the file size in bytes or null if unknown - * @throws \InvalidArgumentException if the size is not a interger - */ - private function setSize($size): self - { - if (is_int($size) === false) { - throw new \InvalidArgumentException('Upload file size must be an integer'); - } - - $this->size = $size; - return $this; - } - - /** - * @throws \InvalidArgumentException - */ - private function setClientFilename(?string $clientFilename): self - { - if ($this->isStringOrNull($clientFilename) === false) { - throw new \InvalidArgumentException('Upload file client filename must be a string or null'); - } - - $this->clientFilename = $clientFilename; - return $this; - } - - /** - * @throws \InvalidArgumentException - */ - private function setClientMediaType(?string $clientMediaType): self - { - if ($this->isStringOrNull($clientMediaType) === false) { - throw new \InvalidArgumentException('Upload file client media type must be a string or null'); - } - - $this->clientMediaType = $clientMediaType; - return $this; - } - - private function isStringOrNull($param): bool - { - return in_array(gettype($param), ['string', 'NULL']); } private function isStringNotEmpty($param): bool diff --git a/src/http-message/src/Uri/Uri.php b/src/http-message/src/Uri/Uri.php index c48371c8b..4a8afcc46 100755 --- a/src/http-message/src/Uri/Uri.php +++ b/src/http-message/src/Uri/Uri.php @@ -12,8 +12,9 @@ declare(strict_types=1); namespace Hyperf\HttpMessage\Uri; use Psr\Http\Message\UriInterface; +use Stringable; -class Uri implements UriInterface +class Uri implements UriInterface, Stringable { /** * Absolute http and https URIs require a host per RFC 7230 Section 2.7 @@ -23,71 +24,58 @@ class Uri implements UriInterface */ public const DEFAULT_HTTP_HOST = 'localhost'; - /** - * @var array - */ - private static $defaultPorts = [ + private static array $defaultPorts = [ 'http' => 80, 'https' => 443, ]; - /** - * @var string - */ - private static $charUnreserved = 'a-zA-Z0-9_\-\.~'; + private static string $charUnreserved = 'a-zA-Z0-9_\-\.~'; + + private static string $charSubDelims = '!\$&\'\(\)\*\+,;='; + + private static array $replaceQuery = ['=' => '%3D', '&' => '%26']; /** - * @var string + * uri scheme. */ - private static $charSubDelims = '!\$&\'\(\)\*\+,;='; + private string $scheme = ''; /** - * @var array + * uri user info. */ - private static $replaceQuery = ['=' => '%3D', '&' => '%26']; + private string $userInfo = ''; /** - * @var string uri scheme + * uri host. */ - private $scheme = ''; + private string $host = ''; /** - * @var string uri user info + * uri port. */ - private $userInfo = ''; + private ?int $port = null; /** - * @var string uri host + * uri path. */ - private $host = ''; + private string $path = ''; /** - * @var null|int uri port + * uri query string. */ - private $port; + private string $query = ''; /** - * @var string uri path + * uri fragment. */ - private $path = ''; - - /** - * @var string uri query string - */ - private $query = ''; - - /** - * @var string uri fragment - */ - private $fragment = ''; + private string $fragment = ''; /** * @param string $uri URI to parse */ - public function __construct($uri = '') + public function __construct(string $uri = '') { - // weak type check to also accept null until we can add scalar type hints - if ($uri != '') { + if ($uri) { $parts = parse_url($uri); if ($parts === false) { throw new \InvalidArgumentException("Unable to parse URI: {$uri}"); @@ -253,7 +241,7 @@ class Uri implements UriInterface * The value returned MUST be percent-encoded, but MUST NOT double-encode * any characters. To determine what characters to encode, please refer to * RFC 3986, Sections 2 and 3.4. - * As an example, if a value in a key/value pair of the query string should + * As an example, if a value in a key/value a pair of the query string should * include an ampersand ("&") not intended as a delimiter between values, * that value MUST be passed in encoded form (e.g., "%26") to the instance. * @@ -318,7 +306,7 @@ class Uri implements UriInterface * user; an empty string for the user is equivalent to removing user * information. * - * @param string $user the user name to use for authority + * @param string $user the username to use for authority * @param null|string $password the password associated with $user * @return static a new instance with the specified user information */ @@ -448,9 +436,8 @@ class Uri implements UriInterface * @param UriInterface $uri URI to use as a base * @param string $key key to set * @param null|string $value Value to set - * @return UriInterface */ - public static function withQueryValue(UriInterface $uri, $key, $value) + public static function withQueryValue(UriInterface $uri, string $key, ?string $value): UriInterface { $current = $uri->getQuery(); @@ -512,18 +499,12 @@ class Uri implements UriInterface * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to * that format). * - * @param string $scheme - * @param string $authority - * @param string $path - * @param string $query - * @param string $fragment * @return string * @see https://tools.ietf.org/html/rfc3986#section-5.3 */ - public static function composeComponents($scheme, $authority, $path, $query, $fragment) + public static function composeComponents(string $scheme, string $authority, string $path, string $query, string $fragment) { $uri = ''; - // weak type checks to also accept null until we can add scalar type hints if ($scheme != '') { $uri .= $scheme . ':'; } @@ -553,10 +534,8 @@ class Uri implements UriInterface /** * Get default port of the current scheme. - * - * @return null|int */ - public function getDefaultPort() + public function getDefaultPort(): ?int { return self::$defaultPorts[$this->getScheme()] ?? null; } @@ -570,10 +549,10 @@ class Uri implements UriInterface $this->host = self::DEFAULT_HTTP_HOST; } if ($this->getAuthority() === '') { - if (strpos($this->path, '//') === 0) { + if (str_starts_with($this->path, '//')) { throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"'); } - if ($this->scheme === '' && strpos(explode('/', $this->path, 2)[0], ':') !== false) { + if ($this->scheme === '' && str_contains(explode('/', $this->path, 2)[0], ':')) { throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon'); } } elseif (isset($this->path[0]) && $this->path[0] !== '/') { @@ -589,7 +568,7 @@ class Uri implements UriInterface private function applyParts(array $parts) { $this->scheme = isset($parts['scheme']) ? $this->filterScheme($parts['scheme']) : ''; - $this->userInfo = isset($parts['user']) ? $parts['user'] : ''; + $this->userInfo = $parts['user'] ?? ''; $this->host = isset($parts['host']) ? $this->filterHost($parts['host']) : ''; $this->port = isset($parts['port']) ? $this->filterPort($parts['port']) : null; $this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : ''; @@ -602,40 +581,20 @@ class Uri implements UriInterface $this->removeDefaultPort(); } - /** - * @param string $scheme - * @throws \InvalidArgumentException if the scheme is invalid - * @return string - */ - private function filterScheme($scheme) + private function filterScheme(string $scheme): string { - if (! is_string($scheme)) { - throw new \InvalidArgumentException('Scheme must be a string'); - } - return strtolower($scheme); } - /** - * @param string $host - * @throws \InvalidArgumentException if the host is invalid - * @return string - */ - private function filterHost($host) + private function filterHost(string $host): string { - if (! is_string($host)) { - throw new \InvalidArgumentException('Host must be a string'); - } - return strtolower($host); } /** * @param null|int|string $port - * @throws \InvalidArgumentException if the port is invalid - * @return null|int */ - private function filterPort($port) + private function filterPort($port): ?int { if ($port === null) { return null; @@ -652,7 +611,7 @@ class Uri implements UriInterface /** * Remove the port property when the property is a default port. */ - private function removeDefaultPort() + private function removeDefaultPort(): void { if ($this->port !== null && $this->isDefaultPort()) { $this->port = null; @@ -662,16 +621,10 @@ class Uri implements UriInterface /** * Filters the path of a URI. * - * @param string $path * @throws \InvalidArgumentException if the path is invalid - * @return string */ - private function filterPath($path) + private function filterPath(string $path): string { - if (! is_string($path)) { - throw new \InvalidArgumentException('Path must be a string'); - } - return preg_replace_callback( '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/', [ @@ -684,17 +637,9 @@ class Uri implements UriInterface /** * Filters the query string or fragment of a URI. - * - * @param string $str - * @throws \InvalidArgumentException if the query or fragment is invalid - * @return string */ - private function filterQueryAndFragment($str) + private function filterQueryAndFragment(string $str): string { - if (! is_string($str)) { - throw new \InvalidArgumentException('Query and fragment must be a string'); - } - return preg_replace_callback( '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [ @@ -705,10 +650,7 @@ class Uri implements UriInterface ); } - /** - * @return string - */ - private function rawurlencodeMatchZero(array $match) + private function rawurlencodeMatchZero(array $match): string { return rawurlencode($match[0]); } diff --git a/src/http-message/tests/Stub/Server/RequestStub.php b/src/http-message/tests/Stub/Server/RequestStub.php index e07f5c879..2d3f350ed 100644 --- a/src/http-message/tests/Stub/Server/RequestStub.php +++ b/src/http-message/tests/Stub/Server/RequestStub.php @@ -17,7 +17,7 @@ use Psr\Http\Message\RequestInterface; class RequestStub extends Request { - public static function normalizeParsedBody(array $data = [], ?RequestInterface $request = null) + public static function normalizeParsedBody(array $data = [], ?RequestInterface $request = null): array { return parent::normalizeParsedBody($data, $request); } diff --git a/src/utils/src/Contracts/Arrayable.php b/src/utils/src/Contracts/Arrayable.php index 1c80f65d0..9b39c47ed 100644 --- a/src/utils/src/Contracts/Arrayable.php +++ b/src/utils/src/Contracts/Arrayable.php @@ -11,7 +11,8 @@ declare(strict_types=1); */ namespace Hyperf\Utils\Contracts; -interface Arrayable +use Hyperf\Contract; + +interface Arrayable extends Contract\Arrayable { - public function toArray(): array; }