diff --git a/src/swoole_library/src/__init__.php b/src/swoole_library/src/__init__.php index 30b60703..669b2c25 100644 --- a/src/swoole_library/src/__init__.php +++ b/src/swoole_library/src/__init__.php @@ -9,10 +9,10 @@ declare(strict_types=1); return [ - 'name' => 'swoole', + 'name' => 'swoole', 'checkFileChange' => !getenv('SWOOLE_LIBRARY_DEV'), - 'output' => getenv('SWOOLE_DIR') . '/ext-src/php_swoole_library.h', - 'stripComments' => false, + 'output' => getenv('SWOOLE_DIR') . '/ext-src/php_swoole_library.h', + 'stripComments' => false, /* Notice: Sort by dependency */ 'files' => [ # # diff --git a/src/swoole_library/src/alias.php b/src/swoole_library/src/alias.php index 306b8b26..0db2bc9d 100644 --- a/src/swoole_library/src/alias.php +++ b/src/swoole_library/src/alias.php @@ -9,7 +9,7 @@ declare(strict_types=1); -if (SWOOLE_USE_SHORTNAME) { +if (SWOOLE_USE_SHORTNAME) { // @phpstan-ignore if.alwaysTrue class_alias(Swoole\Coroutine\WaitGroup::class, Co\WaitGroup::class, true); class_alias(Swoole\Coroutine\Server::class, Co\Server::class, true); class_alias(Swoole\Coroutine\Server\Connection::class, Co\Server\Connection::class, true); diff --git a/src/swoole_library/src/alias_ns.php b/src/swoole_library/src/alias_ns.php index 47a4b69f..da6b9e1b 100644 --- a/src/swoole_library/src/alias_ns.php +++ b/src/swoole_library/src/alias_ns.php @@ -13,7 +13,7 @@ use Swoole\Coroutine; -if (SWOOLE_USE_SHORTNAME) { +if (SWOOLE_USE_SHORTNAME) { // @phpstan-ignore if.alwaysTrue function run(callable $fn, ...$args) { return \Swoole\Coroutine\run($fn, ...$args); diff --git a/src/swoole_library/src/core/ArrayObject.php b/src/swoole_library/src/core/ArrayObject.php index e4d37710..83b899af 100644 --- a/src/swoole_library/src/core/ArrayObject.php +++ b/src/swoole_library/src/core/ArrayObject.php @@ -43,9 +43,9 @@ public function __unserialize(array $data): void $this->array = $data; } - public static function from(array $array = []): self + public static function from(array $array = []): static { - return new static($array); + return new static($array); // @phpstan-ignore new.static } public function toArray(): array @@ -105,10 +105,9 @@ public function next() } /** - * @param mixed $key * @return ArrayObject|StringObject */ - public function get($key) + public function get(mixed $key) { if (!$this->exists($key)) { throw new ArrayKeyNotExists($key); @@ -117,11 +116,9 @@ public function get($key) } /** - * @param mixed $key - * @param mixed $default * @return ArrayObject|StringObject */ - public function getOr($key, $default = null) + public function getOr(mixed $key, mixed $default = null) { if (!$this->exists($key)) { return $default; @@ -142,7 +139,7 @@ public function last() } /** - * @return null|int|string + * @return int|string|null */ public function firstKey() { @@ -150,7 +147,7 @@ public function firstKey() } /** - * @return null|int|string + * @return int|string|null */ public function lastKey() { @@ -170,31 +167,27 @@ public function first() } /** - * @param mixed $key - * @param mixed $value * @return $this */ - public function set($key, $value): self + public function set(mixed $key, mixed $value): self { $this->array[$key] = $value; return $this; } /** - * @param mixed $key * @return $this */ - public function delete($key): self + public function delete(mixed $key): self { unset($this->array[$key]); return $this; } /** - * @param mixed $value * @return $this */ - public function remove($value, bool $strict = true, bool $loop = false): self + public function remove(mixed $value, bool $strict = true, bool $loop = false): self { do { $key = $this->search($value, $strict); @@ -217,11 +210,10 @@ public function clear(): self } /** - * @param mixed $key - * @return null|mixed + * @return mixed|null */ #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet(mixed $key) { if (!array_key_exists($key, $this->array)) { return null; @@ -229,63 +221,47 @@ public function offsetGet($key) return $this->array[$key]; } - /** - * @param mixed $key - * @param mixed $value - */ - public function offsetSet($key, $value): void + public function offsetSet(mixed $key, mixed $value): void { $this->array[$key] = $value; } - /** - * @param mixed $key - */ - public function offsetUnset($key): void + public function offsetUnset(mixed $key): void { unset($this->array[$key]); } /** - * @param mixed $key * @return bool */ #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists(mixed $key) { return isset($this->array[$key]); } - /** - * @param mixed $key - */ - public function exists($key): bool + public function exists(mixed $key): bool { return array_key_exists($key, $this->array); } - /** - * @param mixed $value - */ - public function contains($value, bool $strict = true): bool + public function contains(mixed $value, bool $strict = true): bool { return in_array($value, $this->array, $strict); } /** - * @param mixed $value * @return mixed */ - public function indexOf($value, bool $strict = true) + public function indexOf(mixed $value, bool $strict = true) { return $this->search($value, $strict); } /** - * @param mixed $value * @return mixed */ - public function lastIndexOf($value, bool $strict = true) + public function lastIndexOf(mixed $value, bool $strict = true) { $array = $this->array; for (end($array); ($currentKey = key($array)) !== null; prev($array)) { @@ -301,22 +277,21 @@ public function lastIndexOf($value, bool $strict = true) } /** - * @param mixed $needle * @return mixed */ - public function search($needle, bool $strict = true) + public function search(mixed $needle, bool $strict = true) { return array_search($needle, $this->array, $strict); } public function join(string $glue = ''): StringObject { - return static::detectStringType(implode($glue, $this->array)); + return self::detectStringType(implode($glue, $this->array)); } public function serialize(): StringObject { - return static::detectStringType(serialize($this->array)); + return self::detectStringType(serialize($this->array)); } /** @@ -346,19 +321,17 @@ public function product() } /** - * @param mixed $value * @return int */ - public function push($value) + public function push(mixed $value) { return $this->pushBack($value); } /** - * @param mixed $value * @return int */ - public function pushFront($value) + public function pushFront(mixed $value) { return array_unshift($this->array, $value); } @@ -370,19 +343,17 @@ public function append(...$values): ArrayObject } /** - * @param mixed $value * @return int */ - public function pushBack($value) + public function pushBack(mixed $value) { return array_push($this->array, $value); } /** - * @param mixed $value * @return $this */ - public function insert(int $offset, $value): self + public function insert(int $offset, mixed $value): self { if (is_array($value) || is_object($value) || is_null($value)) { $value = [$value]; @@ -415,14 +386,9 @@ public function popBack() return array_pop($this->array); } - /** - * @param mixed $offset - * @param int $length - * @return static - */ - public function slice($offset, int $length = null, bool $preserve_keys = false): self + public function slice(int $offset, ?int $length = null, bool $preserve_keys = false): static { - return new static(array_slice($this->array, ...func_get_args())); + return new static(array_slice($this->array, $offset, $length, $preserve_keys)); // @phpstan-ignore new.static } /** @@ -433,24 +399,19 @@ public function randomGet() return static::detectType($this->array[array_rand($this->array, 1)]); } - /** - * @return $this - */ public function each(callable $fn): self { - if (array_walk($this->array, $fn) === false) { - throw new \RuntimeException('array_walk() failed'); - } + array_walk($this->array, $fn); + return $this; } /** * @param array $args - * @return static */ - public function map(callable $fn, ...$args): self + public function map(callable $fn, ...$args): static { - return new static(array_map($fn, $this->array, ...$args)); + return new static(array_map($fn, $this->array, ...$args)); // @phpstan-ignore new.static } /** @@ -464,76 +425,54 @@ public function reduce(callable $fn, $initial = null) /** * @param array $args - * @return static */ - public function keys(...$args): self + public function keys(...$args): static { - return new static(array_keys($this->array, ...$args)); + return new static(array_keys($this->array, ...$args)); // @phpstan-ignore new.static } - /** - * @return static - */ - public function values(): self + public function values(): static { - return new static(array_values($this->array)); + return new static(array_values($this->array)); // @phpstan-ignore new.static } - /** - * @param mixed $column_key - * @param mixed $index - * @return static - */ - public function column($column_key, $index = null): self + public function column(mixed $column_key, mixed $index = null): static { - return new static(array_column($this->array, $column_key, $index)); + return new static(array_column($this->array, $column_key, $index)); // @phpstan-ignore new.static } - /** - * @return static - */ - public function unique(int $sort_flags = SORT_STRING): self + public function unique(int $sort_flags = SORT_STRING): static { - return new static(array_unique($this->array, $sort_flags)); + return new static(array_unique($this->array, $sort_flags)); // @phpstan-ignore new.static } - /** - * @return static - */ - public function reverse(bool $preserve_keys = false): self + public function reverse(bool $preserve_keys = false): static { - return new static(array_reverse($this->array, $preserve_keys)); + return new static(array_reverse($this->array, $preserve_keys)); // @phpstan-ignore new.static } - /** - * @return static - */ - public function chunk(int $size, bool $preserve_keys = false): self + public function chunk(int $size, bool $preserve_keys = false): static { - return new static(array_chunk($this->array, $size, $preserve_keys)); + return new static(array_chunk($this->array, $size, $preserve_keys)); // @phpstan-ignore new.static } /** * Swap keys and values in an array. - * @return static */ - public function flip(): self + public function flip(): static { - return new static(array_flip($this->array)); + return new static(array_flip($this->array)); // @phpstan-ignore new.static } - /** - * @return static - */ - public function filter(callable $fn, int $flag = 0): self + public function filter(callable $fn, int $flag = 0): static { - return new static(array_filter($this->array, $fn, $flag)); + return new static(array_filter($this->array, $fn, $flag)); // @phpstan-ignore new.static } /** * | Function name | Sorts by | Maintains key association | Order of sort | Related functions | * | :---------------- | :------- | :-------------------------- | :-------------------------- | :---------------- | - * | array_multisort() | value | associative yes, numeric no | first array or sort options | array_walk() | + * | array_multisort() | value | associative yes, numeric no | first array or sort options | array_walk() | * | asort() | value | yes | low to high | arsort() | * | arsort() | value | yes | high to low | asort() | * | krsort() | key | yes | high to low | ksort() | @@ -541,11 +480,11 @@ public function filter(callable $fn, int $flag = 0): self * | natcasesort() | value | yes | natural, case insensitive | natsort() | * | natsort() | value | yes | natural | natcasesort() | * | rsort() | value | no | high to low | sort() | - * | shuffle() | value | no | random | array_rand() | + * | shuffle() | value | no | random | array_rand() | * | sort() | value | no | low to high | rsort() | - * | uasort() | value | yes | user defined | uksort() | - * | uksort() | key | yes | user defined | uasort() | - * | usort() | value | no | user defined | uasort() | + * | uasort() | value | yes | user defined | uksort() | + * | uksort() | key | yes | user defined | uasort() | + * | usort() | value | no | user defined | uasort() | */ /** @@ -553,42 +492,29 @@ public function filter(callable $fn, int $flag = 0): self */ public function asort(int $sort_flags = SORT_REGULAR): self { - if (asort($this->array, $sort_flags) !== true) { - throw new \RuntimeException('asort() failed'); - } + asort($this->array, $sort_flags); + return $this; } - /** - * @return $this - */ public function arsort(int $sort_flags = SORT_REGULAR): self { - if (arsort($this->array, $sort_flags) !== true) { - throw new \RuntimeException('arsort() failed'); - } + arsort($this->array, $sort_flags); + return $this; } - /** - * @return $this - */ public function krsort(int $sort_flags = SORT_REGULAR): self { - if (krsort($this->array, $sort_flags) !== true) { - throw new \RuntimeException('krsort() failed'); - } + krsort($this->array, $sort_flags); + return $this; } - /** - * @return $this - */ public function ksort(int $sort_flags = SORT_REGULAR): self { - if (ksort($this->array, $sort_flags) !== true) { - throw new \RuntimeException('ksort() failed'); - } + ksort($this->array, $sort_flags); + return $this; } @@ -625,66 +551,45 @@ public function rsort(int $sort_flags = SORT_REGULAR): self return $this; } - /** - * @return $this - */ public function shuffle(): self { - if (shuffle($this->array) !== true) { - throw new \RuntimeException('shuffle() failed'); - } + shuffle($this->array); + return $this; } - /** - * @return $this - */ public function sort(int $sort_flags = SORT_REGULAR): self { - if (sort($this->array, $sort_flags) !== true) { - throw new \RuntimeException('sort() failed'); - } + sort($this->array, $sort_flags); + return $this; } - /** - * @return $this - */ public function uasort(callable $value_compare_func): self { - if (uasort($this->array, $value_compare_func) !== true) { - throw new \RuntimeException('uasort() failed'); - } + uasort($this->array, $value_compare_func); + return $this; } - /** - * @return $this - */ public function uksort(callable $value_compare_func): self { - if (uksort($this->array, $value_compare_func) !== true) { - throw new \RuntimeException('uksort() failed'); - } + uksort($this->array, $value_compare_func); + return $this; } - /** - * @return $this - */ public function usort(callable $value_compare_func): self { - if (usort($this->array, $value_compare_func) !== true) { - throw new \RuntimeException('usort() failed'); - } + usort($this->array, $value_compare_func); + return $this; } /** - * @param mixed $value * @return ArrayObject|mixed|StringObject */ - protected static function detectType($value) + protected static function detectType(mixed $value) { if (is_string($value)) { return static::detectStringType($value); @@ -700,11 +605,8 @@ protected static function detectStringType(string $value): StringObject return new StringObject($value); } - /** - * @return static - */ - protected static function detectArrayType(array $value): self + protected static function detectArrayType(array $value): static { - return new static($value); + return new static($value); // @phpstan-ignore new.static } } diff --git a/src/swoole_library/src/core/ConnectionPool.php b/src/swoole_library/src/core/ConnectionPool.php index 1973c642..61ceccc3 100644 --- a/src/swoole_library/src/core/ConnectionPool.php +++ b/src/swoole_library/src/core/ConnectionPool.php @@ -17,27 +17,19 @@ class ConnectionPool { public const DEFAULT_SIZE = 64; - /** @var Channel */ - protected $pool; + protected ?Channel $pool; /** @var callable */ protected $constructor; - /** @var int */ - protected $size; + protected int $size; - /** @var int */ - protected $num; + protected int $num = 0; - /** @var null|string */ - protected $proxy; - - public function __construct(callable $constructor, int $size = self::DEFAULT_SIZE, ?string $proxy = null) + public function __construct(callable $constructor, int $size = self::DEFAULT_SIZE, protected ?string $proxy = null) { - $this->pool = new Channel($this->size = $size); + $this->pool = new Channel($this->size = $size); $this->constructor = $constructor; - $this->num = 0; - $this->proxy = $proxy; } public function fill(): void @@ -76,7 +68,7 @@ public function close(): void { $this->pool->close(); $this->pool = null; - $this->num = 0; + $this->num = 0; } protected function make(): void @@ -87,7 +79,7 @@ protected function make(): void $connection = new $this->proxy($this->constructor); } else { $constructor = $this->constructor; - $connection = $constructor(); + $connection = $constructor(); } } catch (\Throwable $throwable) { $this->num--; diff --git a/src/swoole_library/src/core/Constant.php b/src/swoole_library/src/core/Constant.php index 3bfc464c..c0fdd966 100644 --- a/src/swoole_library/src/core/Constant.php +++ b/src/swoole_library/src/core/Constant.php @@ -237,8 +237,6 @@ class Constant public const OPTION_DNS_CACHE_CAPACITY = 'dns_cache_capacity'; - public const OPTION_MAX_CONCURRENCY = 'max_concurrency'; - public const OPTION_CONNECT_TIMEOUT = 'connect_timeout'; public const OPTION_TIMEOUT = 'timeout'; @@ -259,6 +257,8 @@ class Constant public const OPTION_WEBSOCKET_COMPRESSION = 'websocket_compression'; + public const OPTION_WRITE_FUNC = 'write_func'; + public const OPTION_HTTP_PARSE_COOKIE = 'http_parse_cookie'; public const OPTION_HTTP_PARSE_POST = 'http_parse_post'; @@ -327,6 +327,8 @@ class Constant public const OPTION_MAX_QUEUED_BYTES = 'max_queued_bytes'; + public const OPTION_MAX_CONCURRENCY = 'max_concurrency'; + public const OPTION_WORKER_MAX_CONCURRENCY = 'worker_max_concurrency'; public const OPTION_SEND_TIMEOUT = 'send_timeout'; diff --git a/src/swoole_library/src/core/Coroutine/Barrier.php b/src/swoole_library/src/core/Coroutine/Barrier.php index 442a96d3..a21ab02e 100644 --- a/src/swoole_library/src/core/Coroutine/Barrier.php +++ b/src/swoole_library/src/core/Coroutine/Barrier.php @@ -17,11 +17,11 @@ class Barrier { - private $cid = -1; + private int $cid = -1; private $timer = -1; - private static $cancel_list = []; + private static array $cancel_list = []; public function __destruct() { @@ -39,9 +39,9 @@ public function __destruct() } } - public static function make() + public static function make(): self { - return new static(); + return new self(); } /** @@ -52,7 +52,7 @@ public static function wait(Barrier &$barrier, float $timeout = -1) if ($barrier->cid !== -1) { throw new Exception('The barrier is waiting, cannot wait again.'); } - $cid = Coroutine::getCid(); + $cid = Coroutine::getCid(); $barrier->cid = $cid; if ($timeout > 0 && ($timeout_ms = (int) ($timeout * 1000)) > 0) { $barrier->timer = Timer::after($timeout_ms, function () use ($cid) { diff --git a/src/swoole_library/src/core/Coroutine/FastCGI/Client.php b/src/swoole_library/src/core/Coroutine/FastCGI/Client.php index a5ffbb3a..56b2f70a 100644 --- a/src/swoole_library/src/core/Coroutine/FastCGI/Client.php +++ b/src/swoole_library/src/core/Coroutine/FastCGI/Client.php @@ -22,47 +22,42 @@ class Client { - /** @var int */ - protected $af; + protected int $af; - /** @var string */ - protected $host; + protected string $host; - /** @var int */ - protected $port; + protected int $port; - /** @var bool */ - protected $ssl; + protected bool $ssl; - /** @var Socket */ - protected $socket; + protected ?Socket $socket; public function __construct(string $host, int $port = 0, bool $ssl = false) { if (stripos($host, 'unix:/') === 0) { $this->af = AF_UNIX; - $host = '/' . ltrim(substr($host, strlen('unix:/')), '/'); - $port = 0; - } elseif (strpos($host, ':') !== false) { + $host = '/' . ltrim(substr($host, strlen('unix:/')), '/'); + $port = 0; + } elseif (str_contains($host, ':')) { $this->af = AF_INET6; } else { $this->af = AF_INET; } $this->host = $host; $this->port = $port; - $this->ssl = $ssl; + $this->ssl = $ssl; } /** - * @throws Exception * @return HttpResponse|Response + * @throws Exception */ public function execute(Request $request, float $timeout = -1): Response { - if (!$this->socket) { + if (!isset($this->socket)) { $this->socket = $socket = new Socket($this->af, SOCK_STREAM, IPPROTO_IP); $socket->setProtocol([ - 'open_ssl' => $this->ssl, + 'open_ssl' => $this->ssl, 'open_fastcgi_protocol' => true, ]); if (!$socket->connect($this->host, $this->port, $timeout)) { @@ -77,33 +72,17 @@ public function execute(Request $request, float $timeout = -1): Response } $records = []; while (true) { - if (SWOOLE_VERSION_ID < 40500) { - $recvData = ''; - while (true) { - $tmp = $socket->recv(8192, $timeout); - if (!$tmp) { - if ($tmp === '') { - $this->ioException(SOCKET_ECONNRESET); - } - $this->ioException(); - } - $recvData .= $tmp; - if (FrameParser::hasFrame($recvData)) { - break; - } - } - } else { - $recvData = $socket->recvPacket($timeout); - if (!$recvData) { - if ($recvData === '') { - $this->ioException(SOCKET_ECONNRESET); - } - $this->ioException(); - } - if (!FrameParser::hasFrame($recvData)) { - $this->ioException(SOCKET_EPROTO); + $recvData = $socket->recvPacket($timeout); + if (!$recvData) { + if ($recvData === '') { + $this->ioException(SOCKET_ECONNRESET); } + $this->ioException(); } + if (!FrameParser::hasFrame($recvData)) { + $this->ioException(SOCKET_EPROTO); + } + do { $records[] = $record = FrameParser::parseFrame($recvData); } while (strlen($recvData) !== 0); @@ -112,21 +91,20 @@ public function execute(Request $request, float $timeout = -1): Response $this->socket->close(); $this->socket = null; } - switch (true) { - case $request instanceof HttpRequest: - return new HttpResponse($records); - default: - return new Response($records); - } + return match (true) { + $request instanceof HttpRequest => new HttpResponse($records), + default => new Response($records), + }; } } - /* never here */ - exit(1); + + // Code execution should never reach here. However, we still put an exit() statement here for safe purpose. + exit(1); // @phpstan-ignore deadCode.unreachable } public static function parseUrl(string $url): array { - $url = parse_url($url); + $url = parse_url($url); $host = $url['host'] ?? ''; $port = $url['port'] ?? 0; if (empty($host)) { @@ -141,15 +119,15 @@ public static function parseUrl(string $url): array public static function call(string $url, string $path, $data = '', float $timeout = -1): string { - $client = new Client(...static::parseUrl($url)); - $pathInfo = parse_url($path); - $path = $pathInfo['path'] ?? ''; - $root = dirname($path); - $scriptName = '/' . basename($path); + $client = new Client(...static::parseUrl($url)); + $pathInfo = parse_url($path); + $path = $pathInfo['path'] ?? ''; + $root = dirname($path); + $scriptName = '/' . basename($path); $documentUri = $scriptName; - $query = $pathInfo['query'] ?? ''; - $requestUri = $query ? "{$documentUri}?{$query}" : $documentUri; - $request = new HttpRequest(); + $query = $pathInfo['query'] ?? ''; + $requestUri = $query ? "{$documentUri}?{$query}" : $documentUri; + $request = new HttpRequest(); $request->withDocumentRoot($root) ->withScriptFilename($path) ->withScriptName($documentUri) @@ -157,7 +135,8 @@ public static function call(string $url, string $path, $data = '', float $timeou ->withRequestUri($requestUri) ->withQueryString($query) ->withBody($data) - ->withMethod($request->getContentLength() === 0 ? 'GET' : 'POST'); + ->withMethod($request->getContentLength() === 0 ? 'GET' : 'POST') + ; $response = $client->execute($request, $timeout); return $response->getBody(); } @@ -167,7 +146,7 @@ protected function ioException(?int $errno = null): void $socket = $this->socket; if ($errno !== null) { $socket->errCode = $errno; - $socket->errMsg = swoole_strerror($errno); + $socket->errMsg = swoole_strerror($errno); } $socket->close(); $this->socket = null; diff --git a/src/swoole_library/src/core/Coroutine/FastCGI/Proxy.php b/src/swoole_library/src/core/Coroutine/FastCGI/Proxy.php index 41b959d7..eceabe52 100644 --- a/src/swoole_library/src/core/Coroutine/FastCGI/Proxy.php +++ b/src/swoole_library/src/core/Coroutine/FastCGI/Proxy.php @@ -44,8 +44,8 @@ class Proxy public function __construct(string $url, string $documentRoot = '/') { [$this->host, $this->port] = Client::parseUrl($url); - $this->documentRoot = $documentRoot; - $this->staticFileFilter = [$this, 'staticFileFiltrate']; + $this->documentRoot = $documentRoot; + $this->staticFileFilter = [$this, 'staticFileFiltrate']; } public function withTimeout(float $timeout): self @@ -110,8 +110,8 @@ public function translateRequest($userRequest): HttpRequest { $request = new HttpRequest(); if ($userRequest instanceof \Swoole\Http\Request) { - $server = $userRequest->server; - $headers = $userRequest->header; + $server = $userRequest->server; + $headers = $userRequest->header; $pathInfo = $userRequest->server['path_info']; $pathInfo = '/' . ltrim($pathInfo, '/'); if (strlen($this->index) !== 0) { @@ -120,7 +120,7 @@ public function translateRequest($userRequest): HttpRequest $pathInfo = rtrim($pathInfo, '/') . '/' . $this->index; } } - $requestUri = $scriptName = $documentUri = $server['request_uri']; + $requestUri = $scriptName = $documentUri = $server['request_uri']; $queryString = $server['query_string'] ?? ''; if (strlen($queryString) !== 0) { $requestUri .= "?{$server['query_string']}"; @@ -142,12 +142,13 @@ public function translateRequest($userRequest): HttpRequest ->withContentLength((int) ($headers['content-length'] ?? 0)) ->withHeaders($headers) ->withBody($userRequest->rawContent()) - ->withAddedParams($this->params); + ->withAddedParams($this->params) + ; if ($this->https) { $request->withParam('HTTPS', '1'); } } else { - throw new \InvalidArgumentException('Not supported on ' . get_class($userRequest)); + throw new \InvalidArgumentException('Not supported on ' . $userRequest::class); } return $request; } @@ -160,7 +161,7 @@ public function translateResponse(HttpResponse $response, $userResponse): void $userResponse->cookie = $response->getSetCookieHeaderLines(); $userResponse->end($response->getBody()); } else { - throw new \InvalidArgumentException('Not supported on ' . get_class($userResponse)); + throw new \InvalidArgumentException('Not supported on ' . $userResponse::class); } } @@ -178,7 +179,7 @@ public function pass($userRequest, $userResponse): void return; } } - $client = new Client($this->host, $this->port); + $client = new Client($this->host, $this->port); $response = $client->execute($request, $this->timeout); $this->translateResponse($response, $userResponse); } @@ -190,7 +191,7 @@ public function staticFileFiltrate(HttpRequest $request, $userResponse): bool $extension = pathinfo($request->getScriptFilename(), PATHINFO_EXTENSION); if ($extension !== 'php') { $realPath = realpath($request->getScriptFilename()); - if (!$realPath || strpos($realPath, $this->documentRoot) !== 0 || !is_file($realPath)) { + if (!$realPath || !str_starts_with($realPath, $this->documentRoot) || !is_file($realPath)) { $userResponse->status(Http\Status::NOT_FOUND); } else { $userResponse->sendfile($realPath); @@ -199,6 +200,6 @@ public function staticFileFiltrate(HttpRequest $request, $userResponse): bool } return false; } - throw new \InvalidArgumentException('Not supported on ' . get_class($userResponse)); + throw new \InvalidArgumentException('Not supported on ' . $userResponse::class); } } diff --git a/src/swoole_library/src/core/Coroutine/Http/ClientProxy.php b/src/swoole_library/src/core/Coroutine/Http/ClientProxy.php index a0efab26..10c02550 100644 --- a/src/swoole_library/src/core/Coroutine/Http/ClientProxy.php +++ b/src/swoole_library/src/core/Coroutine/Http/ClientProxy.php @@ -13,20 +13,8 @@ class ClientProxy { - private $body; - - private $statusCode; - - private $headers; - - private $cookies; - - public function __construct($body, $statusCode, $headers, $cookies) + public function __construct(private $body, private $statusCode, private $headers, private $cookies) { - $this->body = $body; - $this->statusCode = $statusCode; - $this->headers = $headers; - $this->cookies = $cookies; } public function getBody() diff --git a/src/swoole_library/src/core/Coroutine/Http/functions.php b/src/swoole_library/src/core/Coroutine/Http/functions.php index 698ab87c..0e12564e 100644 --- a/src/swoole_library/src/core/Coroutine/Http/functions.php +++ b/src/swoole_library/src/core/Coroutine/Http/functions.php @@ -14,40 +14,34 @@ use Swoole\Coroutine\Http\Client\Exception; /** - * @param null $data * @throws Exception */ function request( string $url, string $method, - $data = null, - array $options = null, - array $headers = null, - array $cookies = null + mixed $data = null, + ?array $options = null, + ?array $headers = null, + ?array $cookies = null ): ClientProxy { $driver = swoole_library_get_option('http_client_driver'); - switch ($driver) { - case 'curl': - return request_with_curl($url, $method, $data, $options, $headers, $cookies); - case 'stream': - return request_with_stream($url, $method, $data, $options, $headers, $cookies); - case 'swoole': - default: - return request_with_http_client($url, $method, $data, $options, $headers, $cookies); - } + return match ($driver) { + 'curl' => request_with_curl($url, $method, $data, $options, $headers, $cookies), + 'stream' => request_with_stream($url, $method, $data, $options, $headers, $cookies), + default => request_with_http_client($url, $method, $data, $options, $headers, $cookies), + }; } /** - * @param mixed $data * @throws Exception */ function request_with_http_client( string $url, string $method, - $data = null, - array $options = null, - array $headers = null, - array $cookies = null + mixed $data = null, + ?array $options = null, + ?array $headers = null, + ?array $cookies = null ): ClientProxy { $info = parse_url($url); if (empty($info['scheme'])) { @@ -89,16 +83,15 @@ function request_with_http_client( } /** - * @param mixed $data * @throws Exception */ function request_with_curl( string $url, string $method, - $data = null, - array $options = null, - array $headers = null, - array $cookies = null + mixed $data = null, + ?array $options = null, + ?array $headers = null, + ?array $cookies = null ): ClientProxy { $ch = curl_init($url); if (empty($ch)) { @@ -108,14 +101,14 @@ function request_with_curl( curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method)); $responseHeaders = $responseCookies = []; curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$responseHeaders, &$responseCookies) { - $len = strlen($header); + $len = strlen($header); $header = explode(':', $header, 2); if (count($header) < 2) { return $len; } $headerKey = strtolower(trim($header[0])); if ($headerKey == 'set-cookie') { - [$k, $v] = explode('=', $header[1]); + [$k, $v] = explode('=', $header[1]); $responseCookies[$k] = $v; } else { $responseHeaders[$headerKey][] = trim($header[1]); @@ -159,16 +152,15 @@ function request_with_curl( } /** - * @param mixed $data * @throws Exception */ function request_with_stream( string $url, string $method, - $data = null, - array $options = null, - array $headers = null, - array $cookies = null + mixed $data = null, + ?array $options = null, + ?array $headers = null, + ?array $cookies = null ): ClientProxy { $stream_options = [ 'http' => [ @@ -209,10 +201,9 @@ function request_with_stream( } /** - * @param mixed $data * @throws Exception */ -function post(string $url, $data, array $options = null, array $headers = null, array $cookies = null): ClientProxy +function post(string $url, mixed $data, ?array $options = null, ?array $headers = null, ?array $cookies = null): ClientProxy { return request($url, 'POST', $data, $options, $headers, $cookies); } @@ -220,7 +211,7 @@ function post(string $url, $data, array $options = null, array $headers = null, /** * @throws Exception */ -function get(string $url, array $options = null, array $headers = null, array $cookies = null): ClientProxy +function get(string $url, ?array $options = null, ?array $headers = null, ?array $cookies = null): ClientProxy { return request($url, 'GET', null, $options, $headers, $cookies); } diff --git a/src/swoole_library/src/core/Coroutine/Server.php b/src/swoole_library/src/core/Coroutine/Server.php index 6550497a..37c3901d 100644 --- a/src/swoole_library/src/core/Coroutine/Server.php +++ b/src/swoole_library/src/core/Coroutine/Server.php @@ -11,13 +11,11 @@ namespace Swoole\Coroutine; +use Swoole\Constant; use Swoole\Coroutine; use Swoole\Coroutine\Server\Connection; use Swoole\Exception; -/* compatibility constant */ -define('SWOOLE_COROUTINE_SOCKET_HAVE_SSL_HANDSHAKE', method_exists(Socket::class, 'sslHandshake')); - class Server { /** @var string */ @@ -41,7 +39,7 @@ class Server /** @var bool */ protected $running = false; - /** @var null|callable */ + /** @var callable|null */ protected $fn; /** @var Socket */ @@ -57,7 +55,7 @@ public function __construct(string $host, int $port = 0, bool $ssl = false, bool if ($_host->contains('::')) { $this->type = AF_INET6; } elseif ($_host->startsWith('unix:/')) { - $host = $_host->substr(5)->__toString(); + $host = $_host->substr(5)->__toString(); $this->type = AF_UNIX; } else { $this->type = AF_INET; @@ -74,9 +72,9 @@ public function __construct(string $host, int $port = 0, bool $ssl = false, bool if (!$socket->listen()) { throw new Exception('listen() failed', $socket->errCode); } - $this->port = $socket->getsockname()['port'] ?? 0; - $this->fd = $socket->fd; - $this->socket = $socket; + $this->port = $socket->getsockname()['port'] ?? 0; + $this->fd = $socket->fd; + $this->socket = $socket; $this->setting['open_ssl'] = $ssl; } @@ -115,7 +113,7 @@ public function start(): bool $conn = $socket->accept(); if ($conn) { $conn->setProtocol($this->setting); - if (SWOOLE_COROUTINE_SOCKET_HAVE_SSL_HANDSHAKE && $this->setting['open_ssl'] ?? false) { + if (!empty($this->setting[Constant::OPTION_OPEN_SSL])) { $fn = static function ($fn, $connection) { /* @var $connection Connection */ if (!$connection->exportSocket()->sslHandshake()) { @@ -125,7 +123,7 @@ public function start(): bool }; $arguments = [$this->fn, new Connection($conn)]; } else { - $fn = $this->fn; + $fn = $this->fn; $arguments = [new Connection($conn)]; } if (Coroutine::create($fn, ...$arguments) < 0) { diff --git a/src/swoole_library/src/core/Coroutine/WaitGroup.php b/src/swoole_library/src/core/Coroutine/WaitGroup.php index 1eaf70b5..a03d7bc1 100644 --- a/src/swoole_library/src/core/Coroutine/WaitGroup.php +++ b/src/swoole_library/src/core/Coroutine/WaitGroup.php @@ -13,11 +13,11 @@ class WaitGroup { - protected $chan; + protected Channel $chan; - protected $count = 0; + protected int $count = 0; - protected $waiting = false; + protected bool $waiting = false; public function __construct(int $delta = 0) { @@ -58,7 +58,7 @@ public function wait(float $timeout = -1): bool } if ($this->count > 0) { $this->waiting = true; - $done = $this->chan->pop($timeout); + $done = $this->chan->pop($timeout); $this->waiting = false; return $done; } diff --git a/src/swoole_library/src/core/Coroutine/functions.php b/src/swoole_library/src/core/Coroutine/functions.php index 001e9986..26408e5a 100644 --- a/src/swoole_library/src/core/Coroutine/functions.php +++ b/src/swoole_library/src/core/Coroutine/functions.php @@ -15,7 +15,7 @@ function run(callable $fn, ...$args) { - $s = new Scheduler(); + $s = new Scheduler(); $options = Coroutine::getOptions(); if (!isset($options['hook_flags'])) { $s->set(['hook_flags' => SWOOLE_HOOK_ALL]); @@ -51,7 +51,7 @@ function batch(array $tasks, float $timeout = -1): array function parallel(int $n, callable $fn): void { $count = $n; - $wg = new WaitGroup($n); + $wg = new WaitGroup($n); while ($count--) { Coroutine::create(function () use ($fn, $wg) { $fn(); @@ -61,13 +61,27 @@ function parallel(int $n, callable $fn): void $wg->wait(); } +/** + * Applies the callback to the elements of the given list. + * + * The callback function takes on two parameters. The list parameter's value being the first, and the key/index second. + * Each callback runs in a new coroutine, allowing the list to be processed in parallel. + * + * @param array $list A list of key/value paired input data. + * @param callable $fn The callback function to apply to each item on the list. The callback takes on two parameters. + * The list parameter's value being the first, and the key/index second. + * @param float $timeout > 0 means waiting for the specified number of seconds. other means no waiting. + * @return array Returns an array containing the results of applying the callback function to the corresponding value + * and key of the list (used as arguments for the callback). The returned array will preserve the keys of + * the list. + */ function map(array $list, callable $fn, float $timeout = -1): array { $wg = new WaitGroup(count($list)); foreach ($list as $id => $elem) { Coroutine::create(function () use ($wg, &$list, $id, $elem, $fn): void { $list[$id] = null; - $list[$id] = $fn($elem); + $list[$id] = $fn($elem, $id); $wg->done(); }); } @@ -78,7 +92,7 @@ function map(array $list, callable $fn, float $timeout = -1): array function deadlock_check() { $all_coroutines = Coroutine::listCoroutines(); - $count = Coroutine::stats()['coroutine_num']; + $count = Coroutine::stats()['coroutine_num']; echo "\n===================================================================", "\n [FATAL ERROR]: all coroutines (count: {$count}) are asleep - deadlock!", "\n===================================================================\n"; diff --git a/src/swoole_library/src/core/Curl/Handler.php b/src/swoole_library/src/core/Curl/Handler.php index 10fdf18d..9cdee5be 100644 --- a/src/swoole_library/src/core/Curl/Handler.php +++ b/src/swoole_library/src/core/Curl/Handler.php @@ -19,7 +19,7 @@ use Swoole\Curl\Exception as CurlException; use Swoole\Http\Status; -final class Handler +final class Handler implements \Stringable { /** * @var Client @@ -27,37 +27,37 @@ final class Handler private $client; private $info = [ - 'url' => '', - 'content_type' => '', - 'http_code' => 0, - 'header_size' => 0, - 'request_size' => 0, - 'filetime' => -1, - 'ssl_verify_result' => 0, - 'redirect_count' => 0, - 'total_time' => 5.3E-5, - 'namelookup_time' => 0.0, - 'connect_time' => 0.0, - 'pretransfer_time' => 0.0, - 'size_upload' => 0.0, - 'size_download' => 0.0, - 'speed_download' => 0.0, - 'speed_upload' => 0.0, + 'url' => '', + 'content_type' => '', + 'http_code' => 0, + 'header_size' => 0, + 'request_size' => 0, + 'filetime' => -1, + 'ssl_verify_result' => 0, + 'redirect_count' => 0, + 'total_time' => 5.3E-5, + 'namelookup_time' => 0.0, + 'connect_time' => 0.0, + 'pretransfer_time' => 0.0, + 'size_upload' => 0.0, + 'size_download' => 0.0, + 'speed_download' => 0.0, + 'speed_upload' => 0.0, 'download_content_length' => -1.0, - 'upload_content_length' => -1.0, - 'starttransfer_time' => 0.0, - 'redirect_time' => 0.0, - 'redirect_url' => '', - 'primary_ip' => '', - 'certinfo' => [], - 'primary_port' => 0, - 'local_ip' => '', - 'local_port' => 0, - 'http_version' => 0, - 'protocol' => 0, - 'ssl_verifyresult' => 0, - 'scheme' => '', - 'private' => '', + 'upload_content_length' => -1.0, + 'starttransfer_time' => 0.0, + 'redirect_time' => 0.0, + 'redirect_url' => '', + 'primary_ip' => '', + 'certinfo' => [], + 'primary_port' => 0, + 'local_ip' => '', + 'local_port' => 0, + 'http_version' => 0, + 'protocol' => 0, + 'ssl_verifyresult' => 0, + 'scheme' => '', + 'private' => '', ]; private $withHeaderOut = false; @@ -141,7 +141,7 @@ public function __construct(string $url = '') } } - public function __toString() + public function __toString(): string { $id = spl_object_id($this); return "Object({$id}) of type (curl)"; @@ -191,7 +191,7 @@ public function reset() if (!$this->isAvailable()) { return false; } - foreach ((new \ReflectionClass(static::class))->getDefaultProperties() as $name => $value) { + foreach ((new \ReflectionClass(self::class))->getDefaultProperties() as $name => $value) { $this->{$name} = $value; } } @@ -260,7 +260,7 @@ private function setUrl(string $url, bool $setInfo = true): bool $this->setError(CURLE_URL_MALFORMAT, 'No URL set!'); return false; } - if (strpos($url, '://') === false && $this->unix_socket_path === '') { + if (!str_contains($url, '://') && $this->unix_socket_path === '') { $url = 'http://' . $url; } if ($setInfo) { @@ -331,7 +331,7 @@ private function setPort(int $port): void private function setError($code, $msg = ''): void { $this->errCode = $code; - $this->errMsg = $msg ?: curl_strerror($code); + $this->errMsg = $msg ?: curl_strerror($code); } private function hasHeader(string $headerName): bool @@ -348,7 +348,7 @@ private function setHeader(string $headerName, string $value): void } if ($value !== '') { - $this->headers[$headerName] = $value; + $this->headers[$headerName] = $value; $this->headerMap[$lowerCaseHeaderName] = $headerName; } else { // remove empty headers (keep same with raw cURL) @@ -357,10 +357,9 @@ private function setHeader(string $headerName, string $value): void } /** - * @param mixed $value - * @throws Swoole\Curl\Exception + * @throws Exception */ - private function setOption(int $opt, $value): bool + private function setOption(int $opt, mixed $value): bool { switch ($opt) { // case CURLOPT_STDERR: @@ -388,7 +387,7 @@ private function setOption(int $opt, $value): bool break; case CURLOPT_RETURNTRANSFER: $this->returnTransfer = $value; - $this->transfer = ''; + $this->transfer = ''; break; case CURLOPT_ENCODING: if (empty($value)) { @@ -410,9 +409,7 @@ private function setOption(int $opt, $value): bool break; case CURLOPT_PROXYTYPE: if ($value !== CURLPROXY_HTTP and $value !== CURLPROXY_SOCKS5) { - throw new Swoole\Curl\Exception( - 'swoole_curl_setopt(): Only support following CURLOPT_PROXYTYPE values: CURLPROXY_HTTP, CURLPROXY_SOCKS5' - ); + throw new Swoole\Curl\Exception('swoole_curl_setopt(): Only support following CURLOPT_PROXYTYPE values: CURLPROXY_HTTP, CURLPROXY_SOCKS5'); } $this->proxyType = $value; break; @@ -429,7 +426,7 @@ private function setOption(int $opt, $value): bool $this->proxyPassword = $value; break; case CURLOPT_PROXYUSERPWD: - $usernamePassword = explode(':', $value); + $usernamePassword = explode(':', $value); $this->proxyUsername = urldecode($usernamePassword[0]); $this->proxyPassword = urldecode($usernamePassword[1] ?? null); break; @@ -456,9 +453,9 @@ private function setOption(int $opt, $value): bool $resolve = substr($resolve, 1); } $tmpResolve = explode(':', $resolve, 3); - $host = $tmpResolve[0] ?? ''; - $port = $tmpResolve[1] ?? 0; - $ip = $tmpResolve[2] ?? ''; + $host = $tmpResolve[0] ?? ''; + $port = $tmpResolve[1] ?? 0; + $ip = $tmpResolve[2] ?? ''; if ($flag === '-') { unset($this->resolve[$host][$port]); } else { @@ -469,9 +466,7 @@ private function setOption(int $opt, $value): bool break; case CURLOPT_IPRESOLVE: if ($value !== CURL_IPRESOLVE_WHATEVER and $value !== CURL_IPRESOLVE_V4) { - throw new Swoole\Curl\Exception( - 'swoole_curl_setopt(): Only support following CURLOPT_IPRESOLVE values: CURL_IPRESOLVE_WHATEVER, CURL_IPRESOLVE_V4' - ); + throw new Swoole\Curl\Exception('swoole_curl_setopt(): Only support following CURLOPT_IPRESOLVE values: CURL_IPRESOLVE_WHATEVER, CURL_IPRESOLVE_V4'); } break; case CURLOPT_TCP_NODELAY: @@ -560,8 +555,8 @@ private function setOption(int $opt, $value): bool return false; } foreach ($value as $header) { - $header = explode(':', $header, 2); - $headerName = $header[0]; + $header = explode(':', $header, 2); + $headerName = $header[0]; $headerValue = trim($header[1] ?? ''); $this->setHeader($headerName, $headerValue); } @@ -689,8 +684,8 @@ private function setOption(int $opt, $value): bool private function execute() { $this->info['redirect_count'] = $this->info['starttransfer_time'] = 0; - $this->info['redirect_url'] = ''; - $timeBegin = microtime(true); + $this->info['redirect_url'] = ''; + $timeBegin = microtime(true); /* * Socket */ @@ -707,12 +702,12 @@ private function execute() * Http Proxy */ if ($this->proxy) { - $parse = parse_url($this->proxy); - $proxy = $parse['host'] ?? $parse['path']; - $proxyPort = $parse['port'] ?? $this->proxyPort; + $parse = parse_url($this->proxy); + $proxy = $parse['host'] ?? $parse['path']; + $proxyPort = $parse['port'] ?? $this->proxyPort; $proxyUsername = $parse['user'] ?? $this->proxyUsername; $proxyPassword = $parse['pass'] ?? $this->proxyPassword; - $proxyType = $parse['scheme'] ?? $this->proxyType; + $proxyType = $parse['scheme'] ?? $this->proxyType; if (is_string($proxyType)) { if ($proxyType === 'socks5') { $proxyType = CURLPROXY_SOCKS5; @@ -729,26 +724,21 @@ private function execute() } $this->proxy = $proxy = $ip; } - switch ($proxyType) { - case CURLPROXY_HTTP: - $proxyOptions = [ - 'http_proxy_host' => $proxy, - 'http_proxy_port' => $proxyPort, - 'http_proxy_username' => $proxyUsername, - 'http_proxy_password' => $proxyPassword, - ]; - break; - case CURLPROXY_SOCKS5: - $proxyOptions = [ - 'socks5_host' => $proxy, - 'socks5_port' => $proxyPort, - 'socks5_username' => $proxyUsername, - 'socks5_password' => $proxyPassword, - ]; - break; - default: - throw new CurlException("Unexpected proxy type [{$proxyType}]"); - } + $proxyOptions = match ($proxyType) { + CURLPROXY_HTTP => [ + 'http_proxy_host' => $proxy, + 'http_proxy_port' => $proxyPort, + 'http_proxy_username' => $proxyUsername, + 'http_proxy_password' => $proxyPassword, + ], + CURLPROXY_SOCKS5 => [ + 'socks5_host' => $proxy, + 'socks5_port' => $proxyPort, + 'socks5_username' => $proxyUsername, + 'socks5_password' => $proxyPassword, + ], + default => throw new CurlException("Unexpected proxy type [{$proxyType}]"), + }; } /* * Client Options @@ -782,7 +772,7 @@ private function execute() } $client->setData($data); // Notice: although we reset it, raw cURL never do this - $this->infile = null; + $this->infile = null; $this->infileSize = PHP_INT_MAX; } else { // POST data @@ -825,11 +815,11 @@ private function execute() } if ($client->statusCode >= 300 and $client->statusCode < 400 and isset($client->headers['location'])) { $redirectParsedUrl = $this->getRedirectUrl($client->headers['location']); - $redirectUrl = static::unparseUrl($redirectParsedUrl); + $redirectUrl = self::unparseUrl($redirectParsedUrl); if ($this->followLocation and ($this->maxRedirects === null or $this->info['redirect_count'] < $this->maxRedirects)) { if ($this->info['redirect_count'] === 0) { $this->info['starttransfer_time'] = microtime(true) - $timeBegin; - $redirectBeginTime = microtime(true); + $redirectBeginTime = microtime(true); } // force GET if (in_array($client->statusCode, [Status::MOVED_PERMANENTLY, Status::FOUND, Status::SEE_OTHER])) { @@ -852,10 +842,10 @@ private function execute() break; } } - $this->info['total_time'] = microtime(true) - $timeBegin; - $this->info['http_code'] = $client->statusCode; - $this->info['content_type'] = $client->headers['content-type'] ?? ''; - $this->info['size_download'] = $this->info['download_content_length'] = strlen($client->body); + $this->info['total_time'] = microtime(true) - $timeBegin; + $this->info['http_code'] = $client->statusCode; + $this->info['content_type'] = $client->headers['content-type'] ?? ''; + $this->info['size_download'] = $this->info['download_content_length'] = strlen($client->body); $this->info['speed_download'] = 1 / $this->info['total_time'] * $this->info['size_download']; if (isset($redirectBeginTime)) { $this->info['redirect_time'] = microtime(true) - $redirectBeginTime; @@ -866,7 +856,7 @@ private function execute() } if ($this->unix_socket_path) { - $this->info['primary_ip'] = $this->unix_socket_path; + $this->info['primary_ip'] = $this->unix_socket_path; $this->info['primary_port'] = $this->urlInfo['port']; } @@ -908,7 +898,7 @@ private function execute() } if ($this->withHeaderOut) { - $headerOutContent = $client->getHeaderOut(); + $headerOutContent = $client->getHeaderOut(); $this->info['request_header'] = $headerOutContent ? $headerOutContent . "\r\n\r\n" : ''; } if ($this->withFileTime) { @@ -958,14 +948,14 @@ private function execute() private static function unparseUrl(array $parsedUrl): string { - $scheme = ($parsedUrl['scheme'] ?? 'http') . '://'; - $host = $parsedUrl['host'] ?? ''; - $port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : ''; - $user = $parsedUrl['user'] ?? ''; - $pass = isset($parsedUrl['pass']) ? ':' . $parsedUrl['pass'] : ''; - $pass = ($user or $pass) ? "{$pass}@" : ''; - $path = $parsedUrl['path'] ?? ''; - $query = (isset($parsedUrl['query']) and $parsedUrl['query'] !== '') ? '?' . $parsedUrl['query'] : ''; + $scheme = ($parsedUrl['scheme'] ?? 'http') . '://'; + $host = $parsedUrl['host'] ?? ''; + $port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : ''; + $user = $parsedUrl['user'] ?? ''; + $pass = isset($parsedUrl['pass']) ? ':' . $parsedUrl['pass'] : ''; + $pass = ($user or $pass) ? "{$pass}@" : ''; + $path = $parsedUrl['path'] ?? ''; + $query = (isset($parsedUrl['query']) and $parsedUrl['query'] !== '') ? '?' . $parsedUrl['query'] : ''; $fragment = isset($parsedUrl['fragment']) ? '#' . $parsedUrl['fragment'] : ''; return $scheme . $user . $pass . $host . $port . $path . $query . $fragment; } @@ -979,7 +969,7 @@ private function getRedirectUrl(string $location): array if (!isset($location[0])) { return []; } - $redirectUri = $this->urlInfo; + $redirectUri = $this->urlInfo; $redirectUri['query'] = ''; if ($location[0] === '/') { $redirectUri['path'] = $location; @@ -988,7 +978,7 @@ private function getRedirectUrl(string $location): array if ($path === '.') { $path = '/'; } - if (isset($location[1]) and substr($location, 0, 2) === './') { + if (isset($location[1]) and str_starts_with($location, './')) { $location = substr($location, 2); } $redirectUri['path'] = $path . $location; diff --git a/src/swoole_library/src/core/Database/DetectsLostConnections.php b/src/swoole_library/src/core/Database/DetectsLostConnections.php index 6a92be30..4f4d6c8b 100644 --- a/src/swoole_library/src/core/Database/DetectsLostConnections.php +++ b/src/swoole_library/src/core/Database/DetectsLostConnections.php @@ -11,10 +11,11 @@ namespace Swoole\Database; -use Throwable; - class DetectsLostConnections { + /** + * @var array + */ private const ERROR_MESSAGES = [ 'server has gone away', 'no connection to the server', @@ -67,11 +68,11 @@ class DetectsLostConnections 'SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it', ]; - public static function causedByLostConnection(Throwable $e): bool + public static function causedByLostConnection(\Throwable $e): bool { $message = $e->getMessage(); foreach (self::ERROR_MESSAGES as $needle) { - if ($needle !== '' && mb_strpos($message, $needle) !== false) { + if (mb_strpos($message, $needle) !== false) { return true; } } diff --git a/src/swoole_library/src/core/Database/MysqliConfig.php b/src/swoole_library/src/core/Database/MysqliConfig.php index 35d7dd6b..f8d94218 100644 --- a/src/swoole_library/src/core/Database/MysqliConfig.php +++ b/src/swoole_library/src/core/Database/MysqliConfig.php @@ -13,36 +13,28 @@ class MysqliConfig { - /** @var string */ - protected $host = '127.0.0.1'; + protected string $host = '127.0.0.1'; - /** @var int */ - protected $port = 3306; + protected int $port = 3306; - /** @var null|string */ - protected $unixSocket = ''; + protected ?string $unixSocket; - /** @var string */ - protected $dbname = 'test'; + protected string $dbname = 'test'; - /** @var string */ - protected $charset = 'utf8mb4'; + protected string $charset = 'utf8mb4'; - /** @var string */ - protected $username = 'root'; + protected string $username = 'root'; - /** @var string */ - protected $password = 'root'; + protected string $password = 'root'; - /** @var array */ - protected $options = []; + protected array $options = []; public function getHost(): string { return $this->host; } - public function withHost($host): self + public function withHost(string $host): self { $this->host = $host; return $this; @@ -53,9 +45,9 @@ public function getPort(): int return $this->port; } - public function getUnixSocket(): string + public function getUnixSocket(): ?string { - return $this->unixSocket; + return $this->unixSocket ?? null; } public function withUnixSocket(?string $unixSocket): self diff --git a/src/swoole_library/src/core/Database/MysqliPool.php b/src/swoole_library/src/core/Database/MysqliPool.php index e049a4e1..fe5a988c 100644 --- a/src/swoole_library/src/core/Database/MysqliPool.php +++ b/src/swoole_library/src/core/Database/MysqliPool.php @@ -20,12 +20,8 @@ */ class MysqliPool extends ConnectionPool { - /** @var MysqliConfig */ - protected $config; - - public function __construct(MysqliConfig $config, int $size = self::DEFAULT_SIZE) + public function __construct(protected MysqliConfig $config, int $size = self::DEFAULT_SIZE) { - $this->config = $config; parent::__construct(function () { $mysqli = new \mysqli(); foreach ($this->config->getOptions() as $option => $value) { @@ -39,10 +35,10 @@ public function __construct(MysqliConfig $config, int $size = self::DEFAULT_SIZE $this->config->getPort(), $this->config->getUnixSocket() ); - $mysqli->set_charset($this->config->getCharset()); if ($mysqli->connect_errno) { throw new MysqliException($mysqli->connect_error, $mysqli->connect_errno); } + $mysqli->set_charset($this->config->getCharset()); return $mysqli; }, $size, MysqliProxy::class); } diff --git a/src/swoole_library/src/core/Database/MysqliProxy.php b/src/swoole_library/src/core/Database/MysqliProxy.php index 2e49170f..1ed8c7ff 100644 --- a/src/swoole_library/src/core/Database/MysqliProxy.php +++ b/src/swoole_library/src/core/Database/MysqliProxy.php @@ -11,6 +11,9 @@ namespace Swoole\Database; +/** + * @method \mysqli __getObject() + */ class MysqliProxy extends ObjectProxy { public const IO_METHOD_REGEX = '/^autocommit|begin_transaction|change_user|close|commit|kill|multi_query|ping|prepare|query|real_connect|real_query|reap_async_query|refresh|release_savepoint|rollback|savepoint|select_db|send_query|set_charset|ssl_set$/i'; @@ -24,20 +27,16 @@ class MysqliProxy extends ObjectProxy /** @var \mysqli */ protected $__object; - /** @var string */ - protected $charsetContext; + protected string $charsetContext; - /** @var null|array */ - protected $setOptContext; + protected array $setOptContext = []; - /** @var null|array */ - protected $changeUserContext; + protected array $changeUserContext; /** @var callable */ protected $constructor; - /** @var int */ - protected $round = 0; + protected int $round = 0; public function __construct(callable $constructor) { @@ -83,15 +82,13 @@ public function reconnect(): void parent::__construct($constructor()); $this->round++; /* restore context */ - if ($this->charsetContext) { + if (!empty($this->charsetContext)) { $this->__object->set_charset($this->charsetContext); } - if ($this->setOptContext) { - foreach ($this->setOptContext as $opt => $val) { - $this->__object->set_opt($opt, $val); - } + foreach ($this->setOptContext as $opt => $val) { + $this->__object->set_opt($opt, $val); } - if ($this->changeUserContext) { + if (!empty($this->changeUserContext)) { $this->__object->change_user(...$this->changeUserContext); } } @@ -113,7 +110,7 @@ public function set_charset(string $charset): bool return $this->__object->set_charset($charset); } - public function change_user(string $user, string $password, string $database): bool + public function change_user(string $user, string $password, ?string $database): bool { $this->changeUserContext = [$user, $password, $database]; return $this->__object->change_user($user, $password, $database); diff --git a/src/swoole_library/src/core/Database/MysqliStatementProxy.php b/src/swoole_library/src/core/Database/MysqliStatementProxy.php index 0a04b465..8653e455 100644 --- a/src/swoole_library/src/core/Database/MysqliStatementProxy.php +++ b/src/swoole_library/src/core/Database/MysqliStatementProxy.php @@ -18,29 +18,23 @@ class MysqliStatementProxy extends ObjectProxy /** @var \mysqli_stmt */ protected $__object; - /** @var null|string */ - protected $queryString; + protected ?string $queryString; - /** @var null|array */ - protected $attrSetContext; + protected array $attrSetContext = []; - /** @var null|array */ - protected $bindParamContext; + protected array $bindParamContext; - /** @var null|array */ - protected $bindResultContext; + protected array $bindResultContext; - /** @var \Mysqli|MysqliProxy */ - protected $parent; + protected MysqliProxy $parent; - /** @var int */ - protected $parentRound; + protected int $parentRound; public function __construct(\mysqli_stmt $object, ?string $queryString, MysqliProxy $parent) { parent::__construct($object); $this->queryString = $queryString; - $this->parent = $parent; + $this->parent = $parent; $this->parentRound = $parent->getRound(); } @@ -61,21 +55,19 @@ public function __call(string $name, array $arguments) /* if not equal, parent has reconnected */ $this->parent->reconnect(); } - $parent = $this->parent->__getObject(); + $parent = $this->parent->__getObject(); $this->__object = $this->queryString ? @$parent->prepare($this->queryString) : @$parent->stmt_init(); if ($this->__object === false) { throw new MysqliException($parent->error, $parent->errno); } - if ($this->bindParamContext) { + if (!empty($this->bindParamContext)) { $this->__object->bind_param($this->bindParamContext[0], ...$this->bindParamContext[1]); } - if ($this->bindResultContext) { + if (!empty($this->bindResultContext)) { $this->__object->bind_result($this->bindResultContext); } - if ($this->attrSetContext) { - foreach ($this->attrSetContext as $attr => $value) { - $this->__object->attr_set($attr, $value); - } + foreach ($this->attrSetContext as $attr => $value) { + $this->__object->attr_set($attr, $value); } continue; } diff --git a/src/swoole_library/src/core/Database/ObjectProxy.php b/src/swoole_library/src/core/Database/ObjectProxy.php index 44944b81..123198c0 100644 --- a/src/swoole_library/src/core/Database/ObjectProxy.php +++ b/src/swoole_library/src/core/Database/ObjectProxy.php @@ -13,7 +13,7 @@ class ObjectProxy extends \Swoole\ObjectProxy { - public function __clone() + final public function __clone(): void { throw new \Error('Trying to clone an uncloneable database proxy object'); } diff --git a/src/swoole_library/src/core/Database/PDOConfig.php b/src/swoole_library/src/core/Database/PDOConfig.php index 6b407a45..f1531246 100644 --- a/src/swoole_library/src/core/Database/PDOConfig.php +++ b/src/swoole_library/src/core/Database/PDOConfig.php @@ -15,32 +15,23 @@ class PDOConfig { public const DRIVER_MYSQL = 'mysql'; - /** @var string */ - protected $driver = self::DRIVER_MYSQL; + protected string $driver = self::DRIVER_MYSQL; - /** @var string */ - protected $host = '127.0.0.1'; + protected string $host = '127.0.0.1'; - /** @var int */ - protected $port = 3306; + protected int $port = 3306; - /** @var string */ - protected $unixSocket = ''; + protected ?string $unixSocket; - /** @var string */ - protected $dbname = 'test'; + protected string $dbname = 'test'; - /** @var string */ - protected $charset = 'utf8mb4'; + protected string $charset = 'utf8mb4'; - /** @var string */ - protected $username = 'root'; + protected string $username = 'root'; - /** @var string */ - protected $password = 'root'; + protected string $password = 'root'; - /** @var array */ - protected $options = []; + protected array $options = []; public function getDriver(): string { @@ -58,7 +49,7 @@ public function getHost(): string return $this->host; } - public function withHost($host): self + public function withHost(string $host): self { $this->host = $host; return $this; @@ -74,9 +65,9 @@ public function hasUnixSocket(): bool return !empty($this->unixSocket); } - public function getUnixSocket(): string + public function getUnixSocket(): ?string { - return $this->unixSocket; + return $this->unixSocket ?? null; } public function withUnixSocket(?string $unixSocket): self @@ -151,7 +142,7 @@ public function withOptions(array $options): self * * @return string[] */ - public static function getAvailableDrivers() + public static function getAvailableDrivers(): array { return [ self::DRIVER_MYSQL, diff --git a/src/swoole_library/src/core/Database/PDOPool.php b/src/swoole_library/src/core/Database/PDOPool.php index 7ead406a..25cf4c9e 100644 --- a/src/swoole_library/src/core/Database/PDOPool.php +++ b/src/swoole_library/src/core/Database/PDOPool.php @@ -11,7 +11,6 @@ namespace Swoole\Database; -use Exception; use PDO; use Swoole\ConnectionPool; @@ -20,22 +19,15 @@ */ class PDOPool extends ConnectionPool { - /** @var int */ - protected $size = 64; - - /** @var PDOConfig */ - protected $config; - - public function __construct(PDOConfig $config, int $size = self::DEFAULT_SIZE) + public function __construct(protected PDOConfig $config, int $size = self::DEFAULT_SIZE) { - $this->config = $config; parent::__construct(function () { $driver = $this->config->getDriver(); if ($driver === 'sqlite') { - return new PDO($this->createDSN('sqlite')); + return new \PDO($this->createDSN('sqlite')); } - return new PDO($this->createDSN($driver), $this->config->getUsername(), $this->config->getPassword(), $this->config->getOptions()); + return new \PDO($this->createDSN($driver), $this->config->getUsername(), $this->config->getPassword(), $this->config->getOptions()); }, $size, PDOProxy::class); } @@ -49,7 +41,7 @@ public function get(float $timeout = -1) /** * @purpose create DSN - * @throws Exception + * @throws \Exception */ private function createDSN(string $driver): string { @@ -71,7 +63,7 @@ private function createDSN(string $driver): string $dsn = 'sqlite:' . $this->config->getDbname(); break; default: - throw new Exception('Unsupported Database Driver:' . $driver); + throw new \Exception('Unsupported Database Driver:' . $driver); } return $dsn; } diff --git a/src/swoole_library/src/core/Database/PDOProxy.php b/src/swoole_library/src/core/Database/PDOProxy.php index e4d7b23a..4ee20447 100644 --- a/src/swoole_library/src/core/Database/PDOProxy.php +++ b/src/swoole_library/src/core/Database/PDOProxy.php @@ -11,30 +11,27 @@ namespace Swoole\Database; -use PDO; -use PDOException; - +/** + * @method \PDO __getObject() + */ class PDOProxy extends ObjectProxy { - /** @var PDO */ + /** @var \PDO */ protected $__object; - /** @var null|array */ - protected $setAttributeContext; + protected array $setAttributeContext = []; /** @var callable */ protected $constructor; - /** @var int */ - protected $round = 0; + protected int $round = 0; - /** @var int */ - protected $inTransaction = 0; + protected int $inTransaction = 0; public function __construct(callable $constructor) { parent::__construct($constructor()); - $this->__object->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->__object->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $this->constructor = $constructor; } @@ -42,7 +39,7 @@ public function __call(string $name, array $arguments) { try { $ret = $this->__object->{$name}(...$arguments); - } catch (PDOException $e) { + } catch (\PDOException $e) { if (!$this->__object->inTransaction() && DetectsLostConnections::causedByLostConnection($e)) { $this->reconnect(); $ret = $this->__object->{$name}(...$arguments); @@ -75,13 +72,11 @@ public function reconnect(): void { $constructor = $this->constructor; parent::__construct($constructor()); - $this->__object->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->__object->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $this->round++; /* restore context */ - if ($this->setAttributeContext) { - foreach ($this->setAttributeContext as $attribute => $value) { - $this->__object->setAttribute($attribute, $value); - } + foreach ($this->setAttributeContext as $attribute => $value) { + $this->__object->setAttribute($attribute, $value); } } diff --git a/src/swoole_library/src/core/Database/PDOStatementProxy.php b/src/swoole_library/src/core/Database/PDOStatementProxy.php index 4a9eda3a..f035bba6 100644 --- a/src/swoole_library/src/core/Database/PDOStatementProxy.php +++ b/src/swoole_library/src/core/Database/PDOStatementProxy.php @@ -11,39 +11,30 @@ namespace Swoole\Database; -use PDOException; -use PDOStatement; - class PDOStatementProxy extends ObjectProxy { - /** @var PDOStatement */ + /** @var \PDOStatement */ protected $__object; - /** @var null|array */ - protected $setAttributeContext; + protected array $setAttributeContext = []; - /** @var null|array */ - protected $setFetchModeContext; + protected array $setFetchModeContext; - /** @var null|array */ - protected $bindParamContext; + protected array $bindParamContext = []; - /** @var null|array */ - protected $bindColumnContext; + protected array $bindColumnContext = []; - /** @var null|array */ - protected $bindValueContext; + protected array $bindValueContext = []; - /** @var \PDO|PDOProxy */ - protected $parent; + protected PDOProxy $parent; /** @var int */ protected $parentRound; - public function __construct(PDOStatement $object, PDOProxy $parent) + public function __construct(\PDOStatement $object, PDOProxy $parent) { parent::__construct($object); - $this->parent = $parent; + $this->parent = $parent; $this->parentRound = $parent->getRound(); } @@ -51,37 +42,29 @@ public function __call(string $name, array $arguments) { try { $ret = $this->__object->{$name}(...$arguments); - } catch (PDOException $e) { + } catch (\PDOException $e) { if (!$this->parent->inTransaction() && DetectsLostConnections::causedByLostConnection($e)) { if ($this->parent->getRound() === $this->parentRound) { /* if not equal, parent has reconnected */ $this->parent->reconnect(); } - $parent = $this->parent->__getObject(); + $parent = $this->parent->__getObject(); $this->__object = $parent->prepare($this->__object->queryString); - if ($this->setAttributeContext) { - foreach ($this->setAttributeContext as $attribute => $value) { - $this->__object->setAttribute($attribute, $value); - } + foreach ($this->setAttributeContext as $attribute => $value) { + $this->__object->setAttribute($attribute, $value); } - if ($this->setFetchModeContext) { + if (!empty($this->setFetchModeContext)) { $this->__object->setFetchMode(...$this->setFetchModeContext); } - if ($this->bindParamContext) { - foreach ($this->bindParamContext as $param => $item) { - $this->__object->bindParam($param, ...$item); - } + foreach ($this->bindParamContext as $param => $item) { + $this->__object->bindParam($param, ...$item); } - if ($this->bindColumnContext) { - foreach ($this->bindColumnContext as $column => $item) { - $this->__object->bindColumn($column, ...$item); - } + foreach ($this->bindColumnContext as $column => $item) { + $this->__object->bindColumn($column, ...$item); } - if ($this->bindValueContext) { - foreach ($this->bindValueContext as $value => $item) { - $this->__object->bindParam($value, ...$item); - } + foreach ($this->bindValueContext as $value => $item) { + $this->__object->bindParam($value, ...$item); } $ret = $this->__object->{$name}(...$arguments); } else { diff --git a/src/swoole_library/src/core/Database/RedisConfig.php b/src/swoole_library/src/core/Database/RedisConfig.php index 645d7157..a6049e46 100644 --- a/src/swoole_library/src/core/Database/RedisConfig.php +++ b/src/swoole_library/src/core/Database/RedisConfig.php @@ -13,36 +13,33 @@ class RedisConfig { - /** @var string */ - protected $host = '127.0.0.1'; + protected string $host = '127.0.0.1'; - /** @var int */ - protected $port = 6379; + protected int $port = 6379; - /** @var float */ - protected $timeout = 0.0; + protected float $timeout = 0.0; - /** @var string */ - protected $reserved = ''; + protected string $reserved = ''; - /** @var int */ - protected $retry_interval = 0; + protected int $retry_interval = 0; - /** @var float */ - protected $read_timeout = 0.0; + protected float $read_timeout = 0.0; - /** @var string */ - protected $auth = ''; + protected string $auth = ''; - /** @var int */ - protected $dbIndex = 0; + protected int $dbIndex = 0; - public function getHost() + /** + * @var array + */ + protected array $options = []; + + public function getHost(): string { return $this->host; } - public function withHost($host): self + public function withHost(string $host): self { $this->host = $host; return $this; @@ -124,4 +121,34 @@ public function withDbIndex(int $dbIndex): self $this->dbIndex = $dbIndex; return $this; } + + /** + * Add a configurable option. + */ + public function withOption(int $option, mixed $value): self + { + $this->options[$option] = $value; + return $this; + } + + /** + * Add/override configurable options. + * + * @param array $options + */ + public function setOptions(array $options): self + { + $this->options = $options; + return $this; + } + + /** + * Get configurable options. + * + * @return array + */ + public function getOptions(): array + { + return $this->options; + } } diff --git a/src/swoole_library/src/core/Database/RedisPool.php b/src/swoole_library/src/core/Database/RedisPool.php index 6926830a..7ef7c755 100644 --- a/src/swoole_library/src/core/Database/RedisPool.php +++ b/src/swoole_library/src/core/Database/RedisPool.php @@ -20,12 +20,8 @@ */ class RedisPool extends ConnectionPool { - /** @var RedisConfig */ - protected $config; - - public function __construct(RedisConfig $config, int $size = self::DEFAULT_SIZE) + public function __construct(protected RedisConfig $config, int $size = self::DEFAULT_SIZE) { - $this->config = $config; parent::__construct(function () { $redis = new \Redis(); /* Compatible with different versions of Redis extension as much as possible */ @@ -51,6 +47,12 @@ public function __construct(RedisConfig $config, int $size = self::DEFAULT_SIZE) if ($this->config->getDbIndex() !== 0) { $redis->select($this->config->getDbIndex()); } + + /* Set Redis options. */ + foreach ($this->config->getOptions() as $key => $value) { + $redis->setOption($key, $value); + } + return $redis; }, $size); } diff --git a/src/swoole_library/src/core/FastCGI/FrameParser.php b/src/swoole_library/src/core/FastCGI/FrameParser.php index c8f04dfe..0cc4cb79 100644 --- a/src/swoole_library/src/core/FastCGI/FrameParser.php +++ b/src/swoole_library/src/core/FastCGI/FrameParser.php @@ -24,17 +24,17 @@ class FrameParser * @var array */ protected static $classMapping = [ - FastCGI::BEGIN_REQUEST => FastCGI\Record\BeginRequest::class, - FastCGI::ABORT_REQUEST => FastCGI\Record\AbortRequest::class, - FastCGI::END_REQUEST => FastCGI\Record\EndRequest::class, - FastCGI::PARAMS => FastCGI\Record\Params::class, - FastCGI::STDIN => FastCGI\Record\Stdin::class, - FastCGI::STDOUT => FastCGI\Record\Stdout::class, - FastCGI::STDERR => FastCGI\Record\Stderr::class, - FastCGI::DATA => FastCGI\Record\Data::class, - FastCGI::GET_VALUES => FastCGI\Record\GetValues::class, + FastCGI::BEGIN_REQUEST => FastCGI\Record\BeginRequest::class, + FastCGI::ABORT_REQUEST => FastCGI\Record\AbortRequest::class, + FastCGI::END_REQUEST => FastCGI\Record\EndRequest::class, + FastCGI::PARAMS => FastCGI\Record\Params::class, + FastCGI::STDIN => FastCGI\Record\Stdin::class, + FastCGI::STDOUT => FastCGI\Record\Stdout::class, + FastCGI::STDERR => FastCGI\Record\Stderr::class, + FastCGI::DATA => FastCGI\Record\Data::class, + FastCGI::GET_VALUES => FastCGI\Record\GetValues::class, FastCGI::GET_VALUES_RESULT => FastCGI\Record\GetValuesResult::class, - FastCGI::UNKNOWN_TYPE => FastCGI\Record\UnknownType::class, + FastCGI::UNKNOWN_TYPE => FastCGI\Record\UnknownType::class, ]; /** @@ -71,14 +71,14 @@ public static function parseFrame(string &$buffer): Record throw new \RuntimeException('Not enough data in the buffer to parse'); } $recordHeader = unpack(FastCGI::HEADER_FORMAT, $buffer); - $recordType = $recordHeader['type']; + $recordType = $recordHeader['type']; if (!isset(self::$classMapping[$recordType])) { throw new \DomainException("Invalid FastCGI record type {$recordType} received"); } /** @var Record $className */ $className = self::$classMapping[$recordType]; - $record = $className::unpack($buffer); + $record = $className::unpack($buffer); $offset = FastCGI::HEADER_LEN + $record->getContentLength() + $record->getPaddingLength(); $buffer = substr($buffer, $offset); diff --git a/src/swoole_library/src/core/FastCGI/HttpRequest.php b/src/swoole_library/src/core/FastCGI/HttpRequest.php index 833f5c61..9d821959 100644 --- a/src/swoole_library/src/core/FastCGI/HttpRequest.php +++ b/src/swoole_library/src/core/FastCGI/HttpRequest.php @@ -13,26 +13,26 @@ class HttpRequest extends Request { - protected $params = [ - 'REQUEST_SCHEME' => 'http', - 'REQUEST_METHOD' => 'GET', - 'DOCUMENT_ROOT' => '', - 'SCRIPT_FILENAME' => '', - 'SCRIPT_NAME' => '', - 'DOCUMENT_URI' => '/', - 'REQUEST_URI' => '/', - 'QUERY_STRING' => '', - 'CONTENT_TYPE' => 'text/plain', - 'CONTENT_LENGTH' => '0', + protected array $params = [ + 'REQUEST_SCHEME' => 'http', + 'REQUEST_METHOD' => 'GET', + 'DOCUMENT_ROOT' => '', + 'SCRIPT_FILENAME' => '', + 'SCRIPT_NAME' => '', + 'DOCUMENT_URI' => '/', + 'REQUEST_URI' => '/', + 'QUERY_STRING' => '', + 'CONTENT_TYPE' => 'text/plain', + 'CONTENT_LENGTH' => '0', 'GATEWAY_INTERFACE' => 'CGI/1.1', - 'SERVER_PROTOCOL' => 'HTTP/1.1', - 'SERVER_SOFTWARE' => 'swoole/' . SWOOLE_VERSION, - 'REMOTE_ADDR' => 'unknown', - 'REMOTE_PORT' => '0', - 'SERVER_ADDR' => 'unknown', - 'SERVER_PORT' => '0', - 'SERVER_NAME' => 'Swoole', - 'REDIRECT_STATUS' => '200', + 'SERVER_PROTOCOL' => 'HTTP/1.1', + 'SERVER_SOFTWARE' => 'swoole/' . SWOOLE_VERSION, + 'REMOTE_ADDR' => 'unknown', + 'REMOTE_PORT' => '0', + 'SERVER_ADDR' => 'unknown', + 'SERVER_PORT' => '0', + 'SERVER_NAME' => 'Swoole', + 'REDIRECT_STATUS' => '200', ]; public function getScheme(): ?string @@ -120,7 +120,8 @@ public function withUri(string $uri): self $info = parse_url($uri); return $this->withRequestUri($uri) ->withDocumentUri($info['path'] ?? '') - ->withQueryString($info['query'] ?? ''); + ->withQueryString($info['query'] ?? '') + ; } public function getDocumentUri(): ?string @@ -384,7 +385,7 @@ public function getHeaders(): array { $headers = []; foreach ($this->params as $name => $value) { - if (strpos($name, 'HTTP_') === 0) { + if (str_starts_with($name, 'HTTP_')) { $headers[static::convertParamNameToHeaderName($name)] = $value; } } @@ -399,8 +400,7 @@ public function withHeaders(array $headers): self return $this; } - /** @return $this */ - public function withBody($body): Message + public function withBody($body): self { if (is_array($body)) { $body = http_build_query($body); diff --git a/src/swoole_library/src/core/FastCGI/HttpResponse.php b/src/swoole_library/src/core/FastCGI/HttpResponse.php index 883ba9ac..db4fd26e 100644 --- a/src/swoole_library/src/core/FastCGI/HttpResponse.php +++ b/src/swoole_library/src/core/FastCGI/HttpResponse.php @@ -43,17 +43,17 @@ public function __construct(array $records = []) return; } $headers = explode("\r\n", $array[0]); - $body = $array[1]; + $body = $array[1]; foreach ($headers as $header) { $array = explode(':', $header, 2); // An array that contains the name and the value of an HTTP header. if (count($array) != 2) { continue; // Invalid HTTP header? Ignore it! } - $name = trim($array[0]); + $name = trim($array[0]); $value = trim($array[1]); if (strcasecmp($name, 'Status') === 0) { - $array = explode(' ', $value, 2); // An array that contains the status code (and the reason phrase). - $statusCode = $array[0]; + $array = explode(' ', $value, 2); // An array that contains the status code (and the reason phrase). + $statusCode = $array[0]; $reasonPhrase = $array[1] ?? null; } elseif (strcasecmp($name, 'Set-Cookie') === 0) { $this->withSetCookieHeaderLine($value); @@ -61,7 +61,7 @@ public function __construct(array $records = []) $this->withHeader($name, $value); } } - $statusCode = (int) ($statusCode ?? Status::OK); + $statusCode = (int) ($statusCode ?? Status::OK); $reasonPhrase = (string) ($reasonPhrase ?? Status::getReasonPhrase($statusCode)); $this->withStatusCode($statusCode)->withReasonPhrase($reasonPhrase); $this->withBody($body); @@ -102,7 +102,7 @@ public function getHeaders(): array public function withHeader(string $name, string $value): self { - $this->headers[$name] = $value; + $this->headers[$name] = $value; $this->headersMap[strtolower($name)] = $name; return $this; } diff --git a/src/swoole_library/src/core/FastCGI/Message.php b/src/swoole_library/src/core/FastCGI/Message.php index c9604c6b..745f03cb 100644 --- a/src/swoole_library/src/core/FastCGI/Message.php +++ b/src/swoole_library/src/core/FastCGI/Message.php @@ -13,14 +13,11 @@ class Message { - /** @var array */ - protected $params = []; + protected array $params = []; - /** @var string */ - protected $body = ''; + protected string $body = ''; - /** @var string */ - protected $error = ''; + protected string $error = ''; public function getParam(string $name): ?string { diff --git a/src/swoole_library/src/core/FastCGI/Record.php b/src/swoole_library/src/core/FastCGI/Record.php index 050f3a36..70bb9831 100644 --- a/src/swoole_library/src/core/FastCGI/Record.php +++ b/src/swoole_library/src/core/FastCGI/Record.php @@ -16,63 +16,47 @@ /** * FastCGI record. */ -class Record +class Record implements \Stringable { /** * Identifies the FastCGI protocol version. - * - * @var int */ - protected $version = FastCGI::VERSION_1; + protected int $version = FastCGI::VERSION_1; /** * Identifies the FastCGI record type, i.e. the general function that the record performs. - * - * @var int */ - protected $type = FastCGI::UNKNOWN_TYPE; + protected int $type = FastCGI::UNKNOWN_TYPE; /** * Identifies the FastCGI request to which the record belongs. - * - * @var int */ - protected $requestId = FastCGI::DEFAULT_REQUEST_ID; + protected int $requestId = FastCGI::DEFAULT_REQUEST_ID; /** * Reserved byte for future proposes - * - * @var int */ - protected $reserved = 0; + protected int $reserved = 0; /** * The number of bytes in the contentData component of the record. - * - * @var int */ - private $contentLength = 0; + private int $contentLength = 0; /** * The number of bytes in the paddingData component of the record. - * - * @var int */ - private $paddingLength = 0; + private int $paddingLength = 0; /** * Binary data, between 0 and 65535 bytes of data, interpreted according to the record type. - * - * @var string */ - private $contentData = ''; + private string $contentData = ''; /** * Padding data, between 0 and 255 bytes of data, which are ignored. - * - * @var string */ - private $paddingData = ''; + private string $paddingData = ''; /** * Returns the binary message representation of record @@ -99,12 +83,10 @@ final public function __toString(): string * Unpacks the message from the binary data buffer * * @param string $data Binary buffer with raw data - * - * @return static */ - final public static function unpack(string $data): self + final public static function unpack(string $data): static { - $self = new static(); + $self = new static(); // @phpstan-ignore new.static [ $self->version, $self->type, @@ -116,7 +98,7 @@ final public static function unpack(string $data): self $payload = substr($data, FastCGI::HEADER_LEN); self::unpackPayload($self, $payload); - if (get_called_class() !== __CLASS__ && $self->contentLength > 0) { + if (static::class !== self::class && $self->contentLength > 0) { static::unpackPayload($self, $payload); } @@ -133,11 +115,11 @@ public function setContentData(string $data): self $this->contentLength = strlen($data); if ($this->contentLength > FastCGI::MAX_CONTENT_LENGTH) { $this->contentLength = FastCGI::MAX_CONTENT_LENGTH; - $this->contentData = substr($data, 0, FastCGI::MAX_CONTENT_LENGTH); + $this->contentData = substr($data, 0, FastCGI::MAX_CONTENT_LENGTH); } else { $this->contentData = $data; } - $extraLength = $this->contentLength % 8; + $extraLength = $this->contentLength % 8; $this->paddingLength = $extraLength ? (8 - $extraLength) : 0; return $this; } diff --git a/src/swoole_library/src/core/FastCGI/Record/BeginRequest.php b/src/swoole_library/src/core/FastCGI/Record/BeginRequest.php index 15e2d133..8178a1ab 100644 --- a/src/swoole_library/src/core/FastCGI/Record/BeginRequest.php +++ b/src/swoole_library/src/core/FastCGI/Record/BeginRequest.php @@ -51,9 +51,9 @@ class BeginRequest extends Record public function __construct(int $role = FastCGI::UNKNOWN_ROLE, int $flags = 0, string $reserved = '') { - $this->type = FastCGI::BEGIN_REQUEST; - $this->role = $role; - $this->flags = $flags; + $this->type = FastCGI::BEGIN_REQUEST; + $this->role = $role; + $this->flags = $flags; $this->reserved1 = $reserved; $this->setContentData($this->packPayload()); } diff --git a/src/swoole_library/src/core/FastCGI/Record/EndRequest.php b/src/swoole_library/src/core/FastCGI/Record/EndRequest.php index a8330240..8b99d1ec 100644 --- a/src/swoole_library/src/core/FastCGI/Record/EndRequest.php +++ b/src/swoole_library/src/core/FastCGI/Record/EndRequest.php @@ -56,10 +56,10 @@ public function __construct( int $appStatus = 0, string $reserved = '' ) { - $this->type = FastCGI::END_REQUEST; + $this->type = FastCGI::END_REQUEST; $this->protocolStatus = $protocolStatus; - $this->appStatus = $appStatus; - $this->reserved1 = $reserved; + $this->appStatus = $appStatus; + $this->reserved1 = $reserved; $this->setContentData($this->packPayload()); } diff --git a/src/swoole_library/src/core/FastCGI/Record/Params.php b/src/swoole_library/src/core/FastCGI/Record/Params.php index 111878c8..95f8d211 100644 --- a/src/swoole_library/src/core/FastCGI/Record/Params.php +++ b/src/swoole_library/src/core/FastCGI/Record/Params.php @@ -31,7 +31,7 @@ class Params extends Record */ public function __construct(array $values = []) { - $this->type = FastCGI::PARAMS; + $this->type = FastCGI::PARAMS; $this->values = $values; $this->setContentData($this->packPayload()); } @@ -53,18 +53,18 @@ protected static function unpackPayload($self, string $data): void $currentOffset = 0; do { [$nameLengthHigh] = array_values(unpack('CnameLengthHigh', $data)); - $isLongName = ($nameLengthHigh >> 7 == 1); - $valueOffset = $isLongName ? 4 : 1; + $isLongName = ($nameLengthHigh >> 7 == 1); + $valueOffset = $isLongName ? 4 : 1; [$valueLengthHigh] = array_values(unpack('CvalueLengthHigh', substr($data, $valueOffset))); - $isLongValue = ($valueLengthHigh >> 7 == 1); - $dataOffset = $valueOffset + ($isLongValue ? 4 : 1); + $isLongValue = ($valueLengthHigh >> 7 == 1); + $dataOffset = $valueOffset + ($isLongValue ? 4 : 1); $formatParts = [ $isLongName ? 'NnameLength' : 'CnameLength', $isLongValue ? 'NvalueLength' : 'CvalueLength', ]; - $format = join('/', $formatParts); + $format = join('/', $formatParts); [$nameLength, $valueLength] = array_values(unpack($format, $data)); // Clear top bit for long record @@ -81,7 +81,7 @@ protected static function unpackPayload($self, string $data): void $self->values[$nameData] = $valueData; $keyValueLength = $dataOffset + $nameLength + $valueLength; - $data = substr($data, $keyValueLength); + $data = substr($data, $keyValueLength); $currentOffset += $keyValueLength; } while ($currentOffset < $self->getContentLength()); } @@ -94,9 +94,9 @@ protected function packPayload(): string if ($valueData === null) { continue; } - $nameLength = strlen($nameData); + $nameLength = strlen($nameData); $valueLength = strlen((string) $valueData); - $isLongName = $nameLength > 127; + $isLongName = $nameLength > 127; $isLongValue = $valueLength > 127; $formatParts = [ $isLongName ? 'N' : 'C', diff --git a/src/swoole_library/src/core/FastCGI/Record/UnknownType.php b/src/swoole_library/src/core/FastCGI/Record/UnknownType.php index ab502d62..1593d365 100644 --- a/src/swoole_library/src/core/FastCGI/Record/UnknownType.php +++ b/src/swoole_library/src/core/FastCGI/Record/UnknownType.php @@ -40,8 +40,8 @@ class UnknownType extends Record public function __construct(int $type = 0, string $reserved = '') { - $this->type = FastCGI::UNKNOWN_TYPE; - $this->type1 = $type; + $this->type = FastCGI::UNKNOWN_TYPE; + $this->type1 = $type; $this->reserved1 = $reserved; $this->setContentData($this->packPayload()); } diff --git a/src/swoole_library/src/core/FastCGI/Request.php b/src/swoole_library/src/core/FastCGI/Request.php index a4a5d14a..1cd273fe 100644 --- a/src/swoole_library/src/core/FastCGI/Request.php +++ b/src/swoole_library/src/core/FastCGI/Request.php @@ -16,16 +16,16 @@ use Swoole\FastCGI\Record\Params; use Swoole\FastCGI\Record\Stdin; -class Request extends Message +class Request extends Message implements \Stringable { - protected $keepConn = false; + protected bool $keepConn = false; public function __toString(): string { - $body = $this->getBody(); + $body = $this->getBody(); $beginRequestFrame = new BeginRequest(FastCGI::RESPONDER, $this->keepConn ? FastCGI::KEEP_CONN : 0); - $paramsFrame = new Params($this->getParams()); - $paramsEofFrame = new Params(); + $paramsFrame = new Params($this->getParams()); + $paramsEofFrame = new Params(); if (empty($body)) { $message = "{$beginRequestFrame}{$paramsFrame}{$paramsEofFrame}}"; } else { @@ -39,8 +39,8 @@ public function __toString(): string $body = substr($body, $stdinLength); } $stdinList[] = new Stdin(); - $stdin = implode($stdinList); - $message = "{$beginRequestFrame}{$paramsFrame}{$paramsEofFrame}{$stdin}}"; + $stdin = implode('', $stdinList); + $message = "{$beginRequestFrame}{$paramsFrame}{$paramsEofFrame}{$stdin}}"; } return $message; } diff --git a/src/swoole_library/src/core/FastCGI/Response.php b/src/swoole_library/src/core/FastCGI/Response.php index cb76e2bf..b4a24c36 100644 --- a/src/swoole_library/src/core/FastCGI/Response.php +++ b/src/swoole_library/src/core/FastCGI/Response.php @@ -22,7 +22,7 @@ public function __construct(array $records = []) if (!static::verify($records)) { throw new \InvalidArgumentException('Bad records'); } - $body = ''; + $body = ''; $error = ''; foreach ($records as $record) { if ($record instanceof Stdout) { diff --git a/src/swoole_library/src/core/Http/Status.php b/src/swoole_library/src/core/Http/Status.php index 3c5dc52d..42383be0 100644 --- a/src/swoole_library/src/core/Http/Status.php +++ b/src/swoole_library/src/core/Http/Status.php @@ -136,66 +136,66 @@ abstract class Status public const NETWORK_AUTHENTICATION_REQUIRED = 511; protected static $reasonPhrases = [ - self::CONTINUE => 'Continue', - self::SWITCHING_PROTOCOLS => 'Switching Protocols', - self::PROCESSING => 'Processing', - self::OK => 'OK', - self::CREATED => 'Created', - self::ACCEPTED => 'Accepted', - self::NON_AUTHORITATIVE_INFORMATION => 'Non-Authoritative Information', - self::NO_CONTENT => 'No Content', - self::RESET_CONTENT => 'Reset Content', - self::PARTIAL_CONTENT => 'Partial Content', - self::MULTI_STATUS => 'Multi-status', - self::ALREADY_REPORTED => 'Already Reported', - self::IM_USED => 'IM Used', - self::MULTIPLE_CHOICES => 'Multiple Choices', - self::MOVED_PERMANENTLY => 'Moved Permanently', - self::FOUND => 'Found', - self::SEE_OTHER => 'See Other', - self::NOT_MODIFIED => 'Not Modified', - self::USE_PROXY => 'Use Proxy', - self::SWITCH_PROXY => 'Switch Proxy', - self::TEMPORARY_REDIRECT => 'Temporary Redirect', - self::PERMANENT_REDIRECT => 'Permanent Redirect', - self::BAD_REQUEST => 'Bad Request', - self::UNAUTHORIZED => 'Unauthorized', - self::PAYMENT_REQUIRED => 'Payment Required', - self::FORBIDDEN => 'Forbidden', - self::NOT_FOUND => 'Not Found', - self::METHOD_NOT_ALLOWED => 'Method Not Allowed', - self::NOT_ACCEPTABLE => 'Not Acceptable', - self::PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required', - self::REQUEST_TIME_OUT => 'Request Time-out', - self::CONFLICT => 'Conflict', - self::GONE => 'Gone', - self::LENGTH_REQUIRED => 'Length Required', - self::PRECONDITION_FAILED => 'Precondition Failed', - self::REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large', - self::REQUEST_URI_TOO_LARGE => 'Request-URI Too Large', - self::UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type', + self::CONTINUE => 'Continue', + self::SWITCHING_PROTOCOLS => 'Switching Protocols', + self::PROCESSING => 'Processing', + self::OK => 'OK', + self::CREATED => 'Created', + self::ACCEPTED => 'Accepted', + self::NON_AUTHORITATIVE_INFORMATION => 'Non-Authoritative Information', + self::NO_CONTENT => 'No Content', + self::RESET_CONTENT => 'Reset Content', + self::PARTIAL_CONTENT => 'Partial Content', + self::MULTI_STATUS => 'Multi-status', + self::ALREADY_REPORTED => 'Already Reported', + self::IM_USED => 'IM Used', + self::MULTIPLE_CHOICES => 'Multiple Choices', + self::MOVED_PERMANENTLY => 'Moved Permanently', + self::FOUND => 'Found', + self::SEE_OTHER => 'See Other', + self::NOT_MODIFIED => 'Not Modified', + self::USE_PROXY => 'Use Proxy', + self::SWITCH_PROXY => 'Switch Proxy', + self::TEMPORARY_REDIRECT => 'Temporary Redirect', + self::PERMANENT_REDIRECT => 'Permanent Redirect', + self::BAD_REQUEST => 'Bad Request', + self::UNAUTHORIZED => 'Unauthorized', + self::PAYMENT_REQUIRED => 'Payment Required', + self::FORBIDDEN => 'Forbidden', + self::NOT_FOUND => 'Not Found', + self::METHOD_NOT_ALLOWED => 'Method Not Allowed', + self::NOT_ACCEPTABLE => 'Not Acceptable', + self::PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required', + self::REQUEST_TIME_OUT => 'Request Time-out', + self::CONFLICT => 'Conflict', + self::GONE => 'Gone', + self::LENGTH_REQUIRED => 'Length Required', + self::PRECONDITION_FAILED => 'Precondition Failed', + self::REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large', + self::REQUEST_URI_TOO_LARGE => 'Request-URI Too Large', + self::UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type', self::REQUESTED_RANGE_NOT_SATISFIABLE => 'Requested range not satisfiable', - self::EXPECTATION_FAILED => 'Expectation Failed', - self::MISDIRECTED_REQUEST => 'Misdirected Request', - self::UNPROCESSABLE_ENTITY => 'Unprocessable Entity', - self::LOCKED => 'Locked', - self::FAILED_DEPENDENCY => 'Failed Dependency', - self::UNORDERED_COLLECTION => 'Unordered Collection', - self::UPGRADE_REQUIRED => 'Upgrade Required', - self::PRECONDITION_REQUIRED => 'Precondition Required', - self::TOO_MANY_REQUESTS => 'Too Many Requests', + self::EXPECTATION_FAILED => 'Expectation Failed', + self::MISDIRECTED_REQUEST => 'Misdirected Request', + self::UNPROCESSABLE_ENTITY => 'Unprocessable Entity', + self::LOCKED => 'Locked', + self::FAILED_DEPENDENCY => 'Failed Dependency', + self::UNORDERED_COLLECTION => 'Unordered Collection', + self::UPGRADE_REQUIRED => 'Upgrade Required', + self::PRECONDITION_REQUIRED => 'Precondition Required', + self::TOO_MANY_REQUESTS => 'Too Many Requests', self::REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large', - self::UNAVAILABLE_FOR_LEGAL_REASONS => 'Unavailable For Legal Reasons', - self::INTERNAL_SERVER_ERROR => 'Internal Server Error', - self::NOT_IMPLEMENTED => 'Not Implemented', - self::BAD_GATEWAY => 'Bad Gateway', - self::SERVICE_UNAVAILABLE => 'Service Unavailable', - self::GATEWAY_TIME_OUT => 'Gateway Time-out', - self::HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported', - self::VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates', - self::INSUFFICIENT_STORAGE => 'Insufficient Storage', - self::LOOP_DETECTED => 'Loop Detected', - self::NOT_EXTENDED => 'Not Extended', + self::UNAVAILABLE_FOR_LEGAL_REASONS => 'Unavailable For Legal Reasons', + self::INTERNAL_SERVER_ERROR => 'Internal Server Error', + self::NOT_IMPLEMENTED => 'Not Implemented', + self::BAD_GATEWAY => 'Bad Gateway', + self::SERVICE_UNAVAILABLE => 'Service Unavailable', + self::GATEWAY_TIME_OUT => 'Gateway Time-out', + self::HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported', + self::VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates', + self::INSUFFICIENT_STORAGE => 'Insufficient Storage', + self::LOOP_DETECTED => 'Loop Detected', + self::NOT_EXTENDED => 'Not Extended', self::NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required', ]; diff --git a/src/swoole_library/src/core/MultibyteStringObject.php b/src/swoole_library/src/core/MultibyteStringObject.php index e45b8472..30c145ca 100644 --- a/src/swoole_library/src/core/MultibyteStringObject.php +++ b/src/swoole_library/src/core/MultibyteStringObject.php @@ -18,54 +18,45 @@ public function length(): int return mb_strlen($this->string); } - /** - * @return false|int - */ - public function indexOf(string $needle, int $offset = 0, ?string $encoding = null) + public function indexOf(string $needle, int $offset = 0, ?string $encoding = null): false|int { - return mb_strpos($this->string, ...func_get_args()); + return mb_strpos($this->string, $needle, $offset, $encoding); } - /** - * @return false|int - */ - public function lastIndexOf(string $needle, int $offset = 0, ?string $encoding = null) + public function lastIndexOf(string $needle, int $offset = 0, ?string $encoding = null): false|int { - return mb_strrpos($this->string, ...func_get_args()); + return mb_strrpos($this->string, $needle, $offset, $encoding); } - /** - * @return false|int - */ - public function pos(string $needle, int $offset = 0, ?string $encoding = null) + public function pos(string $needle, int $offset = 0, ?string $encoding = null): false|int { - return mb_strpos($this->string, ...func_get_args()); + return mb_strpos($this->string, $needle, $offset, $encoding); } - /** - * @return false|int - */ - public function rpos(string $needle, int $offset = 0, ?string $encoding = null) + public function rpos(string $needle, int $offset = 0, ?string $encoding = null): false|int { - return mb_strrpos($this->string, ...func_get_args()); + return mb_strrpos($this->string, $needle, $offset, $encoding); } - /** - * @return false|int - */ - public function ipos(string $needle, ?string $encoding = null) + public function ipos(string $needle, int $offset = 0, ?string $encoding = null): int|false { - return mb_stripos($this->string, ...func_get_args()); + return mb_stripos($this->string, $needle, $offset, $encoding); } /** - * @return static + * @todo First parameter will be renamed to $start in Swoole 5.2+. + * @todo This method will be refactored and marked as final in Swoole 5.2+. + * 1. It should use keyword self instead of static. + * 2. Don't use function func_get_args(). */ - public function substr(int $offset, ?int $length = null, ?string $encoding = null) + public function substr(int $offset, ?int $length = null, ?string $encoding = null): static { - return new static(mb_substr($this->string, ...func_get_args())); + return new static(mb_substr($this->string, ...func_get_args())); // @phpstan-ignore new.static } + /** + * @todo This method is not implemented correctly. + */ public function chunk(int $splitLength = 1, ?int $limit = null): ArrayObject { return static::detectArrayType(mb_split($this->string, ...func_get_args())); diff --git a/src/swoole_library/src/core/NameResolver.php b/src/swoole_library/src/core/NameResolver.php index 0ec1a32a..488b6434 100644 --- a/src/swoole_library/src/core/NameResolver.php +++ b/src/swoole_library/src/core/NameResolver.php @@ -19,16 +19,13 @@ abstract class NameResolver { protected $baseUrl; - protected $prefix; - protected $info; private $filter_fn; - public function __construct($url, $prefix = 'swoole_service_') + public function __construct($url, protected $prefix = 'swoole_service_') { $this->checkServerUrl($url); - $this->prefix = $prefix; } abstract public function join(string $name, string $ip, int $port, array $options = []): bool; @@ -58,7 +55,7 @@ public function hasFilter(): bool * and an empty string indicates name lookup failed, and lookup operation will not continue. * return Cluster: has multiple nodes and failover is possible * return false or null: try another name resolver - * @return null|Cluster|false|string + * @return Cluster|false|string|null */ public function lookup(string $name) { @@ -79,9 +76,8 @@ public function lookup(string $name) /** * !!! The host MUST BE IP ADDRESS - * @param mixed $url */ - protected function checkServerUrl($url) + protected function checkServerUrl(string $url) { $info = parse_url($url); if (empty($info['scheme']) or empty($info['host'])) { @@ -103,15 +99,10 @@ protected function checkServerUrl($url) $baseUrl .= rtrim($info['path'], '/'); } $this->baseUrl = $baseUrl; - $this->info = $info; + $this->info = $info; } - /** - * @param $r ClientProxy - * @param mixed $url - * @return bool - */ - protected function checkResponse($r, $url) + protected function checkResponse(?ClientProxy $r, string $url): bool { if (empty($r)) { throw new Exception("failed to request URL({$url})"); diff --git a/src/swoole_library/src/core/NameResolver/Cluster.php b/src/swoole_library/src/core/NameResolver/Cluster.php index bd75b602..ca36ad1c 100644 --- a/src/swoole_library/src/core/NameResolver/Cluster.php +++ b/src/swoole_library/src/core/NameResolver/Cluster.php @@ -15,10 +15,7 @@ class Cluster { - /** - * @var array - */ - private $nodes = []; + private array $nodes = []; /** * @throws Exception @@ -46,7 +43,7 @@ public function pop() return false; } $index = array_rand($this->nodes, 1); - $node = $this->nodes[$index]; + $node = $this->nodes[$index]; unset($this->nodes[$index]); return $node; } diff --git a/src/swoole_library/src/core/NameResolver/Consul.php b/src/swoole_library/src/core/NameResolver/Consul.php index 921625f6..a51865ed 100644 --- a/src/swoole_library/src/core/NameResolver/Consul.php +++ b/src/swoole_library/src/core/NameResolver/Consul.php @@ -28,19 +28,19 @@ class Consul extends NameResolver public function join(string $name, string $ip, int $port, array $options = []): bool { $weight = $options['weight'] ?? 100; - $data = [ - 'ID' => $this->getServiceId($name, $ip, $port), - 'Name' => $this->prefix . $name, - 'Address' => $ip, - 'Port' => $port, + $data = [ + 'ID' => $this->getServiceId($name, $ip, $port), + 'Name' => $this->prefix . $name, + 'Address' => $ip, + 'Port' => $port, 'EnableTagOverride' => false, - 'Weights' => [ + 'Weights' => [ 'Passing' => $weight, 'Warning' => 1, ], ]; $url = $this->baseUrl . '/v1/agent/service/register'; - $r = request($url, 'PUT', json_encode($data)); + $r = request($url, 'PUT', json_encode($data, JSON_THROW_ON_ERROR)); return $this->checkResponse($r, $url); } @@ -69,11 +69,11 @@ public function enableMaintenanceMode(string $name, string $ip, int $port): bool public function getCluster(string $name): ?Cluster { $url = $this->baseUrl . '/v1/catalog/service/' . $this->prefix . $name; - $r = get($url); + $r = get($url); if (!$this->checkResponse($r, $url)) { return null; } - $list = json_decode($r->getBody()); + $list = json_decode($r->getBody(), null, 512, JSON_THROW_ON_ERROR); if (empty($list)) { return null; } diff --git a/src/swoole_library/src/core/NameResolver/Nacos.php b/src/swoole_library/src/core/NameResolver/Nacos.php index ef1228ca..505179f4 100644 --- a/src/swoole_library/src/core/NameResolver/Nacos.php +++ b/src/swoole_library/src/core/NameResolver/Nacos.php @@ -28,16 +28,16 @@ class Nacos extends NameResolver */ public function join(string $name, string $ip, int $port, array $options = []): bool { - $params['port'] = $port; - $params['ip'] = $ip; - $params['healthy'] = 'true'; - $params['weight'] = $options['weight'] ?? 100; - $params['encoding'] = $options['encoding'] ?? 'utf-8'; + $params['port'] = $port; + $params['ip'] = $ip; + $params['healthy'] = 'true'; + $params['weight'] = $options['weight'] ?? 100; + $params['encoding'] = $options['encoding'] ?? 'utf-8'; $params['namespaceId'] = $options['namespaceId'] ?? 'public'; $params['serviceName'] = $this->prefix . $name; $url = $this->baseUrl . '/nacos/v1/ns/instance?' . http_build_query($params); - $r = Coroutine\Http\post($url, []); + $r = Coroutine\Http\post($url, []); return $this->checkResponse($r, $url); } @@ -46,12 +46,12 @@ public function join(string $name, string $ip, int $port, array $options = []): */ public function leave(string $name, string $ip, int $port): bool { - $params['port'] = $port; - $params['ip'] = $ip; + $params['port'] = $port; + $params['ip'] = $ip; $params['serviceName'] = $this->prefix . $name; $url = $this->baseUrl . '/nacos/v1/ns/instance?' . http_build_query($params); - $r = Coroutine\Http\request($this->baseUrl . '/nacos/v1/ns/instance?' . http_build_query($params), 'DELETE'); + $r = Coroutine\Http\request($this->baseUrl . '/nacos/v1/ns/instance?' . http_build_query($params), 'DELETE'); return $this->checkResponse($r, $url); } @@ -63,11 +63,11 @@ public function getCluster(string $name): ?Cluster $params['serviceName'] = $this->prefix . $name; $url = $this->baseUrl . '/nacos/v1/ns/instance/list?' . http_build_query($params); - $r = Coroutine\Http\get($url); + $r = Coroutine\Http\get($url); if (!$this->checkResponse($r, $url)) { return null; } - $result = json_decode($r->getBody()); + $result = json_decode($r->getBody(), null, 512, JSON_THROW_ON_ERROR); if (empty($result)) { return null; } diff --git a/src/swoole_library/src/core/ObjectProxy.php b/src/swoole_library/src/core/ObjectProxy.php index e26b5963..7d3a952a 100644 --- a/src/swoole_library/src/core/ObjectProxy.php +++ b/src/swoole_library/src/core/ObjectProxy.php @@ -16,11 +16,8 @@ class ObjectProxy /** @var object */ protected $__object; - public function __construct($object) + public function __construct(object $object) { - if (!is_object($object)) { - throw new \TypeError('Non-object given'); - } $this->__object = $object; } diff --git a/src/swoole_library/src/core/Server/Admin.php b/src/swoole_library/src/core/Server/Admin.php index a6c5c995..628c932a 100644 --- a/src/swoole_library/src/core/Server/Admin.php +++ b/src/swoole_library/src/core/Server/Admin.php @@ -39,16 +39,16 @@ class Admin public const SIZE_OF_ZEND_ARRAY = 56; - private static $map = [ - 'reactor' => SWOOLE_SERVER_COMMAND_REACTOR_THREAD, + private static array $map = [ + 'reactor' => SWOOLE_SERVER_COMMAND_REACTOR_THREAD, 'reactor_thread' => SWOOLE_SERVER_COMMAND_REACTOR_THREAD, - 'worker' => SWOOLE_SERVER_COMMAND_EVENT_WORKER, - 'event_worker' => SWOOLE_SERVER_COMMAND_EVENT_WORKER, - 'task' => SWOOLE_SERVER_COMMAND_TASK_WORKER, - 'task_worker' => SWOOLE_SERVER_COMMAND_TASK_WORKER, + 'worker' => SWOOLE_SERVER_COMMAND_EVENT_WORKER, + 'event_worker' => SWOOLE_SERVER_COMMAND_EVENT_WORKER, + 'task' => SWOOLE_SERVER_COMMAND_TASK_WORKER, + 'task_worker' => SWOOLE_SERVER_COMMAND_TASK_WORKER, ]; - private static $allList = [ + private static array $allList = [ 'all', 'all_reactor', 'all_reactor_thread', @@ -59,13 +59,13 @@ class Admin 'specific', ]; - private static $postMethodList = [ + private static array $postMethodList = [ 'server_reload', 'server_shutdown', 'close_session', ]; - private static $accessToken = ''; + private static string $accessToken = ''; public static function init(Server $server) { @@ -77,7 +77,7 @@ public static function init(Server $server) $server->addCommand( 'server_reload', $accepted_process_types, - function ($server, $msg) { + function (Server $server, string $msg) { $server->reload(); return self::json('Operation succeeded'); } @@ -86,7 +86,7 @@ function ($server, $msg) { $server->addCommand( 'server_shutdown', $accepted_process_types, - function ($server, $msg) { + function (Server $server, string $msg): void { $server->shutdown(); } ); @@ -94,26 +94,22 @@ function ($server, $msg) { $server->addCommand( 'coroutine_stats', $accepted_process_types, - function ($server, $msg) { - return self::json(Coroutine::stats()); - } + fn (Server $server, string $msg) => self::json(Coroutine::stats()) ); $server->addCommand( 'coroutine_list', $accepted_process_types, - function ($server, $msg) { - return self::json(iterator_to_array(Coroutine::list())); - } + fn (Server $server, string $msg) => self::json(iterator_to_array(Coroutine::list())) ); $server->addCommand( 'coroutine_bt', $accepted_process_types, - function ($server, $msg) { - $json = json_decode($msg); - $cid = empty($json->cid) ? 0 : intval($json->cid); - $bt = Coroutine::getBackTrace($cid); + function (Server $server, string $msg) { + $json = json_decode($msg, null, 512, JSON_THROW_ON_ERROR); + $cid = empty($json->cid) ? 0 : intval($json->cid); + $bt = Coroutine::getBackTrace($cid); if ($bt === false) { return self::json("Coroutine#{$cid} not exists", 4004); } @@ -124,20 +120,18 @@ function ($server, $msg) { $server->addCommand( 'server_stats', $accepted_process_types, - function ($server, $msg) { - return self::json($server->stats()); - } + fn (Server $server, string $msg) => self::json($server->stats()) ); $server->addCommand( 'server_setting', $accepted_process_types, - function (Server $server, $msg) { - $setting = $server->setting; - $setting['mode'] = $server->mode; - $setting['host'] = $server->host; - $setting['port'] = $server->port; - $setting['master_pid'] = $server->master_pid; + function (Server $server, string $msg) { + $setting = $server->setting; + $setting['mode'] = $server->mode; + $setting['host'] = $server->host; + $setting['port'] = $server->port; + $setting['master_pid'] = $server->master_pid; $setting['manager_pid'] = $server->manager_pid; return self::json($setting); } @@ -146,8 +140,8 @@ function (Server $server, $msg) { $server->addCommand( 'get_client_info', $accepted_process_types, - function (Server $server, $msg) { - $json = json_decode($msg, true); + function (Server $server, string $msg) { + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); if (empty($json['session_id'])) { return self::json('require session_id', 4003); } @@ -155,39 +149,38 @@ function (Server $server, $msg) { } ); - $server->addCommand('close_session', $accepted_process_types, [__CLASS__, 'handlerCloseSession']); - $server->addCommand('get_version_info', $accepted_process_types, [__CLASS__, 'handlerGetVersionInfo']); - $server->addCommand('get_worker_info', $accepted_process_types, [__CLASS__, 'handlerGetWorkerInfo']); - $server->addCommand('get_timer_list', $accepted_process_types, [__CLASS__, 'handlerGetTimerList']); - $server->addCommand('get_coroutine_list', $accepted_process_types, [__CLASS__, 'handlerGetCoroutineList']); - $server->addCommand('get_objects', $accepted_process_types, [__CLASS__, 'handlerGetObjects']); - $server->addCommand('get_class_info', $accepted_process_types, [__CLASS__, 'handlerGetClassInfo']); - $server->addCommand('get_function_info', $accepted_process_types, [__CLASS__, 'handlerGetFunctionInfo']); - $server->addCommand('get_object_by_handle', $accepted_process_types, [__CLASS__, 'handlerGetObjectByHandle']); - $server->addCommand('get_server_cpu_usage', $accepted_process_types, [__CLASS__, 'handlerGetServerCpuUsage']); + $server->addCommand('close_session', $accepted_process_types, [self::class, 'handlerCloseSession']); + $server->addCommand('get_version_info', $accepted_process_types, [self::class, 'handlerGetVersionInfo']); + $server->addCommand('get_worker_info', $accepted_process_types, [self::class, 'handlerGetWorkerInfo']); + $server->addCommand('get_timer_list', $accepted_process_types, [self::class, 'handlerGetTimerList']); + $server->addCommand('get_coroutine_list', $accepted_process_types, [self::class, 'handlerGetCoroutineList']); + $server->addCommand('get_objects', $accepted_process_types, [self::class, 'handlerGetObjects']); + $server->addCommand('get_class_info', $accepted_process_types, [self::class, 'handlerGetClassInfo']); + $server->addCommand('get_function_info', $accepted_process_types, [self::class, 'handlerGetFunctionInfo']); + $server->addCommand('get_object_by_handle', $accepted_process_types, [self::class, 'handlerGetObjectByHandle']); + $server->addCommand('get_server_cpu_usage', $accepted_process_types, [self::class, 'handlerGetServerCpuUsage']); $server->addCommand( 'get_server_memory_usage', $accepted_process_types, - [__CLASS__, 'handlerGetServerMemoryUsage'] + [self::class, 'handlerGetServerMemoryUsage'] ); $server->addCommand( 'get_static_property_value', $accepted_process_types, - [__CLASS__, 'handlerGetStaticPropertyValue'] + [self::class, 'handlerGetStaticPropertyValue'] ); $server->addCommand( 'get_defined_functions', $accepted_process_types, - [__CLASS__, 'handlerGetDefinedFunctions'] + [self::class, 'handlerGetDefinedFunctions'] ); - $server->addCommand('get_declared_classes', $accepted_process_types, [__CLASS__, 'handlerGetDeclaredClasses']); + $server->addCommand('get_declared_classes', $accepted_process_types, [self::class, 'handlerGetDeclaredClasses']); $server->addCommand( 'gc_status', $accepted_process_types, - function ($server, $msg) { - $status = function_exists('gc_status') ? gc_status() : []; - return self::json($status); + function (Server $server, string $msg) { + return self::json(gc_status()); } ); @@ -195,45 +188,37 @@ function ($server, $msg) { $server->addCommand( 'opcache_status', $accepted_process_types, - function ($server, $msg) { - return self::json(opcache_get_status(true)); - } + fn (Server $server, string $msg) => self::json(opcache_get_status(true)) ); } $server->addCommand( 'getpid', $accepted_process_types, - function ($server, $msg) { - return self::json(['pid' => posix_getpid()]); - } + fn (Server $server, string $msg) => self::json(['pid' => posix_getpid()]) ); $server->addCommand( 'memory_usage', $accepted_process_types, - function ($server, $msg) { - return self::json([ - 'usage' => memory_get_usage(), - 'real_usage' => memory_get_usage(true), - ]); - } + fn (Server $server, string $msg) => self::json([ + 'usage' => memory_get_usage(), + 'real_usage' => memory_get_usage(true), + ]) ); $server->addCommand( 'get_included_files', $accepted_process_types, - function ($server, $msg) { - return self::json(['files' => get_included_files()]); - } + fn (Server $server, string $msg) => self::json(['files' => get_included_files()]) ); - $server->addCommand('get_resources', $accepted_process_types, [__CLASS__, 'handlerGetResources']); + $server->addCommand('get_resources', $accepted_process_types, [self::class, 'handlerGetResources']); $server->addCommand( 'get_defined_constants', $accepted_process_types, - function ($server, $msg) { + function (Server $server, string $msg) { $constants = get_defined_constants(); foreach ($constants as $k => $c) { if (is_resource($c)) { @@ -248,15 +233,15 @@ function ($server, $msg) { $server->addCommand( 'get_loaded_extensions', $accepted_process_types, - function ($server, $msg) { + function (Server $server, string $msg) { $extensions = get_loaded_extensions(); - $list = []; + $list = []; foreach ($extensions as $key => $extension) { - $ext = new \ReflectionExtension($extension); + $ext = new \ReflectionExtension($extension); $list[$key] = [ - 'id' => ++$key, - 'name' => $extension, - 'version' => $ext->getVersion() ?? '', + 'id' => ++$key, + 'name' => $extension, + 'version' => (string) $ext->getVersion(), ]; } return self::json($list); @@ -266,24 +251,20 @@ function ($server, $msg) { $server->addCommand( 'get_declared_interfaces', $accepted_process_types, - function ($server, $msg) { - return self::json(get_declared_interfaces()); - } + fn (Server $server, string $msg) => self::json(get_declared_interfaces()) ); $server->addCommand( 'get_declared_traits', $accepted_process_types, - function ($server, $msg) { - return self::json(get_declared_traits()); - } + fn (Server $server, string $msg) => self::json(get_declared_traits()) ); $server->addCommand( 'get_included_file_contents', $accepted_process_types, - function (Server $server, $msg) { - $json = json_decode($msg, true); + function (Server $server, string $msg) { + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); if (empty($json['filename'])) { return self::json('require filename', 4003); } @@ -303,18 +284,18 @@ function (Server $server, $msg) { $server->addCommand( 'get_globals', $accepted_process_types, - function ($server, $msg) { + function (Server $server, string $msg) { $globals = []; foreach ($GLOBALS as $key => $item) { if ($key === 'GLOBALS') { continue; } - $type = gettype($item); + $type = gettype($item); $other = []; if ($type === 'object') { $other = [ - 'class_name' => get_class($item), - 'object_id' => spl_object_id($item), + 'class_name' => $item::class, + 'object_id' => spl_object_id($item), 'object_hash' => spl_object_hash($item), ]; } @@ -322,9 +303,9 @@ function ($server, $msg) { $item = ''; } $globals[] = [ - 'key' => $key, + 'key' => $key, 'value' => $item, - 'type' => $type, + 'type' => $type, 'other' => $other, ]; } @@ -335,8 +316,8 @@ function ($server, $msg) { $server->addCommand( 'get_extension_info', $accepted_process_types, - function (Server $server, $msg) { - $json = json_decode($msg, true); + function (Server $server, string $msg) { + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); if (empty($json['extension_name']) || !extension_loaded($json['extension_name'])) { return self::json('require extension_name', 4004); @@ -358,13 +339,13 @@ function (Server $server, $msg) { unset($constants['NULL'], $constants['NAN'], $constants['INF']); return self::json([ - 'classes' => $ext->getClassNames(), - 'version' => $ext->getVersion(), - 'constants' => $constants, - 'ini_entries' => $ext->getINIEntries(), + 'classes' => $ext->getClassNames(), + 'version' => $ext->getVersion(), + 'constants' => $constants, + 'ini_entries' => $ext->getINIEntries(), 'dependencies' => $ext->getDependencies(), - 'functions' => array_keys($ext->getFunctions()), - 'info' => trim($info), + 'functions' => array_keys($ext->getFunctions()), + 'info' => trim($info), ]); } ); @@ -372,7 +353,7 @@ function (Server $server, $msg) { $server->addCommand( 'get_composer_packages', $accepted_process_types, - function (Server $server, $msg) { + function (Server $server, string $msg) { if (!class_exists(\Composer\InstalledVersions::class)) { return self::json('require composer 2.0', 4003); } @@ -395,7 +376,7 @@ function (Server $server, $msg) { $key_name = "__root__{$key}"; } $package['root']['install_path'] = !empty($package['root']['install_path']) ? realpath($package['root']['install_path']) : ''; - $list[$key_name] = $package; + $list[$key_name] = $package; } break; } @@ -409,17 +390,18 @@ public static function getAccessToken(): string return self::$accessToken; } - public static function start(Server $server) + public static function start(Server $server): void { $admin_server_uri = swoole_string($server->setting['admin_server']); if ($admin_server_uri->startsWith('unix:/')) { - return swoole_error_log(SWOOLE_LOG_ERROR, "admin_server[{$server->setting['admin_server']}] is not supported"); + swoole_error_log(SWOOLE_LOG_ERROR, "admin_server[{$server->setting['admin_server']}] is not supported"); + return; } if ($admin_server_uri->contains('@')) { [$access_name, $access_secret] = $admin_server_uri->split('@', 2)->get(0)->split(':', 2)->toArray(); - self::$accessToken = sha1($access_name . $access_secret); - [$host, $port] = $admin_server_uri->split('@', 2)->get(1)->split(':', 2)->toArray(); + self::$accessToken = sha1($access_name . $access_secret); + [$host, $port] = $admin_server_uri->split('@', 2)->get(1)->split(':', 2)->toArray(); } else { [$host, $port] = $admin_server_uri->split(':', 2)->toArray(); } @@ -442,7 +424,8 @@ public static function start(Server $server) $method = $req->getMethod(); if ($method === 'OPTIONS') { - return $resp->end(); + $resp->end(); + return; } $token = self::getAccessToken(); @@ -470,7 +453,7 @@ public static function start(Server $server) } if ($cmd === 'multi') { - $body = json_decode($req->getContent(), true); + $body = json_decode($req->getContent(), true, 512, JSON_THROW_ON_ERROR); if (empty($body) || !is_array($body) || $method != 'POST') { goto _bad_process; } @@ -488,10 +471,10 @@ public static function start(Server $server) if ($process->startsWith('master')) { $process_type = SWOOLE_SERVER_COMMAND_MASTER; - $process_id = 0; + $process_id = 0; } elseif ($process->startsWith('manager')) { $process_type = SWOOLE_SERVER_COMMAND_MANAGER; - $process_id = 0; + $process_id = 0; } elseif ($process->startsWith('all') || $process->equals('specific')) { if (!in_array($process->toString(), self::$allList)) { goto _bad_process; @@ -515,7 +498,7 @@ public static function start(Server $server) } $process_type = self::$map[$array->get(0)->toString()]; - $process_id = intval($array->get(1)->toString()); + $process_id = intval($array->get(1)->toString()); } $result = $server->command($cmd, $process_id, intval($process_type), $data, false); @@ -523,12 +506,12 @@ public static function start(Server $server) $resp->end(json_encode([ 'code' => swoole_last_error(), 'data' => swoole_strerror(swoole_last_error()), - ])); + ], JSON_THROW_ON_ERROR)); } else { $resp->end($result); } }); - $admin_server->handle('/', function (Request $req, Response $resp) use ($server) { + $admin_server->handle('/', function (Request $req, Response $resp): void { $resp->status(404); }); $server->admin_server = $admin_server; @@ -536,17 +519,15 @@ public static function start(Server $server) } /** - * @param $server Server - * @param mixed $msg * @return false|string */ - public static function handlerGetResources($server, $msg) + public static function handlerGetResources(Server $server, string $msg) { $resources = get_resources(); - $list = []; + $list = []; foreach ($resources as $r) { $info = [ - 'id' => function_exists('get_resource_id') ? get_resource_id($r) : intval($r), + 'id' => get_resource_id($r), 'type' => get_resource_type($r), ]; if ($info['type'] == 'stream') { @@ -558,36 +539,30 @@ public static function handlerGetResources($server, $msg) } /** - * @param $server Server - * @param mixed $msg * @return false|string */ - public static function handlerGetWorkerInfo($server, $msg) + public static function handlerGetWorkerInfo(Server $server, string $msg) { $info = [ - 'id' => $server->getWorkerId(), - 'pid' => $server->getWorkerPid(), - 'gc_status' => function_exists('gc_status') ? gc_status() : [], - 'memory_usage' => memory_get_usage(), + 'id' => $server->getWorkerId(), + 'pid' => $server->getWorkerPid(), + 'gc_status' => gc_status(), + 'memory_usage' => memory_get_usage(), 'memory_real_usage' => memory_get_usage(true), - 'process_status' => self::getProcessStatus(), - 'coroutine_stats' => Coroutine::stats(), - 'timer_stats' => Timer::stats(), + 'process_status' => self::getProcessStatus(), + 'coroutine_stats' => Coroutine::stats(), + 'timer_stats' => Timer::stats(), + 'vm_status' => swoole_get_vm_status(), ]; - if (function_exists('swoole_get_vm_status')) { - $info['vm_status'] = swoole_get_vm_status(); - } return self::json($info); } /** - * @param mixed $server - * @param mixed $msg * @return false|string */ - public static function handlerCloseSession($server, $msg) + public static function handlerCloseSession(Server $server, string $msg) { - $json = json_decode($msg, true); + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); if (empty($json['session_id'])) { return self::json('require session_id', 4003); } @@ -598,16 +573,14 @@ public static function handlerCloseSession($server, $msg) } /** - * @param mixed $server - * @param mixed $msg * @return false|string */ - public static function handlerGetTimerList($server, $msg) + public static function handlerGetTimerList(Server $server, string $msg) { $list = []; foreach (Timer::list() as $timer_id) { $list[] = [ - 'id' => $timer_id, + 'id' => $timer_id, 'info' => Timer::info($timer_id), ]; } @@ -616,43 +589,38 @@ public static function handlerGetTimerList($server, $msg) } /** - * @param mixed $server - * @param mixed $msg * @return false|string */ - public static function handlerGetCoroutineList($server, $msg) + public static function handlerGetCoroutineList(Server $server, string $msg) { $list = []; foreach (Coroutine::list() as $cid) { $list[] = [ - 'id' => $cid, - 'elapsed' => Coroutine::getElapsed($cid), + 'id' => $cid, + 'elapsed' => Coroutine::getElapsed($cid), 'stack_usage' => Coroutine::getStackUsage($cid), - 'backTrace' => Coroutine::getBackTrace($cid, DEBUG_BACKTRACE_IGNORE_ARGS, 1), + 'backTrace' => Coroutine::getBackTrace($cid, DEBUG_BACKTRACE_IGNORE_ARGS, 1), ]; } return self::json($list); } - public static function handlerGetObjects($server, $msg) + public static function handlerGetObjects(Server $server, string $msg) { - if (!function_exists('swoole_get_objects')) { - return self::json(['require ext-swoole_plus'], 5000); - } - $list = []; + $list = []; $objects = swoole_get_objects(); foreach ($objects as $o) { - $class_name = get_class($o); - $class = new \ReflectionClass($class_name); - $filename = $class->getFileName(); - $line = $class->getStartLine(); - $list[] = [ - 'id' => spl_object_id($o), - 'hash' => spl_object_hash($o), - 'class' => $class_name, - 'filename' => $filename ?: '', - 'line' => $line ?: '', + $class_name = $o::class; + $class = new \ReflectionClass($class_name); + $filename = $class->getFileName(); + $line = $class->getStartLine(); + $list[] = [ + 'id' => spl_object_id($o), + 'hash' => spl_object_hash($o), + 'class' => $class_name, + 'filename' => $filename ?: '', + 'line' => $line ?: '', 'memory_size' => self::getObjectMemorySize($o), ]; } @@ -660,25 +628,21 @@ public static function handlerGetObjects($server, $msg) return self::json($list); } - public static function handlerGetClassInfo($server, $msg) + public static function handlerGetClassInfo(Server $server, string $msg) { - $json = json_decode($msg, true); - if (empty($json['class_name']) && empty($json['interface_name'])) { - return self::json(['error' => 'require class_name or interface_name'], 4004); - } - + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); if (!empty($json['class_name'])) { if (!class_exists($json['class_name'], false) && !interface_exists($json['class_name'], false)) { return self::json("{$json['class_name']} not exists", 4003); } $name = $json['class_name']; - } - - if (!empty($json['interface_name'])) { + } elseif (!empty($json['interface_name'])) { if (!interface_exists($json['interface_name'], false)) { return self::json("{$json['interface_name']} not exists", 4003); } $name = $json['interface_name']; + } else { + return self::json(['error' => 'require class_name or interface_name'], 4004); } $class = new \ReflectionClass($name); @@ -689,38 +653,38 @@ public static function handlerGetClassInfo($server, $msg) $tmp = []; foreach ($data as $k => $v) { $tmp[] = [ - 'name' => $k, + 'name' => $k, 'value' => is_array($v) ? var_export($v, true) : $v, - 'type' => is_array($v) ? 'detail' : 'default', + 'type' => is_array($v) ? 'detail' : 'default', ]; } return $tmp; }; $tmpConstants = $class->getConstants(); - $constants = $tmpConstants ? $getTmpConstants($tmpConstants) : []; + $constants = $tmpConstants ? $getTmpConstants($tmpConstants) : []; $staticProperties = []; - $properties = []; - $tmpProperties = $class->getProperties(); + $properties = []; + $tmpProperties = $class->getProperties(); $getTmpProperties = function ($class, $data) { - $static = []; - $noStatic = []; + $static = []; + $noStatic = []; $defaultProperties = $class->getDefaultProperties(); foreach ($data as $k => $v) { - $name = $v->getName(); + $name = $v->getName(); $modifiers = \Reflection::getModifierNames($v->getModifiers()); if ($v->isStatic()) { $static[] = [ - 'name' => $name, - 'value' => $defaultProperties[$name], + 'name' => $name, + 'value' => $defaultProperties[$name], 'modifiers' => implode(' ', $modifiers), ]; } else { $noStatic[] = [ - 'name' => $name, - 'value' => $defaultProperties[$name], + 'name' => $name, + 'value' => $defaultProperties[$name], 'modifiers' => implode(' ', $modifiers), ]; } @@ -729,32 +693,32 @@ public static function handlerGetClassInfo($server, $msg) }; if ($tmpProperties) { - $tmpProperties = $getTmpProperties($class, $tmpProperties); + $tmpProperties = $getTmpProperties($class, $tmpProperties); $staticProperties = $tmpProperties['static']; - $properties = $tmpProperties['no_static']; + $properties = $tmpProperties['no_static']; } - $staticMethods = []; - $methods = []; + $staticMethods = []; + $methods = []; $tmpStaticMethods = $class->getMethods(); $getTmpMethods = function ($data) { - $static = []; + $static = []; $noStatic = []; foreach ($data as $k => $v) { - $name = $v->getName(); - $line = $v->getStartLine(); + $name = $v->getName(); + $line = $v->getStartLine(); $modifiers = \Reflection::getModifierNames($v->getModifiers()); if ($v->isStatic()) { $static[] = [ - 'name' => $name, - 'line' => $line ?: '', + 'name' => $name, + 'line' => $line ?: '', 'modifiers' => implode(' ', $modifiers), ]; } else { $noStatic[] = [ - 'name' => $name, - 'line' => $line ?: '', + 'name' => $name, + 'line' => $line ?: '', 'modifiers' => implode(' ', $modifiers), ]; } @@ -764,34 +728,31 @@ public static function handlerGetClassInfo($server, $msg) if ($tmpStaticMethods) { $tmpStaticMethods = $getTmpMethods($tmpStaticMethods); - $staticMethods = $tmpStaticMethods['static']; - $methods = $tmpStaticMethods['no_static']; + $staticMethods = $tmpStaticMethods['static']; + $methods = $tmpStaticMethods['no_static']; } $tmpParentClass = $class->getParentClass(); - $parentClass = $tmpParentClass ? $tmpParentClass->getName() : ''; - - $tmpInterface = $class->getInterfaceNames(); - $interface = $tmpInterface ?? []; + $parentClass = $tmpParentClass ? $tmpParentClass->getName() : ''; $data = [ - 'filename' => $filename, - 'constants' => $constants, + 'filename' => $filename, + 'constants' => $constants, 'staticProperties' => $staticProperties, - 'properties' => $properties, - 'staticMethods' => $staticMethods, - 'methods' => $methods, - 'parentClass' => $parentClass, - 'interface' => $interface, + 'properties' => $properties, + 'staticMethods' => $staticMethods, + 'methods' => $methods, + 'parentClass' => $parentClass, + 'interface' => $class->getInterfaceNames(), ]; return self::json($data); } - public static function handlerGetFunctionInfo($server, $msg) + public static function handlerGetFunctionInfo(Server $server, string $msg) { - $json = json_decode($msg, true); + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); - $className = $json['class_name'] ?? ''; + $className = $json['class_name'] ?? ''; $functionName = $json['function_name'] ?? ''; if (empty($json) || empty($functionName)) { @@ -806,7 +767,7 @@ public static function handlerGetFunctionInfo($server, $msg) if (!method_exists($className, $functionName)) { return self::json("{$className}->{$functionName} not exists", 4004); } - $ref = new \ReflectionMethod($className, $functionName); + $ref = new \ReflectionMethod($className, $functionName); $isStatic = $ref->isStatic(); } else { if (!function_exists($functionName)) { @@ -816,12 +777,12 @@ public static function handlerGetFunctionInfo($server, $msg) } $result = [ - 'filename' => $ref->getFileName(), - 'line' => $ref->getStartLine() ?? '', - 'num' => $ref->getNumberOfParameters(), + 'filename' => $ref->getFileName(), + 'line' => $ref->getStartLine() ?: '', + 'num' => $ref->getNumberOfParameters(), 'user_defined' => $ref->isUserDefined(), - 'extension' => $ref->getExtensionName(), - 'is_static' => $isStatic, + 'extension' => $ref->getExtensionName(), + 'is_static' => $isStatic, ]; $params = $ref->getParameters(); @@ -872,19 +833,19 @@ public static function handlerGetFunctionInfo($server, $msg) } $isPassedByReference = $param->isPassedByReference() ? '&' : ''; - $isVariadic = $param->isVariadic() ? '...' : ''; + $isVariadic = $param->isVariadic() ? '...' : ''; $option = "{$optional}{$type} {$isPassedByReference}{$isVariadic}"; - $param = "\${$paramName}{$default}"; + $param = "\${$paramName}{$default}"; $list[] = [ - 'optional' => $optional, - 'type' => $type, + 'optional' => $optional, + 'type' => $type, 'is_passed_by_reference' => $isPassedByReference, - 'is_variadic' => $isVariadic, - 'name' => $paramName, - 'default' => $default, - 'full' => $option !== ' ' ? "{$option}{$param}" : $param, + 'is_variadic' => $isVariadic, + 'name' => $paramName, + 'default' => $default, + 'full' => $option !== ' ' ? "{$option}{$param}" : $param, ]; } $result['params'] = $list; @@ -892,13 +853,9 @@ public static function handlerGetFunctionInfo($server, $msg) return self::json($result); } - public static function handlerGetObjectByHandle($server, $msg) + public static function handlerGetObjectByHandle(Server $server, string $msg) { - if (!function_exists('swoole_get_object_by_handle')) { - return self::json(['require ext-swoole_plus'], 5000); - } - - $json = json_decode($msg, true); + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); if (empty($json) || empty($json['object_id']) || empty($json['object_hash'])) { return self::json(['error' => 'Params Error!'], 4004); } @@ -916,11 +873,11 @@ public static function handlerGetObjectByHandle($server, $msg) return self::json(var_export($object, true)); } - public static function handlerGetVersionInfo($server, $msg) + public static function handlerGetVersionInfo(Server $server, string $msg) { $ip_arr = swoole_get_local_ip(); - $host = []; - $local = []; + $host = []; + $local = []; foreach ($ip_arr as $k => $ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { $host[] = $ip; @@ -929,55 +886,55 @@ public static function handlerGetVersionInfo($server, $msg) } } $data = [ - 'os' => php_uname('s') . '-' . php_uname('r'), + 'os' => php_uname('s') . '-' . php_uname('r'), 'swoole' => swoole_version(), - 'php' => phpversion(), - 'ip' => $host ? $host[0] : $local[0], + 'php' => phpversion(), + 'ip' => $host ? $host[0] : $local[0], ]; return self::json($data); } - public static function handlerGetDefinedFunctions($server, $msg) + public static function handlerGetDefinedFunctions(Server $server, string $msg) { $functions = get_defined_functions(); - $arr = []; - if ($functions) { - $arr['internal'] = $functions['internal']; - + $arr = [ + 'internal' => $functions['internal'], + ]; + if (!empty($functions['user'])) { foreach ($functions['user'] as $function_name) { - $function = new \ReflectionFunction($function_name); - $filename = $function->getFileName(); - $line = $function->getStartLine(); + $function = new \ReflectionFunction($function_name); + $filename = $function->getFileName(); + $line = $function->getStartLine(); $arr['user'][] = [ 'function' => $function_name, 'filename' => $filename, - 'line' => $line, + 'line' => $line, ]; } } return self::json($arr); } - public static function handlerGetDeclaredClasses($server, $msg) + public static function handlerGetDeclaredClasses(Server $server, string $msg) { $classes = get_declared_classes(); - $arr = []; + $arr = []; if ($classes) { foreach ($classes as $classes_name) { $function = new \ReflectionClass($classes_name); $filename = $function->getFileName(); - $line = $function->getStartLine(); - $arr[] = [ - 'class' => $classes_name, + $line = $function->getStartLine(); + $arr[] = [ + 'class' => $classes_name, 'filename' => $filename ?: '', - 'line' => $line ?: '', + 'line' => $line ?: '', ]; } } return self::json($arr); } - public static function handlerGetServerMemoryUsage($server, $msg) + public static function handlerGetServerMemoryUsage(Server $server, string $msg) { $total = 0; @@ -993,8 +950,9 @@ public static function handlerGetServerMemoryUsage($server, $msg) $total += $result['manager']; $n = $server->setting['worker_num'] + $server->setting['task_worker_num']; + /** @var int $n */ for ($i = 0; $i < $n; $i++) { - $key = 'worker-' . $i; + $key = 'worker-' . $i; $result[$key] = self::getProcessMemoryRealUsage($server->getWorkerPid($i)); $total += $result[$key]; } @@ -1005,13 +963,13 @@ public static function handlerGetServerMemoryUsage($server, $msg) // TODO: Support other OS if (PHP_OS_FAMILY === 'Linux') { preg_match('#MemTotal:\s+(\d+) kB#i', file_get_contents('/proc/meminfo'), $match); - $result['memory_size'] = $match[1] * 1024; + $result['memory_size'] = intval($match[1]) * 1024; } return self::json($result); } - public static function handlerGetServerCpuUsage($server, $msg) + public static function handlerGetServerCpuUsage(Server $server, string $msg) { $total = 0; @@ -1029,21 +987,22 @@ public static function handlerGetServerCpuUsage($server, $msg) $total += $result['manager'][1] ?? 0; $n = $server->setting['worker_num'] + $server->setting['task_worker_num']; + /** @var int $n */ for ($i = 0; $i < $n; $i++) { - $key = 'worker-' . $i; + $key = 'worker-' . $i; $result[$key] = self::getProcessCpuUsage($server->getWorkerPid($i))[1] ?? 0; $total += $result[$key]; } - $result['total'] = $total; + $result['total'] = $total; $result['cpu_num'] = swoole_cpu_num(); return self::json($result); } - public static function handlerGetStaticPropertyValue($server, $msg) + public static function handlerGetStaticPropertyValue(Server $server, string $msg) { - $json = json_decode($msg, true); + $json = json_decode($msg, true, 512, JSON_THROW_ON_ERROR); if (empty($json['class_name'])) { return self::json(['error' => 'require class_name!'], 4004); } @@ -1051,7 +1010,7 @@ public static function handlerGetStaticPropertyValue($server, $msg) return self::json(['error' => 'require property_name!'], 4004); } - $className = $json['class_name']; + $className = $json['class_name']; $propertyName = $json['property_name']; if (!class_exists($className)) { @@ -1059,7 +1018,7 @@ public static function handlerGetStaticPropertyValue($server, $msg) } $reflection = new \ReflectionClass($className); - $value = $reflection->getStaticPropertyValue($propertyName, []); + $value = $reflection->getStaticPropertyValue($propertyName, []); $result = [ 'value' => var_export($value, true), @@ -1072,7 +1031,7 @@ private static function handlerMulti(Server $server, array $list) $return_list = []; foreach ($list as $key => $content) { $path_array = swoole_string($content['path'])->trim('/')->split('/'); - $cmd = $path_array->get(1)->toString(); + $cmd = $path_array->get(1)->toString(); if ($path_array->count() == 2) { $process = swoole_string('master'); @@ -1080,7 +1039,7 @@ private static function handlerMulti(Server $server, array $list) $process = $path_array->get(2); } - $data = []; + $data = []; $url_query = parse_url($process->toString(), PHP_URL_QUERY) ?? []; if (!empty($url_query)) { parse_str($url_query, $data); @@ -1089,10 +1048,10 @@ private static function handlerMulti(Server $server, array $list) if ($process->startsWith('master')) { $process_type = SWOOLE_SERVER_COMMAND_MASTER; - $process_id = 0; + $process_id = 0; } elseif ($process->startsWith('manager')) { $process_type = SWOOLE_SERVER_COMMAND_MANAGER; - $process_id = 0; + $process_id = 0; } elseif ($process->startsWith('all') || $process->startsWith('specific')) { if (!in_array($process->toString(), self::$allList) && !$process->startsWith('specific')) { $return_list[$key] = json_decode('{}'); @@ -1112,7 +1071,7 @@ private static function handlerMulti(Server $server, array $list) } $process_type = self::$map[$array->get(0)->toString()]; - $process_id = intval($array->get(1)->toString()); + $process_id = intval($array->get(1)->toString()); } $return_list[$key] = $server->command($cmd, $process_id, intval($process_type), $data, true); @@ -1149,8 +1108,8 @@ private static function handlerGetAll(Server $server, StringObject $process, $cm if ($array->count() != 2 || !isset(self::$map[$array->get(0)->toString()])) { $result[$name] = $json_decode ? json_decode('{}') : $json_decode; } else { - $process_type = self::$map[$array->get(0)->toString()]; - $process_id = intval($array->get(1)->toString()); + $process_type = self::$map[$array->get(0)->toString()]; + $process_id = intval($array->get(1)->toString()); $result[$name] = $server->command($cmd, $process_id, $process_type, $data, $json_decode); } } @@ -1194,8 +1153,8 @@ private static function handlerGetAllReactor($cmd, $data, Server $server, bool $ private static function handlerGetAllWorker($cmd, $data, Server $server, bool $json_decode = false) { $process_type = SWOOLE_SERVER_COMMAND_EVENT_WORKER; - $worker_num = $server->setting['worker_num']; - $list = []; + $worker_num = $server->setting['worker_num']; + $list = []; for ($process_id = 0; $process_id < $worker_num; $process_id++) { $list["worker-{$process_id}"] = $server->command($cmd, $process_id, $process_type, $data, $json_decode); } @@ -1205,7 +1164,7 @@ private static function handlerGetAllWorker($cmd, $data, Server $server, bool $j private static function handlerGetAllTaskWorker($cmd, $data, Server $server, bool $json_decode = false) { $process_type = SWOOLE_SERVER_COMMAND_TASK_WORKER; - $list = []; + $list = []; if (empty($server->setting['task_worker_num'])) { return $list; } @@ -1223,7 +1182,7 @@ private static function getProcessCpuUsage($pid) return [0]; } - $statAll = file_get_contents('/proc/stat'); + $statAll = file_get_contents('/proc/stat'); $statProc = file_get_contents("/proc/{$pid}/stat"); $dataAll = preg_split("/[ \t]+/", $statAll, 6); @@ -1256,12 +1215,12 @@ private static function getProcessStatus($pid = 'self') return $array; } $status = swoole_string(trim(file_get_contents("/proc/{$pid}/status"))); - $lines = $status->split("\n"); + $lines = $status->split("\n"); foreach ($lines as $l) { if (empty($l)) { continue; } - [$k, $v] = swoole_string($l)->split(':'); + [$k, $v] = swoole_string($l)->split(':'); $array[$k] = trim($v); } return $array; diff --git a/src/swoole_library/src/core/Server/Helper.php b/src/swoole_library/src/core/Server/Helper.php index ca53f692..a9e10e54 100644 --- a/src/swoole_library/src/core/Server/Helper.php +++ b/src/swoole_library/src/core/Server/Helper.php @@ -11,194 +11,194 @@ namespace Swoole\Server; +use Swoole\Constant; +use Swoole\Coroutine; use Swoole\Server; use Swoole\Timer; -use function Swoole\Coroutine\go; - class Helper { public const STATS_TIMER_INTERVAL_TIME = 1000; public const GLOBAL_OPTIONS = [ - 'debug_mode' => true, - 'trace_flags' => true, - 'log_file' => true, - 'log_level' => true, - 'log_date_format' => true, - 'log_date_with_microseconds' => true, - 'log_rotation' => true, - 'display_errors' => true, - 'dns_server' => true, - 'socket_dns_timeout' => true, - 'socket_connect_timeout' => true, - 'socket_write_timeout' => true, - 'socket_send_timeout' => true, - 'socket_read_timeout' => true, - 'socket_recv_timeout' => true, - 'socket_buffer_size' => true, - 'socket_timeout' => true, - 'http2_header_table_size' => true, - 'http2_enable_push' => true, + 'debug_mode' => true, + 'trace_flags' => true, + 'log_file' => true, + 'log_level' => true, + 'log_date_format' => true, + 'log_date_with_microseconds' => true, + 'log_rotation' => true, + 'display_errors' => true, + 'dns_server' => true, + 'socket_dns_timeout' => true, + 'socket_connect_timeout' => true, + 'socket_write_timeout' => true, + 'socket_send_timeout' => true, + 'socket_read_timeout' => true, + 'socket_recv_timeout' => true, + 'socket_buffer_size' => true, + 'socket_timeout' => true, + 'http2_header_table_size' => true, + 'http2_enable_push' => true, 'http2_max_concurrent_streams' => true, - 'http2_init_window_size' => true, - 'http2_max_frame_size' => true, - 'http2_max_header_list_size' => true, + 'http2_init_window_size' => true, + 'http2_max_frame_size' => true, + 'http2_max_header_list_size' => true, ]; public const SERVER_OPTIONS = [ - 'chroot' => true, - 'user' => true, - 'group' => true, - 'daemonize' => true, - 'pid_file' => true, - 'reactor_num' => true, - 'single_thread' => true, - 'worker_num' => true, - 'max_wait_time' => true, - 'max_queued_bytes' => true, - 'max_concurrency' => true, - 'worker_max_concurrency' => true, - 'enable_coroutine' => true, - 'send_timeout' => true, - 'dispatch_mode' => true, - 'send_yield' => true, - 'dispatch_func' => true, - 'discard_timeout_request' => true, - 'enable_unsafe_event' => true, - 'enable_delay_receive' => true, - 'enable_reuse_port' => true, - 'task_use_object' => true, - 'task_object' => true, - 'event_object' => true, - 'task_enable_coroutine' => true, - 'task_worker_num' => true, - 'task_ipc_mode' => true, - 'task_tmpdir' => true, - 'task_max_request' => true, - 'task_max_request_grace' => true, - 'max_connection' => true, - 'max_conn' => true, - 'start_session_id' => true, - 'heartbeat_check_interval' => true, - 'heartbeat_idle_time' => true, - 'max_request' => true, - 'max_request_grace' => true, - 'reload_async' => true, - 'open_cpu_affinity' => true, - 'cpu_affinity_ignore' => true, - 'http_parse_cookie' => true, - 'http_parse_post' => true, - 'http_parse_files' => true, - 'http_compression' => true, - 'http_compression_level' => true, - 'compression_level' => true, - 'http_gzip_level' => true, + 'chroot' => true, + 'user' => true, + 'group' => true, + 'daemonize' => true, + 'pid_file' => true, + 'reactor_num' => true, + 'single_thread' => true, + 'worker_num' => true, + 'max_wait_time' => true, + 'max_queued_bytes' => true, + 'max_concurrency' => true, + 'worker_max_concurrency' => true, + 'enable_coroutine' => true, + 'send_timeout' => true, + 'dispatch_mode' => true, + 'send_yield' => true, + 'dispatch_func' => true, + 'discard_timeout_request' => true, + 'enable_unsafe_event' => true, + 'enable_delay_receive' => true, + 'enable_reuse_port' => true, + 'task_use_object' => true, + 'task_object' => true, + 'event_object' => true, + 'task_enable_coroutine' => true, + 'task_worker_num' => true, + 'task_ipc_mode' => true, + 'task_tmpdir' => true, + 'task_max_request' => true, + 'task_max_request_grace' => true, + 'max_connection' => true, + 'max_conn' => true, + 'start_session_id' => true, + 'heartbeat_check_interval' => true, + 'heartbeat_idle_time' => true, + 'max_request' => true, + 'max_request_grace' => true, + 'reload_async' => true, + 'open_cpu_affinity' => true, + 'cpu_affinity_ignore' => true, + 'http_parse_cookie' => true, + 'http_parse_post' => true, + 'http_parse_files' => true, + 'http_compression' => true, + 'http_compression_level' => true, + 'compression_level' => true, + 'http_gzip_level' => true, 'http_compression_min_length' => true, - 'compression_min_length' => true, - 'websocket_compression' => true, - 'upload_tmp_dir' => true, - 'upload_max_filesize' => true, - 'enable_static_handler' => true, - 'document_root' => true, - 'http_autoindex' => true, - 'http_index_files' => true, - 'http_compression_types' => true, - 'compression_types' => true, - 'static_handler_locations' => true, - 'input_buffer_size' => true, - 'buffer_input_size' => true, - 'output_buffer_size' => true, - 'buffer_output_size' => true, - 'message_queue_key' => true, + 'compression_min_length' => true, + 'websocket_compression' => true, + 'upload_tmp_dir' => true, + 'upload_max_filesize' => true, + 'enable_static_handler' => true, + 'document_root' => true, + 'http_autoindex' => true, + 'http_index_files' => true, + 'http_compression_types' => true, + 'compression_types' => true, + 'static_handler_locations' => true, + 'input_buffer_size' => true, + 'buffer_input_size' => true, + 'output_buffer_size' => true, + 'buffer_output_size' => true, + 'message_queue_key' => true, ]; public const PORT_OPTIONS = [ - 'ssl_cert_file' => true, - 'ssl_key_file' => true, - 'backlog' => true, - 'socket_buffer_size' => true, + 'ssl_cert_file' => true, + 'ssl_key_file' => true, + 'backlog' => true, + 'socket_buffer_size' => true, 'kernel_socket_recv_buffer_size' => true, 'kernel_socket_send_buffer_size' => true, - 'heartbeat_idle_time' => true, - 'buffer_high_watermark' => true, - 'buffer_low_watermark' => true, - 'open_tcp_nodelay' => true, - 'tcp_defer_accept' => true, - 'open_tcp_keepalive' => true, - 'open_eof_check' => true, - 'open_eof_split' => true, - 'package_eof' => true, - 'open_http_protocol' => true, - 'open_websocket_protocol' => true, - 'websocket_subprotocol' => true, - 'open_websocket_close_frame' => true, - 'open_websocket_ping_frame' => true, - 'open_websocket_pong_frame' => true, - 'open_http2_protocol' => true, - 'open_mqtt_protocol' => true, - 'open_redis_protocol' => true, - 'max_idle_time' => true, - 'tcp_keepidle' => true, - 'tcp_keepinterval' => true, - 'tcp_keepcount' => true, - 'tcp_user_timeout' => true, - 'tcp_fastopen' => true, - 'open_length_check' => true, - 'package_length_type' => true, - 'package_length_offset' => true, - 'package_body_offset' => true, - 'package_body_start' => true, - 'package_length_func' => true, - 'package_max_length' => true, - 'ssl_compress' => true, - 'ssl_protocols' => true, - 'ssl_verify_peer' => true, - 'ssl_allow_self_signed' => true, - 'ssl_client_cert_file' => true, - 'ssl_verify_depth' => true, - 'ssl_prefer_server_ciphers' => true, - 'ssl_ciphers' => true, - 'ssl_ecdh_curve' => true, - 'ssl_dhparam' => true, - 'ssl_sni_certs' => true, + 'heartbeat_idle_time' => true, + 'buffer_high_watermark' => true, + 'buffer_low_watermark' => true, + 'open_tcp_nodelay' => true, + 'tcp_defer_accept' => true, + 'open_tcp_keepalive' => true, + 'open_eof_check' => true, + 'open_eof_split' => true, + 'package_eof' => true, + 'open_http_protocol' => true, + 'open_websocket_protocol' => true, + 'websocket_subprotocol' => true, + 'open_websocket_close_frame' => true, + 'open_websocket_ping_frame' => true, + 'open_websocket_pong_frame' => true, + 'open_http2_protocol' => true, + 'open_mqtt_protocol' => true, + 'open_redis_protocol' => true, + 'max_idle_time' => true, + 'tcp_keepidle' => true, + 'tcp_keepinterval' => true, + 'tcp_keepcount' => true, + 'tcp_user_timeout' => true, + 'tcp_fastopen' => true, + 'open_length_check' => true, + 'package_length_type' => true, + 'package_length_offset' => true, + 'package_body_offset' => true, + 'package_body_start' => true, + 'package_length_func' => true, + 'package_max_length' => true, + 'ssl_compress' => true, + 'ssl_protocols' => true, + 'ssl_verify_peer' => true, + 'ssl_allow_self_signed' => true, + 'ssl_client_cert_file' => true, + 'ssl_verify_depth' => true, + 'ssl_prefer_server_ciphers' => true, + 'ssl_ciphers' => true, + 'ssl_ecdh_curve' => true, + 'ssl_dhparam' => true, + 'ssl_sni_certs' => true, ]; public const AIO_OPTIONS = [ - 'aio_core_worker_num' => true, - 'aio_worker_num' => true, - 'aio_max_wait_time' => true, - 'aio_max_idle_time' => true, - 'enable_signalfd' => true, - 'wait_signal' => true, + 'aio_core_worker_num' => true, + 'aio_worker_num' => true, + 'aio_max_wait_time' => true, + 'aio_max_idle_time' => true, + 'enable_signalfd' => true, + 'wait_signal' => true, 'dns_cache_refresh_time' => true, - 'thread_num' => true, - 'min_thread_num' => true, - 'max_thread_num' => true, - 'socket_dontwait' => true, - 'dns_lookup_random' => true, - 'use_async_resolver' => true, - 'enable_coroutine' => true, + 'thread_num' => true, + 'min_thread_num' => true, + 'max_thread_num' => true, + 'socket_dontwait' => true, + 'dns_lookup_random' => true, + 'use_async_resolver' => true, + 'enable_coroutine' => true, ]; public const COROUTINE_OPTIONS = [ - 'max_coro_num' => true, - 'max_coroutine' => true, - 'enable_deadlock_check' => true, - 'hook_flags' => true, + 'max_coro_num' => true, + 'max_coroutine' => true, + 'enable_deadlock_check' => true, + 'hook_flags' => true, 'enable_preemptive_scheduler' => true, - 'c_stack_size' => true, - 'stack_size' => true, - 'name_resolver' => true, - 'dns_cache_expire' => true, - 'dns_cache_capacity' => true, - 'max_concurrency' => true, + 'c_stack_size' => true, + 'stack_size' => true, + 'name_resolver' => true, + 'dns_cache_expire' => true, + 'dns_cache_capacity' => true, + 'max_concurrency' => true, ]; public const HELPER_OPTIONS = [ - 'stats_file' => true, + 'stats_file' => true, 'stats_timer_interval' => true, - 'admin_server' => true, + 'admin_server' => true, ]; public static function checkOptions(array $input_options) @@ -224,7 +224,7 @@ public static function onBeforeStart(Server $server) public static function onBeforeShutdown(Server $server) { - if ($server->admin_server) { + if ($server->admin_server) { // @phpstan-ignore if.alwaysTrue $server->admin_server->shutdown(); $server->admin_server = null; } @@ -236,10 +236,10 @@ public static function onWorkerStart(Server $server, int $workerId) $interval_ms = empty($server->setting['stats_timer_interval']) ? self::STATS_TIMER_INTERVAL_TIME : intval($server->setting['stats_timer_interval']); $server->stats_timer = Timer::tick($interval_ms, function () use ($server) { - $stats = $server->stats(); + $stats = $server->stats(); $stats_file = swoole_string($server->setting['stats_file']); if ($stats_file->endsWith('.json')) { - $out = json_encode($stats); + $out = json_encode($stats, JSON_THROW_ON_ERROR); } elseif ($stats_file->endsWith('.php')) { $out = "setting['admin_server'])) { - go(function () use ($server) { + if (!empty($server->setting[Constant::OPTION_ADMIN_SERVER])) { + Coroutine::create(function () use ($server): void { Admin::start($server); }); } diff --git a/src/swoole_library/src/core/StringObject.php b/src/swoole_library/src/core/StringObject.php index c083076f..613e7493 100644 --- a/src/swoole_library/src/core/StringObject.php +++ b/src/swoole_library/src/core/StringObject.php @@ -11,19 +11,13 @@ namespace Swoole; -class StringObject +class StringObject implements \Stringable { - /** - * @var string - */ - protected $string; - /** * StringObject constructor. */ - public function __construct(string $string = '') + public function __construct(protected string $string = '') { - $this->string = $string; } public function __toString(): string @@ -31,9 +25,9 @@ public function __toString(): string return $this->string; } - public static function from(string $string = ''): self + public static function from(string $string = ''): static { - return new static($string); + return new static($string); // @phpstan-ignore new.static } public function length(): int @@ -41,44 +35,29 @@ public function length(): int return strlen($this->string); } - /** - * @return false|int - */ - public function indexOf(string $needle, int $offset = 0) + public function indexOf(string $needle, int $offset = 0): false|int { - return strpos($this->string, ...func_get_args()); + return strpos($this->string, $needle, $offset); } - /** - * @return false|int - */ - public function lastIndexOf(string $needle, int $offset = 0) + public function lastIndexOf(string $needle, int $offset = 0): false|int { - return strrpos($this->string, ...func_get_args()); + return strrpos($this->string, $needle, $offset); } - /** - * @return false|int - */ - public function pos(string $needle, int $offset = 0) + public function pos(string $needle, int $offset = 0): false|int { - return strpos($this->string, ...func_get_args()); + return strpos($this->string, $needle, $offset); } - /** - * @return false|int - */ - public function rpos(string $needle, int $offset = 0) + public function rpos(string $needle, int $offset = 0): false|int { - return strrpos($this->string, ...func_get_args()); + return strrpos($this->string, $needle, $offset); } - /** - * @return static - */ - public function reverse(): self + public function reverse(): static { - return new static(strrev($this->string)); + return new static(strrev($this->string)); // @phpstan-ignore new.static } /** @@ -89,32 +68,22 @@ public function ipos(string $needle) return stripos($this->string, $needle); } - /** - * @return static - */ - public function lower(): self + public function lower(): static { - return new static(strtolower($this->string)); + return new static(strtolower($this->string)); // @phpstan-ignore new.static } - /** - * @return static - */ - public function upper(): self + public function upper(): static { - return new static(strtoupper($this->string)); + return new static(strtoupper($this->string)); // @phpstan-ignore new.static } - /** - * @param mixed $characters - * @return static - */ - public function trim($characters = ''): self + public function trim(string $characters = ''): static { if ($characters) { - return new static(trim($this->string, $characters)); + return new static(trim($this->string, $characters)); // @phpstan-ignore new.static } - return new static(trim($this->string)); + return new static(trim($this->string)); // @phpstan-ignore new.static } /** @@ -122,7 +91,7 @@ public function trim($characters = ''): self */ public function ltrim(): self { - return new static(ltrim($this->string)); + return new static(ltrim($this->string)); // @phpstan-ignore new.static } /** @@ -130,7 +99,7 @@ public function ltrim(): self */ public function rtrim(): self { - return new static(rtrim($this->string)); + return new static(rtrim($this->string)); // @phpstan-ignore new.static } /** @@ -138,38 +107,30 @@ public function rtrim(): self */ public function substr(int $offset, ?int $length = null) { - return new static(substr($this->string, ...func_get_args())); + return new static(substr($this->string, ...func_get_args())); // @phpstan-ignore new.static } - /** - * @return static - */ - public function repeat(int $times): self + public function repeat(int $times): static { - return new static(str_repeat($this->string, $times)); + return new static(str_repeat($this->string, $times)); // @phpstan-ignore new.static } - /** - * @param mixed $str - * @return static - */ - public function append($str): self + public function append(mixed $str): static { - return new static($this->string .= $str); + return new static($this->string .= $str); // @phpstan-ignore new.static } /** - * @param null|int $count - * @return static + * @param int|null $count */ - public function replace(string $search, string $replace, &$count = null): self + public function replace(string $search, string $replace, &$count = null): static { - return new static(str_replace($search, $replace, $this->string, $count)); + return new static(str_replace($search, $replace, $this->string, $count)); // @phpstan-ignore new.static } public function startsWith(string $needle): bool { - return strpos($this->string, $needle) === 0; + return str_starts_with($this->string, $needle); } public function endsWith(string $needle): bool @@ -190,7 +151,7 @@ public function equals($str, bool $strict = false): bool public function contains(string $subString): bool { - return strpos($this->string, $subString) !== false; + return str_contains($this->string, $subString); } public function split(string $delimiter, int $limit = PHP_INT_MAX): ArrayObject @@ -206,12 +167,9 @@ public function char(int $index): string return $this->string[$index]; } - /** - * @return static - */ - public function chunkSplit(int $chunkLength = 76, string $chunkEnd = ''): self + public function chunkSplit(int $chunkLength = 76, string $chunkEnd = ''): static { - return new static(chunk_split($this->string, ...func_get_args())); + return new static(chunk_split($this->string, ...func_get_args())); // @phpstan-ignore new.static } public function chunk(int $splitLength = 1): ArrayObject diff --git a/src/swoole_library/src/functions.php b/src/swoole_library/src/functions.php index a0a27be6..a29be444 100644 --- a/src/swoole_library/src/functions.php +++ b/src/swoole_library/src/functions.php @@ -13,7 +13,7 @@ throw new RuntimeException('require PHP version 7.2 or later'); } -if (SWOOLE_USE_SHORTNAME) { +if (SWOOLE_USE_SHORTNAME) { // @phpstan-ignore if.alwaysTrue function _string(string $string = ''): Swoole\StringObject { return new Swoole\StringObject($string); @@ -32,25 +32,31 @@ function _array(array $array = []): Swoole\ArrayObject class SwooleLibrary { - public static $options = []; + /** + * @var array + */ + public static array $options = []; } -function swoole_library_set_options(array $options) +/** + * @param array $options + */ +function swoole_library_set_options(array $options): void { SwooleLibrary::$options = $options; } -function swoole_library_get_options() +function swoole_library_get_options(): array { return SwooleLibrary::$options; } -function swoole_library_set_option(string $key, $value) +function swoole_library_set_option(string $key, mixed $value): void { SwooleLibrary::$options[$key] = $value; } -function swoole_library_get_option(string $key) +function swoole_library_get_option(string $key): mixed { return SwooleLibrary::$options[$key] ?? null; } @@ -77,7 +83,7 @@ function swoole_table(int $size, string $fields): Swoole\Table $table = new Swoole\Table($size, 0.25); foreach ($_fields as $f) { - $_f = swoole_string($f)->trim()->split(':'); + $_f = swoole_string($f)->trim()->split(':'); $name = $_f->get(0)->trim()->toString(); $type = $_f->get(1)->trim(); @@ -103,7 +109,6 @@ function swoole_table(int $size, string $fields): Swoole\Table break; default: throw new RuntimeException("unknown field type[{$type}]"); - break; } } @@ -142,15 +147,15 @@ function swoole_container_cpu_num() // cgroup v2 $cpu_max = '/sys/fs/cgroup/cpu.max'; if (file_exists($cpu_max)) { - $cpu_max = file_get_contents($cpu_max); - $fields = explode($cpu_max, ' '); + $cpu_max = file_get_contents($cpu_max); + $fields = explode($cpu_max, ' '); $quota_us = $fields[0]; if ($quota_us == 'max') { return swoole_cpu_num(); } $period_us = $fields[1] ?? 100000; } else { - $quota_us = file_get_contents('/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us'); + $quota_us = file_get_contents('/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us'); $period_us = file_get_contents('/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us'); } $cpu_num = floatval($quota_us) / floatval($period_us); @@ -159,23 +164,3 @@ function swoole_container_cpu_num() } return intval(floor($cpu_num)); } - -if (!function_exists('array_key_last')) { - function array_key_last(array $array) - { - if (!empty($array)) { - return key(array_slice($array, -1, 1, true)); - } - return null; - } -} - -if (!function_exists('array_key_first')) { - function array_key_first(array $array) - { - foreach ($array as $key => $unused) { - return $key; - } - return null; - } -}