PHP80 小修 (#187)

* migrate-php80

fix styles
fix static analyse

* fix some bugs
This commit is contained in:
sunxyw
2022-12-19 20:22:47 +08:00
committed by GitHub
parent da516b487d
commit 8ff7da4d23
46 changed files with 180 additions and 366 deletions

View File

@@ -84,5 +84,5 @@ define('ZM_STATE_DIR', TMP_DIR . '/.zm_' . sha1(ZM_INIT_TIME . FRAMEWORK_ROOT_DI
&& define('SWOOLE_HOOK_NATIVE_CURL', 4096) && define('SWOOLE_HOOK_NATIVE_CURL', 4096)
&& define('SWOOLE_HOOK_BLOCKING_FUNCTION', 8192) && define('SWOOLE_HOOK_BLOCKING_FUNCTION', 8192)
&& define('SWOOLE_HOOK_SOCKETS', 16384) && define('SWOOLE_HOOK_SOCKETS', 16384)
&& define('SWOOLE_HOOK_ALL', 2147481599) && define('SWOOLE_HOOK_ALL', 2_147_481_599)
); );

View File

@@ -28,7 +28,7 @@ if (function_exists('zm_internal_errcode')) {
*/ */
function zm_dir(string $dir): string function zm_dir(string $dir): string
{ {
if (strpos($dir, 'phar://') === 0) { if (str_starts_with($dir, 'phar://')) {
return $dir; return $dir;
} }
return str_replace('/', DIRECTORY_SEPARATOR, $dir); return str_replace('/', DIRECTORY_SEPARATOR, $dir);
@@ -46,10 +46,8 @@ function zm_exec(string $cmd): ExecutionResult
/** /**
* sleep 指定时间单位为秒最小单位为1毫秒即0.001 * sleep 指定时间单位为秒最小单位为1毫秒即0.001
*
* @param float|int $time
*/ */
function zm_sleep($time) function zm_sleep(float|int $time)
{ {
Adaptive::sleep($time); Adaptive::sleep($time);
} }
@@ -64,10 +62,8 @@ function coroutine(): ?CoroutineInterface
/** /**
* 获取内部错误码 * 获取内部错误码
*
* @param int|string $code
*/ */
function zm_internal_errcode($code): string function zm_internal_errcode(int|string $code): string
{ {
return "[ErrCode:{$code}] "; return "[ErrCode:{$code}] ";
} }

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace ZM\Annotation; namespace ZM\Annotation;
abstract class AnnotationBase implements \IteratorAggregate abstract class AnnotationBase implements \IteratorAggregate, \Stringable
{ {
/** @var array|\Closure|string 方法名或闭包 */ /** @var array|\Closure|string 方法名或闭包 */
public \Closure|string|array $method = ''; public \Closure|string|array $method = '';
@@ -13,9 +13,9 @@ abstract class AnnotationBase implements \IteratorAggregate
public array $group = []; public array $group = [];
public function __toString() public function __toString(): string
{ {
$str = __CLASS__ . ': '; $str = self::class . ': ';
foreach ($this as $k => $v) { foreach ($this as $k => $v) {
$str .= "\n\t" . $k . ' => '; $str .= "\n\t" . $k . ' => ';
if (is_string($v)) { if (is_string($v)) {
@@ -39,10 +39,8 @@ abstract class AnnotationBase implements \IteratorAggregate
/** /**
* 在 InstantPlugin 下调用,设置回调或匿名函数 * 在 InstantPlugin 下调用,设置回调或匿名函数
*
* @param \Closure|string $method
*/ */
public function on($method): AnnotationBase public function on(\Closure|callable|string $method): AnnotationBase
{ {
$this->method = $method; $this->method = $method;
return $this; return $this;

View File

@@ -58,8 +58,7 @@ class AnnotationHandler
/** /**
* 设置执行前判断注解是否应该被执行的检查回调函数 * 设置执行前判断注解是否应该被执行的检查回调函数
* *
* @param callable $rule 回调函数 * @param callable $rule 回调函数
* @return $this
*/ */
public function setRuleCallback(callable $rule): AnnotationHandler public function setRuleCallback(callable $rule): AnnotationHandler
{ {
@@ -71,8 +70,7 @@ class AnnotationHandler
/** /**
* 设置成功执行后有返回值时执行的返回值后续逻辑回调函数 * 设置成功执行后有返回值时执行的返回值后续逻辑回调函数
* *
* @param callable $return 回调函数 * @param callable $return 回调函数
* @return $this
*/ */
public function setReturnCallback(callable $return): AnnotationHandler public function setReturnCallback(callable $return): AnnotationHandler
{ {
@@ -88,7 +86,7 @@ class AnnotationHandler
* @param mixed ...$params 传入的参数们 * @param mixed ...$params 传入的参数们
* @throws \Throwable * @throws \Throwable
*/ */
public function handleAll(...$params) public function handleAll(mixed ...$params)
{ {
try { try {
// 遍历注册的注解 // 遍历注册的注解

View File

@@ -138,7 +138,7 @@ class AnnotationParser
// 预处理0排除所有非继承于 AnnotationBase 的注解 // 预处理0排除所有非继承于 AnnotationBase 的注解
if (!$vs instanceof AnnotationBase) { if (!$vs instanceof AnnotationBase) {
logger()->notice(get_class($vs) . ' is not extended from ' . AnnotationBase::class); logger()->notice($vs::class . ' is not extended from ' . AnnotationBase::class);
continue; continue;
} }
@@ -172,7 +172,7 @@ class AnnotationParser
foreach ($methods_annotations as $method_anno) { foreach ($methods_annotations as $method_anno) {
// 预处理3.0:排除所有非继承于 AnnotationBase 的注解 // 预处理3.0:排除所有非继承于 AnnotationBase 的注解
if (!$method_anno instanceof AnnotationBase) { if (!$method_anno instanceof AnnotationBase) {
logger()->notice('Binding annotation ' . get_class($method_anno) . ' to ' . $v . '::' . $method_name . ' is not extended from ' . AnnotationBase::class); logger()->notice('Binding annotation ' . $method_anno::class . ' to ' . $v . '::' . $method_name . ' is not extended from ' . AnnotationBase::class);
continue; continue;
} }
@@ -225,11 +225,11 @@ class AnnotationParser
if ($class_annotation instanceof ErgodicAnnotation) { if ($class_annotation instanceof ErgodicAnnotation) {
continue; continue;
} }
$o[get_class($class_annotation)][] = $class_annotation; $o[$class_annotation::class][] = $class_annotation;
} }
foreach (($obj['methods_annotations'] ?? []) as $methods_annotations) { foreach (($obj['methods_annotations'] ?? []) as $methods_annotations) {
foreach ($methods_annotations as $annotation) { foreach ($methods_annotations as $annotation) {
$o[get_class($annotation)][] = $annotation; $o[$annotation::class][] = $annotation;
} }
} }
} }
@@ -238,7 +238,7 @@ class AnnotationParser
public function parseSpecial($annotation, $same_method_annotations = null): ?bool public function parseSpecial($annotation, $same_method_annotations = null): ?bool
{ {
foreach (($this->special_parsers[get_class($annotation)] ?? []) as $parser) { foreach (($this->special_parsers[$annotation::class] ?? []) as $parser) {
$result = $parser($annotation, $same_method_annotations); $result = $parser($annotation, $same_method_annotations);
if (is_bool($result)) { if (is_bool($result)) {
return $result; return $result;

View File

@@ -23,20 +23,16 @@ use ZM\Annotation\Interfaces\Level;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)] #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
class BindEvent extends AnnotationBase implements Level class BindEvent extends AnnotationBase implements Level
{ {
/**
* @Required()
*/
public string $event_class;
public int $level = 800;
/** /**
* @param string $event_class 绑定事件的类型 * @param string $event_class 绑定事件的类型
*/ */
public function __construct(string $event_class, int $level = 800) public function __construct(
{ /**
$this->event_class = $event_class; * @Required()
$this->level = $level; */
public string $event_class,
public int $level = 800
) {
} }
public function getLevel(): int public function getLevel(): int

View File

@@ -19,10 +19,7 @@ use ZM\Annotation\AnnotationBase;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)] #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
class Init extends AnnotationBase class Init extends AnnotationBase
{ {
public int $worker = 0; public function __construct(public int $worker = 0)
public function __construct(int $worker = 0)
{ {
$this->worker = $worker;
} }
} }

View File

@@ -20,13 +20,11 @@ use ZM\Annotation\Interfaces\ErgodicAnnotation;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS)] #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS)]
class Controller extends AnnotationBase implements ErgodicAnnotation class Controller extends AnnotationBase implements ErgodicAnnotation
{ {
/** public function __construct(
* @Required() /**
*/ * @Required()
public string $prefix = ''; */
public string $prefix
public function __construct(string $prefix) ) {
{
$this->prefix = $prefix;
} }
} }

View File

@@ -19,26 +19,18 @@ use ZM\Annotation\AnnotationBase;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)] #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
class Route extends AnnotationBase class Route extends AnnotationBase
{ {
/** public function __construct(
* @Required() /**
*/ * @Required()
public string $route = ''; */
public $route,
public string $name = ''; public $name = '',
public $request_method = ['GET', 'POST'],
public array $request_method = ['GET', 'POST']; /**
* Routing path params binding. eg. {"id"="\d+"}
/** */
* Routing path params binding. eg. {"id"="\d+"} public $params = []
*/ ) {
public array $params = [];
public function __construct($route, $name = '', $request_method = ['GET', 'POST'], $params = [])
{
$this->route = $route;
$this->name = $name;
$this->request_method = $request_method;
$this->params = $params;
} }
public static function make($route, $name = '', $request_method = ['GET', 'POST'], $params = []): static public static function make($route, $name = '', $request_method = ['GET', 'POST'], $params = []): static

View File

@@ -21,18 +21,14 @@ use ZM\Annotation\Interfaces\ErgodicAnnotation;
class Middleware extends AnnotationBase implements ErgodicAnnotation class Middleware extends AnnotationBase implements ErgodicAnnotation
{ {
/** /**
* @Required() * @param string[] $params
*/ */
public string $name; public function __construct(
/**
/** * @Required()
* @var string[] */
*/ public $name,
public array $params = []; public array $params = []
) {
public function __construct($name, $params = [])
{
$this->name = $name;
$this->params = $params;
} }
} }

View File

@@ -22,59 +22,13 @@ use ZM\Exception\ZMKnownException;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)] #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
class BotCommand extends AnnotationBase implements Level class BotCommand extends AnnotationBase implements Level
{ {
public string $name = '';
public string $match = '';
public string $pattern = '';
public string $regex = '';
public string $start_with = '';
public string $end_with = '';
public string $keyword = '';
/** @var string[] */
public array $alias = [];
public string $message_type = '';
public string $user_id = '';
public string $group_id = '';
public int $level = 20;
private array $arguments = []; private array $arguments = [];
public function __construct( /**
$name = '', * @param string[] $alias
$match = '', */
$pattern = '', public function __construct(public $name = '', public $match = '', public $pattern = '', public $regex = '', public $start_with = '', public $end_with = '', public $keyword = '', public $alias = [], public $message_type = '', public $user_id = '', public $group_id = '', public $level = 20)
$regex = '', {
$start_with = '',
$end_with = '',
$keyword = '',
$alias = [],
$message_type = '',
$user_id = '',
$group_id = '',
$level = 20
) {
$this->name = $name;
$this->match = $match;
$this->pattern = $pattern;
$this->regex = $regex;
$this->start_with = $start_with;
$this->end_with = $end_with;
$this->keyword = $keyword;
$this->alias = $alias;
$this->message_type = $message_type;
$this->user_id = $user_id;
$this->group_id = $group_id;
$this->level = $level;
} }
public static function make( public static function make(
@@ -95,7 +49,6 @@ class BotCommand extends AnnotationBase implements Level
} }
/** /**
* @return $this
* @throws InvalidArgumentException * @throws InvalidArgumentException
* @throws ZMKnownException * @throws ZMKnownException
*/ */

View File

@@ -19,32 +19,8 @@ use ZM\Annotation\AnnotationBase;
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class BotEvent extends AnnotationBase class BotEvent extends AnnotationBase
{ {
public ?string $type; public function __construct(public ?string $type = null, public ?string $detail_type = null, public ?string $impl = null, public ?string $platform = null, public ?string $self_id = null, public ?string $sub_type = null)
{
public ?string $detail_type;
public ?string $impl;
public ?string $platform;
public ?string $self_id;
public ?string $sub_type;
public function __construct(
?string $type = null,
?string $detail_type = null,
?string $impl = null,
?string $platform = null,
?string $self_id = null,
?string $sub_type = null
) {
$this->type = $type;
$this->detail_type = $detail_type;
$this->impl = $impl;
$this->platform = $platform;
$this->self_id = $self_id;
$this->sub_type = $sub_type;
} }
public static function make( public static function make(

View File

@@ -20,25 +20,8 @@ use ZM\Exception\ZMKnownException;
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_ALL)] #[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_ALL)]
class CommandArgument extends AnnotationBase implements ErgodicAnnotation class CommandArgument extends AnnotationBase implements ErgodicAnnotation
{ {
/**
* @Required()
*/
public string $name;
public string $description = '';
public string $type = 'string'; public string $type = 'string';
public bool $required = false;
public string $prompt = '';
public string $default = '';
public int $timeout = 60;
public int $error_prompt_policy = 1;
/** /**
* @param string $name 参数名称(可以是中文) * @param string $name 参数名称(可以是中文)
* @param string $description 参数描述(默认为空) * @param string $description 参数描述(默认为空)
@@ -49,23 +32,19 @@ class CommandArgument extends AnnotationBase implements ErgodicAnnotation
* @throws InvalidArgumentException|ZMKnownException * @throws InvalidArgumentException|ZMKnownException
*/ */
public function __construct( public function __construct(
string $name, /**
string $description = '', * @Required()
*/
public string $name,
public string $description = '',
string $type = 'string', string $type = 'string',
bool $required = false, public bool $required = false,
string $prompt = '', public string $prompt = '',
string $default = '', public string $default = '',
int $timeout = 60, public int $timeout = 60,
int $error_prompt_policy = 1 public int $error_prompt_policy = 1
) { ) {
$this->name = $name;
$this->description = $description;
$this->type = $this->fixTypeName($type); $this->type = $this->fixTypeName($type);
$this->required = $required;
$this->prompt = $prompt;
$this->default = $default;
$this->timeout = $timeout;
$this->error_prompt_policy = $error_prompt_policy;
if ($this->type === 'bool') { if ($this->type === 'bool') {
if ($this->default === '') { if ($this->default === '') {
$this->default = 'yes'; $this->default = 'yes';

View File

@@ -11,7 +11,7 @@ class CheckConfigCommand extends Command
{ {
use SourceLoadModeOnly; use SourceLoadModeOnly;
private $need_update = false; private bool $need_update = false;
protected function handle(): int protected function handle(): int
{ {

View File

@@ -130,9 +130,7 @@ class InitCommand extends Command
// TODO: 优化代码,避免在循环中使用 array_merge 以减少资源消耗 // TODO: 优化代码,避免在循环中使用 array_merge 以减少资源消耗
$files = array_merge($files, glob($this->getVendorPath($pattern), GLOB_BRACE)); $files = array_merge($files, glob($this->getVendorPath($pattern), GLOB_BRACE));
} }
return array_map(function ($file) { return array_map(fn ($file) => str_replace($this->getVendorPath(''), '', $file), $files);
return str_replace($this->getVendorPath(''), '', $file);
}, $files);
} }
/** /**

View File

@@ -143,7 +143,7 @@ class ProxyServerCommand extends Command
$ip = 0; $ip = 0;
for ($i = 0; $i < 4; ++$i) { for ($i = 0; $i < 4; ++$i) {
// var_dump(ord($tmp[$i])); // var_dump(ord($tmp[$i]));
$ip += ord($tmp[$i]) * pow(256, 3 - $i); $ip += ord($tmp[$i]) * 256 ** (3 - $i);
} }
$request['dest_addr'] = long2ip($ip); $request['dest_addr'] = long2ip($ip);
$offset += 4; $offset += 4;
@@ -308,6 +308,7 @@ class ProxyServerCommand extends Command
public function udpWorkerOnMessage($udp_connection, $data, &$worker) public function udpWorkerOnMessage($udp_connection, $data, &$worker)
{ {
$addr = [];
logger()->debug('send:' . bin2hex($data)); logger()->debug('send:' . bin2hex($data));
$request = []; $request = [];
$offset = 0; $offset = 0;
@@ -326,7 +327,7 @@ class ProxyServerCommand extends Command
$tmp = substr($data, $offset, 4); $tmp = substr($data, $offset, 4);
$ip = 0; $ip = 0;
for ($i = 0; $i < 4; ++$i) { for ($i = 0; $i < 4; ++$i) {
$ip += ord($tmp[$i]) * pow(256, 3 - $i); $ip += ord($tmp[$i]) * 256 ** (3 - $i);
} }
$request['dest_addr'] = long2ip($ip); $request['dest_addr'] = long2ip($ip);
$offset += 4; $offset += 4;
@@ -412,15 +413,11 @@ class ProxyServerCommand extends Command
$this->config['auth'] = [0 => true]; $this->config['auth'] = [0 => true];
$type = $input->getOption('type') ?? 'http'; $type = $input->getOption('type') ?? 'http';
logger()->notice('Proxy server started at ' . $type . '://' . $address . ':' . $port); logger()->notice('Proxy server started at ' . $type . '://' . $address . ':' . $port);
switch ($type) { match ($type) {
case 'http': 'http' => $this->startHttpProxy($address, $port),
$this->startHttpProxy($address, $port); 'socks', 'socks5' => $this->startSocksProxy($address, $port),
break; default => 0,
case 'socks': };
case 'socks5':
$this->startSocksProxy($address, $port);
break;
}
return 0; return 0;
} }
@@ -464,7 +461,7 @@ class ProxyServerCommand extends Command
* @param string $address 地址 * @param string $address 地址
* @param int|string $port 端口 * @param int|string $port 端口
*/ */
private function startSocksProxy(string $address, $port) private function startSocksProxy(string $address, int|string $port)
{ {
define('STAGE_INIT', 0); define('STAGE_INIT', 0);
define('STAGE_AUTH', 1); define('STAGE_AUTH', 1);

View File

@@ -21,9 +21,7 @@ class ServerStartCommand extends ServerCommand
{ {
$cmd = new self(); $cmd = new self();
$cmd->configure(); $cmd->configure();
return array_map(function ($x) { return array_map(fn ($x) => $x->getDefault(), $cmd->getDefinition()->getOptions());
return $x->getDefault();
}, $cmd->getDefinition()->getOptions());
} }
protected function configure() protected function configure()

View File

@@ -33,7 +33,7 @@ class ServerStopCommand extends ServerCommand
$pid = file_get_contents($file_path . '/' . $file); $pid = file_get_contents($file_path . '/' . $file);
Process::kill((int) $pid, SIGKILL); Process::kill((int) $pid, SIGKILL);
} elseif ($file === 'master.json') { } elseif ($file === 'master.json') {
$json = json_decode(file_get_contents($file_path . '/' . $file), true); $json = json_decode(file_get_contents($file_path . '/' . $file), true, 512, JSON_THROW_ON_ERROR);
Process::kill($json['pid'], SIGKILL); Process::kill($json['pid'], SIGKILL);
} }
unlink($file_path . '/' . $file); unlink($file_path . '/' . $file);

View File

@@ -60,7 +60,7 @@ class ZMConfig
/** /**
* @var null|ConfigTracer 配置跟踪器 * @var null|ConfigTracer 配置跟踪器
*/ */
private ?ConfigTracer $tracer; private ?ConfigTracer $tracer = null;
/** /**
* 构造配置实例 * 构造配置实例
@@ -159,7 +159,7 @@ class ZMConfig
* *
* @return null|array|mixed * @return null|array|mixed
*/ */
public function get(string $key, $default = null) public function get(string $key, mixed $default = null)
{ {
return $this->holder->get($key, $default); return $this->holder->get($key, $default);
} }
@@ -174,7 +174,7 @@ class ZMConfig
* @param array|string $key 配置项名称,可使用.访问数组 * @param array|string $key 配置项名称,可使用.访问数组
* @param mixed $value 要写入的值,传入 null 会进行删除 * @param mixed $value 要写入的值,传入 null 会进行删除
*/ */
public function set($key, $value = null): void public function set(array|string $key, mixed $value = null): void
{ {
$keys = is_array($key) ? $key : [$key => $value]; $keys = is_array($key) ? $key : [$key => $value];
foreach ($keys as $i_key => $i_val) { foreach ($keys as $i_key => $i_val) {
@@ -294,7 +294,7 @@ class ZMConfig
// 2. 文件名.环境:如 test.development此时加载类型为 environment // 2. 文件名.环境:如 test.development此时加载类型为 environment
// 3. 文件名.patch如 test.patch此时加载类型为 patch // 3. 文件名.patch如 test.patch此时加载类型为 patch
// 至于其他的格式,则为未定义行为 // 至于其他的格式,则为未定义行为
if (strpos($name, '.') === false) { if (!str_contains($name, '.')) {
return 'default'; return 'default';
} }
$name_and_env = explode('.', $name); $name_and_env = explode('.', $name);

View File

@@ -19,7 +19,7 @@ use ZM\Store\FileSystem;
*/ */
final class ConsoleApplication extends Application final class ConsoleApplication extends Application
{ {
private static $obj; private static ?ConsoleApplication $obj = null;
public function __construct(string $name = 'zhamao-framework') public function __construct(string $name = 'zhamao-framework')
{ {

View File

@@ -12,12 +12,11 @@ class BoundMethod
* 调用指定闭包、类方法并注入依赖 * 调用指定闭包、类方法并注入依赖
* *
* @param Container $container * @param Container $container
* @param callable|string $callback
* @return mixed * @return mixed
* @throws EntryResolutionException|\ReflectionException * @throws EntryResolutionException|\ReflectionException
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public static function call(ContainerInterface $container, $callback, array $parameters = [], string $default_method = null) public static function call(ContainerInterface $container, callable|string $callback, array $parameters = [], string $default_method = null)
{ {
if (is_string($callback) && !$default_method && method_exists($callback, '__invoke')) { if (is_string($callback) && !$default_method && method_exists($callback, '__invoke')) {
$default_method = '__invoke'; $default_method = '__invoke';
@@ -41,10 +40,9 @@ class BoundMethod
/** /**
* Get all dependencies for a given method. * Get all dependencies for a given method.
* *
* @param callable|string $callback
* @throws \ReflectionException * @throws \ReflectionException
*/ */
protected static function getMethodDependencies(ContainerInterface $container, $callback, array $parameters = []): array protected static function getMethodDependencies(ContainerInterface $container, callable|string $callback, array $parameters = []): array
{ {
$dependencies = []; $dependencies = [];

View File

@@ -10,47 +10,42 @@ use ZM\Utils\ReflectionUtil;
trait ContainerTrait trait ContainerTrait
{ {
/** protected array $shared = [];
* @var array
*/
protected $shared = [];
/** /**
* @var array[] * @var array[]
*/ */
protected $build_stack = []; protected array $build_stack = [];
/** /**
* @var array[] * @var array[]
*/ */
protected $with = []; protected array $with = [];
/** /**
* 日志前缀 * 日志前缀
*
* @var string
*/ */
protected $log_prefix; protected string $log_prefix;
/** /**
* @var array[] * @var array[]
*/ */
private static $bindings = []; private static array $bindings = [];
/** /**
* @var object[] * @var object[]
*/ */
private static $instances = []; private static array $instances = [];
/** /**
* @var string[] * @var string[]
*/ */
private static $aliases = []; private static array $aliases = [];
/** /**
* @var \Closure[][] * @var \Closure[][]
*/ */
private static $extenders = []; private static array $extenders = [];
public function __construct() public function __construct()
{ {
@@ -188,7 +183,7 @@ trait ContainerTrait
* @param mixed $instance 实例 * @param mixed $instance 实例
* @return mixed * @return mixed
*/ */
public function instance(string $abstract, $instance) public function instance(string $abstract, mixed $instance)
{ {
if (isset(self::$instances[$abstract])) { if (isset(self::$instances[$abstract])) {
return self::$instances[$abstract]; return self::$instances[$abstract];
@@ -211,9 +206,7 @@ trait ContainerTrait
*/ */
public function factory(string $abstract): \Closure public function factory(string $abstract): \Closure
{ {
return function () use ($abstract) { return fn () => $this->make($abstract);
return $this->make($abstract);
};
} }
/** /**
@@ -313,7 +306,7 @@ trait ContainerTrait
* @return mixed * @return mixed
* @throws EntryResolutionException * @throws EntryResolutionException
*/ */
public function build($concrete) public function build(\Closure|string $concrete)
{ {
// 如果传入的是闭包,则直接执行并返回 // 如果传入的是闭包,则直接执行并返回
if ($concrete instanceof \Closure) { if ($concrete instanceof \Closure) {
@@ -363,7 +356,7 @@ trait ContainerTrait
* @param null|string $default_method 默认方法 * @param null|string $default_method 默认方法
* @return mixed * @return mixed
*/ */
public function call($callback, array $parameters = [], string $default_method = null) public function call(callable|string $callback, array $parameters = [], string $default_method = null)
{ {
if ($this->shouldLog()) { if ($this->shouldLog()) {
if (count($parameters)) { if (count($parameters)) {
@@ -446,7 +439,7 @@ trait ContainerTrait
*/ */
public function getLogPrefix(): string public function getLogPrefix(): string
{ {
return ($this->log_prefix ?: '[WorkerContainer(U)]') . ' '; return ($this->log_prefix ?? '[WorkerContainer(U)]') . ' ';
} }
/** /**
@@ -674,10 +667,9 @@ trait ContainerTrait
/** /**
* 获取类名的实际类型 * 获取类名的实际类型
* *
* @param string $abstract 类或接口名 * @param string $abstract 类或接口名
* @return \Closure|string
*/ */
protected function getConcrete(string $abstract) protected function getConcrete(string $abstract): \Closure|string
{ {
if (isset(self::$bindings[$abstract])) { if (isset(self::$bindings[$abstract])) {
return self::$bindings[$abstract]['concrete']; return self::$bindings[$abstract]['concrete'];
@@ -692,7 +684,7 @@ trait ContainerTrait
* @param mixed $concrete 实际类型 * @param mixed $concrete 实际类型
* @param string $abstract 类或接口名 * @param string $abstract 类或接口名
*/ */
protected function isBuildable($concrete, string $abstract): bool protected function isBuildable(mixed $concrete, string $abstract): bool
{ {
return $concrete === $abstract || $concrete instanceof \Closure; return $concrete === $abstract || $concrete instanceof \Closure;
} }

View File

@@ -14,10 +14,10 @@ class EventProvider implements SortedProviderInterface
/** /**
* @var array<string, array<array<int, callable>>> 已注册的事件监听器 * @var array<string, array<array<int, callable>>> 已注册的事件监听器
*/ */
private static $_events = []; private static array $_events = [];
/** @var array @phpstan-ignore-next-line */ /** @var array @phpstan-ignore-next-line */
private static $_event_map = []; private static array $_event_map = [];
/** /**
* 添加事件监听器 * 添加事件监听器
@@ -30,15 +30,15 @@ class EventProvider implements SortedProviderInterface
{ {
if (is_object($event)) { // 传入对象时必须带 class 和 method 属性,这时将忽略 callback 参数 if (is_object($event)) { // 传入对象时必须带 class 和 method 属性,这时将忽略 callback 参数
if (property_exists($event, 'class') && property_exists($event, 'method')) { if (property_exists($event, 'class') && property_exists($event, 'method')) {
self::$_events[get_class($event)][] = [$level, [resolve($event->class), $event->method]]; self::$_events[$event::class][] = [$level, [resolve($event->class), $event->method]];
self::$_event_map[$event->class][$event->method][] = $event; self::$_event_map[$event->class][$event->method][] = $event;
} elseif (is_array($callback) && is_object($callback[0] ?? '') && is_string($callback[1] ?? null)) { } elseif (is_array($callback) && is_object($callback[0] ?? '') && is_string($callback[1] ?? null)) {
// 如果没有上面两个属性,则可能是回调函数是一个数组,如果是这样,则可以直接使用回调函数 // 如果没有上面两个属性,则可能是回调函数是一个数组,如果是这样,则可以直接使用回调函数
self::$_event_map[get_class($callback[0])][$callback[1]][] = $event; self::$_event_map[$callback[0]::class][$callback[1]][] = $event;
$event->class = get_class($callback[0]); $event->class = $callback[0]::class;
$event->method = $callback[1]; $event->method = $callback[1];
} }
$this->sortEvents(get_class($event)); $this->sortEvents($event::class);
} elseif (is_string($event)) { } elseif (is_string($event)) {
self::$_events[$event][] = [$level, $callback]; self::$_events[$event][] = [$level, $callback];
$this->sortEvents($event); $this->sortEvents($event);
@@ -66,18 +66,14 @@ class EventProvider implements SortedProviderInterface
*/ */
public function getListenersForEvent(object $event): iterable public function getListenersForEvent(object $event): iterable
{ {
return self::getEventListeners(method_exists($event, 'getName') ? $event->getName() : get_class($event)); return $this->getEventListeners(method_exists($event, 'getName') ? $event->getName() : $event::class);
} }
/** /**
* 排序事件 * 排序事件
*
* @param string|\Stringable $name
*/ */
private function sortEvents($name) private function sortEvents(string|\Stringable $name)
{ {
usort(self::$_events[$name], function ($a, $b) { usort(self::$_events[$name], fn ($a, $b) => $a[0] <= $b[0] ? 1 : -1);
return $a[0] <= $b[0] ? 1 : -1;
});
} }
} }

View File

@@ -17,10 +17,8 @@ class SignalListener
/** /**
* 用于记录 Ctrl+C 的次数 * 用于记录 Ctrl+C 的次数
*
* @var int
*/ */
private static $manager_kill_time = 0; private static int $manager_kill_time = 0;
/** /**
* 开启 Worker 进程的 SIGINT 监听 * 开启 Worker 进程的 SIGINT 监听

View File

@@ -181,9 +181,7 @@ class WorkerEventListener
private function dispatchInit(): void private function dispatchInit(): void
{ {
$handler = new AnnotationHandler(Init::class); $handler = new AnnotationHandler(Init::class);
$handler->setRuleCallback(function (Init $anno) { $handler->setRuleCallback(fn (Init $anno) => $anno->worker === -1 || $anno->worker === ProcessManager::getProcessId());
return $anno->worker === -1 || $anno->worker === ProcessManager::getProcessId();
});
$handler->handleAll(); $handler->handleAll();
} }

View File

@@ -6,11 +6,8 @@ namespace ZM\Exception;
class InterruptException extends ZMException class InterruptException extends ZMException
{ {
public $return_var; public function __construct(public $return_var = null, $message = '', $code = 0, \Throwable $previous = null)
public function __construct($return_var = null, $message = '', $code = 0, \Throwable $previous = null)
{ {
parent::__construct($message, '', $code, $previous); parent::__construct($message, '', $code, $previous);
$this->return_var = $return_var;
} }
} }

View File

@@ -30,6 +30,7 @@ use ZM\Exception\SingletonViolationException;
use ZM\Exception\ZMKnownException; use ZM\Exception\ZMKnownException;
use ZM\Logger\TablePrinter; use ZM\Logger\TablePrinter;
use ZM\Process\ProcessStateManager; use ZM\Process\ProcessStateManager;
use ZM\Store\FileSystem;
use ZM\Utils\EasterEgg; use ZM\Utils\EasterEgg;
/** /**
@@ -173,10 +174,8 @@ class Framework
/** /**
* 获取驱动 * 获取驱动
*
* @return Driver|SwooleDriver|WorkermanDriver
*/ */
public function getDriver() public function getDriver(): Driver
{ {
return $this->driver; return $this->driver;
} }
@@ -242,7 +241,7 @@ class Framework
// 框架多进程依赖 // 框架多进程依赖
if (defined('ZM_STATE_DIR') && !is_dir(ZM_STATE_DIR)) { if (defined('ZM_STATE_DIR') && !is_dir(ZM_STATE_DIR)) {
mkdir(ZM_STATE_DIR); FileSystem::createDir(ZM_STATE_DIR);
} }
} }
@@ -408,7 +407,7 @@ class Framework
logger()->emergency('代码解析错误!'); logger()->emergency('代码解析错误!');
exit(1); exit(1);
} }
$json = json_decode($r, true); $json = json_decode($r, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($json)) { if (!is_array($json)) {
logger()->error(zm_internal_errcode('E00012') . '解析 @OnSetup 时发生错误,请检查代码!'); logger()->error(zm_internal_errcode('E00012') . '解析 @OnSetup 时发生错误,请检查代码!');
return; return;

View File

@@ -14,22 +14,22 @@ class MiddlewareHandler
/** /**
* @var array 存储中间件的 * @var array 存储中间件的
*/ */
protected $middlewares = []; protected array $middlewares = [];
/** /**
* @var array 存储注册中间件的类和方法 * @var array 存储注册中间件的类和方法
*/ */
protected $reg_map = []; protected array $reg_map = [];
/** /**
* @var array 用于将中间件名称压栈 * @var array 用于将中间件名称压栈
*/ */
protected $stack = []; protected array $stack = [];
/** /**
* @var array 用于将正在运行的中间件压栈 * @var array 用于将正在运行的中间件压栈
*/ */
protected $callable_stack = []; protected array $callable_stack = [];
public function registerBefore(string $name, callable $callback) public function registerBefore(string $name, callable $callback)
{ {
@@ -44,7 +44,7 @@ class MiddlewareHandler
&& isset($this->middlewares[$name]['before']) // 且存在before && isset($this->middlewares[$name]['before']) // 且存在before
&& is_array($this->middlewares[$name]['before']) // 且before也是数组类型callback && is_array($this->middlewares[$name]['before']) // 且before也是数组类型callback
&& is_object($this->middlewares[$name]['before'][0]) // 且before类型也为动态调用 && is_object($this->middlewares[$name]['before'][0]) // 且before类型也为动态调用
&& get_class($this->middlewares[$name]['before'][0]) === get_class($callback[0]) // 且before和after在一个类 && $this->middlewares[$name]['before'][0]::class === $callback[0]::class // 且before和after在一个类
) { ) {
// 那么就把after的对象替换为和before同一个 // 那么就把after的对象替换为和before同一个
$callback[0] = $this->middlewares[$name]['before'][0]; $callback[0] = $this->middlewares[$name]['before'][0];
@@ -173,7 +173,7 @@ class MiddlewareHandler
} }
if (is_array($callback) && count($callback) === 2) { if (is_array($callback) && count($callback) === 2) {
// 活性调用,根据组合名称来判断 // 活性调用,根据组合名称来判断
return (is_object($callback[0]) ? get_class($callback[0]) : $callback[0]) . '::' . $callback[1]; return (is_object($callback[0]) ? $callback[0]::class : $callback[0]) . '::' . $callback[1];
} }
if (is_string($callback)) { if (is_string($callback)) {
return $callback; return $callback;

View File

@@ -18,8 +18,7 @@ class Pipeline
/** /**
* 向管道发送数据 * 向管道发送数据
* *
* @param mixed $value 数据 * @param mixed $value 数据
* @return $this
*/ */
public function send(mixed $value): Pipeline public function send(mixed $value): Pipeline
{ {
@@ -30,8 +29,7 @@ class Pipeline
/** /**
* 指定要过的中间件列表 * 指定要过的中间件列表
* *
* @param array $middlewares 要过的中间件(或者叫兼容管道的中间件也行)列表 * @param array $middlewares 要过的中间件(或者叫兼容管道的中间件也行)列表
* @return $this
*/ */
public function through(array $middlewares): Pipeline public function through(array $middlewares): Pipeline
{ {

View File

@@ -12,11 +12,10 @@ class ProcessStateManager
public static array $process_mode = []; public static array $process_mode = [];
/** /**
* @param null|int|string $id_or_name
* @throws ZMKnownException * @throws ZMKnownException
* @internal * @internal
*/ */
public static function removeProcessState(int $type, $id_or_name = null) public static function removeProcessState(int $type, int|string $id_or_name = null)
{ {
switch ($type) { switch ($type) {
case ZM_PROCESS_MASTER: case ZM_PROCESS_MASTER:
@@ -64,12 +63,11 @@ class ProcessStateManager
/** /**
* 用于框架内部获取多进程运行状态的函数 * 用于框架内部获取多进程运行状态的函数
* *
* @param mixed $id_or_name
* @return false|int|mixed * @return false|int|mixed
* @throws ZMKnownException * @throws ZMKnownException
* @internal * @internal
*/ */
public static function getProcessState(int $type, $id_or_name = null) public static function getProcessState(int $type, mixed $id_or_name = null)
{ {
$file = ZM_STATE_DIR; $file = ZM_STATE_DIR;
switch ($type) { switch ($type) {
@@ -78,10 +76,7 @@ class ProcessStateManager
return false; return false;
} }
$json = json_decode(file_get_contents(zm_dir($file . '/master.json')), true); $json = json_decode(file_get_contents(zm_dir($file . '/master.json')), true);
if ($json !== null) { return $json ?? false;
return $json;
}
return false;
case ZM_PROCESS_MANAGER: case ZM_PROCESS_MANAGER:
if (!file_exists(zm_dir($file . '/manager.pid'))) { if (!file_exists(zm_dir($file . '/manager.pid'))) {
return false; return false;
@@ -119,10 +114,9 @@ class ProcessStateManager
/** /**
* 将各进程的pid写入文件以备后续崩溃及僵尸进程处理使用 * 将各进程的pid写入文件以备后续崩溃及僵尸进程处理使用
* *
* @param int|string $pid
* @internal * @internal
*/ */
public static function saveProcessState(int $type, $pid, array $data = []) public static function saveProcessState(int $type, int|string $pid, array $data = [])
{ {
switch ($type) { switch ($type) {
case ZM_PROCESS_MASTER: case ZM_PROCESS_MASTER:

View File

@@ -12,7 +12,7 @@ use Doctrine\DBAL\ParameterType;
class DBConnection implements Connection class DBConnection implements Connection
{ {
/** @var \PDO */ /** @var \PDO */
private $conn; private object $conn;
private $pool_name; private $pool_name;

View File

@@ -19,7 +19,7 @@ class DBPool
/** /**
* @var array<string, SwooleObjectPool|WorkermanObjectPool> 连接池列表 * @var array<string, SwooleObjectPool|WorkermanObjectPool> 连接池列表
*/ */
private static $pools = []; private static array $pools = [];
/** /**
* 通过配置文件创建一个 MySQL 连接池 * 通过配置文件创建一个 MySQL 连接池
@@ -68,10 +68,9 @@ class DBPool
/** /**
* 获取一个数据库连接池 * 获取一个数据库连接池
* *
* @param string $name 连接池名称 * @param string $name 连接池名称
* @return SwooleObjectPool|WorkermanObjectPool
*/ */
public static function pool(string $name) public static function pool(string $name): PoolInterface
{ {
if (!isset(self::$pools[$name]) && count(self::$pools) !== 1) { if (!isset(self::$pools[$name]) && count(self::$pools) !== 1) {
throw new \RuntimeException("Pool {$name} not found"); throw new \RuntimeException("Pool {$name} not found");

View File

@@ -9,7 +9,7 @@ use ZM\Store\Database\DBException as DbException;
class DBQueryBuilder extends QueryBuilder class DBQueryBuilder extends QueryBuilder
{ {
private $wrapper; private DBWrapper $wrapper;
public function __construct(DBWrapper $wrapper) public function __construct(DBWrapper $wrapper)
{ {
@@ -18,10 +18,9 @@ class DBQueryBuilder extends QueryBuilder
} }
/** /**
* @return DBStatementWrapper|int
* @throws DbException * @throws DbException
*/ */
public function execute() public function execute(): DBStatementWrapper|int
{ {
if ($this->getType() === self::SELECT) { if ($this->getType() === self::SELECT) {
return $this->wrapper->executeQuery($this->getSQL(), $this->getParameters(), $this->getParameterTypes()); return $this->wrapper->executeQuery($this->getSQL(), $this->getParameters(), $this->getParameterTypes());

View File

@@ -13,12 +13,8 @@ use Doctrine\DBAL\ParameterType;
class DBStatement implements \IteratorAggregate, Statement class DBStatement implements \IteratorAggregate, Statement
{ {
/** @var \PDOStatement */ public function __construct(private \PDOStatement $statement)
private $statement;
public function __construct($obj)
{ {
$this->statement = $obj;
} }
public function closeCursor() public function closeCursor()

View File

@@ -14,11 +14,8 @@ use Doctrine\DBAL\ForwardCompatibility\Result;
class DBStatementWrapper class DBStatementWrapper
{ {
public ?Result $stmt; public function __construct(public ?Result $stmt)
public function __construct(?Result $stmt)
{ {
$this->stmt = $stmt;
} }
/** /**

View File

@@ -22,7 +22,7 @@ class DBWrapper
{ {
try { try {
$db_list = config()->get('global.database'); $db_list = config()->get('global.database');
if (isset($db_list[$name]) || count($db_list) === 1) { if (isset($db_list[$name]) || (is_countable($db_list) ? count($db_list) : 0) === 1) {
if ($name === '') { if ($name === '') {
$name = array_key_first($db_list); $name = array_key_first($db_list);
} }
@@ -66,10 +66,9 @@ class DBWrapper
/** /**
* wrapper method * wrapper method
* @return array|false
* @throws DBException * @throws DBException
*/ */
public function fetchAssociative(string $query, array $params = [], array $types = []) public function fetchAssociative(string $query, array $params = [], array $types = []): array|false
{ {
try { try {
return $this->connection->fetchAssociative($query, $params, $types); return $this->connection->fetchAssociative($query, $params, $types);
@@ -80,10 +79,9 @@ class DBWrapper
/** /**
* wrapper method * wrapper method
* @return array|false
* @throws DBException * @throws DBException
*/ */
public function fetchNumeric(string $query, array $params = [], array $types = []) public function fetchNumeric(string $query, array $params = [], array $types = []): array|false
{ {
try { try {
return $this->connection->fetchNumeric($query, $params, $types); return $this->connection->fetchNumeric($query, $params, $types);
@@ -182,10 +180,9 @@ class DBWrapper
/** /**
* wrapper method * wrapper method
* @param mixed $value
* @param null|int|string|Type $type * @param null|int|string|Type $type
*/ */
public function quote($value, $type = ParameterType::STRING) public function quote(mixed $value, $type = ParameterType::STRING)
{ {
return $this->connection->quote($value, $type); return $this->connection->quote($value, $type);
} }
@@ -414,7 +411,7 @@ class DBWrapper
* @return int|string the number of affected rows * @return int|string the number of affected rows
* @throws DBException * @throws DBException
*/ */
public function executeStatement(string $sql, array $params = [], array $types = []) public function executeStatement(string $sql, array $params = [], array $types = []): int|string
{ {
try { try {
return $this->connection->executeStatement($sql, $params, $types); return $this->connection->executeStatement($sql, $params, $types);
@@ -436,7 +433,7 @@ class DBWrapper
* @param null|string $name name of the sequence object from which the ID should be returned * @param null|string $name name of the sequence object from which the ID should be returned
* @return false|int|string a string representation of the last inserted ID * @return false|int|string a string representation of the last inserted ID
*/ */
public function lastInsertId(?string $name = null) public function lastInsertId(?string $name = null): false|int|string
{ {
return $this->connection->lastInsertId($name); return $this->connection->lastInsertId($name);
} }
@@ -600,13 +597,10 @@ class DBWrapper
*/ */
private function getConnectionClass(string $type): string private function getConnectionClass(string $type): string
{ {
switch ($type) { return match ($type) {
case 'mysql': 'mysql' => MySQLDriver::class,
return MySQLDriver::class; 'sqlite' => SQLiteDriver::class,
case 'sqlite': default => throw new DBException('Unknown database type: ' . $type),
return SQLiteDriver::class; };
default:
throw new DBException('Unknown database type: ' . $type);
}
} }
} }

View File

@@ -11,14 +11,13 @@ class FileSystem
/** /**
* 递归或非递归扫描目录,可返回相对目录的文件列表或绝对目录的文件列表 * 递归或非递归扫描目录,可返回相对目录的文件列表或绝对目录的文件列表
* *
* @param string $dir 目录 * @param string $dir 目录
* @param bool $recursive 是否递归扫描子目录 * @param bool $recursive 是否递归扫描子目录
* @param bool|string $relative 是否返回相对目录如果为true则返回相对目录如果为false则返回绝对目录 * @param bool|string $relative 是否返回相对目录如果为true则返回相对目录如果为false则返回绝对目录
* @param bool $include_dir 非递归模式下,是否包含目录 * @param bool $include_dir 非递归模式下,是否包含目录
* @return array|false
* @since 2.5 * @since 2.5
*/ */
public static function scanDirFiles(string $dir, bool $recursive = true, $relative = false, bool $include_dir = false) public static function scanDirFiles(string $dir, bool $recursive = true, bool|string $relative = false, bool $include_dir = false): array|false
{ {
$dir = zm_dir($dir); $dir = zm_dir($dir);
// 不是目录不扫,直接 false 处理 // 不是目录不扫,直接 false 处理
@@ -114,26 +113,26 @@ class FileSystem
* @param bool|string $return_path_value 是否返回文件路径,返回文件路径的话传入字符串 * @param bool|string $return_path_value 是否返回文件路径,返回文件路径的话传入字符串
* @return string[] * @return string[]
*/ */
public static function getClassesPsr4(string $dir, string $base_namespace, $rule = null, $return_path_value = false): array public static function getClassesPsr4(string $dir, string $base_namespace, mixed $rule = null, bool|string $return_path_value = false): array
{ {
// 预先读取下composer的file列表 // 预先读取下composer的file列表
$composer = ZMUtil::getComposerMetadata(); $composer = ZMUtil::getComposerMetadata();
$classes = []; $classes = [];
// 扫描目录使用递归模式相对路径模式因为下面此路径要用作转换成namespace // 扫描目录使用递归模式相对路径模式因为下面此路径要用作转换成namespace
$files = FileSystem::scanDirFiles($dir, true, true); $files = self::scanDirFiles($dir, true, true);
foreach ($files as $v) { foreach ($files as $v) {
$pathinfo = pathinfo($v); $pathinfo = pathinfo($v);
if (($pathinfo['extension'] ?? '') == 'php') { if (($pathinfo['extension'] ?? '') == 'php') {
$path = rtrim($dir, '/') . '/' . rtrim($pathinfo['dirname'], './') . '/' . $pathinfo['basename']; $path = rtrim($dir, '/') . '/' . rtrim($pathinfo['dirname'], './') . '/' . $pathinfo['basename'];
// 过滤不包含类的文件 // 过滤不包含类的文件
$tokens = token_get_all(file_get_contents($path)); $tokens = \PhpToken::tokenize(file_get_contents($path));
$found = false; $found = false;
foreach ($tokens as $token) { foreach ($tokens as $token) {
if (!is_array($token)) { if (!$token instanceof \PhpToken) {
continue; continue;
} }
if ($token[0] === T_CLASS) { if ($token->is(T_CLASS)) {
$found = true; $found = true;
break; break;
} }

View File

@@ -8,9 +8,9 @@ use ZM\Exception\ZMKnownException;
class FileLock class FileLock
{ {
private static $lock_file_handle = []; private static array $lock_file_handle = [];
private static $name_hash = []; private static array $name_hash = [];
/** /**
* 基于文件的锁,适用于跨进程操作资源用的 * 基于文件的锁,适用于跨进程操作资源用的
@@ -19,7 +19,7 @@ class FileLock
*/ */
public static function lock(string $name) public static function lock(string $name)
{ {
self::$name_hash[$name] = self::$name_hash[$name] ?? md5($name); self::$name_hash[$name] ??= md5($name);
$lock_file = zm_dir(TMP_DIR . '/.zm_' . zm_instance_id() . self::$name_hash[$name] . '.lock'); $lock_file = zm_dir(TMP_DIR . '/.zm_' . zm_instance_id() . self::$name_hash[$name] . '.lock');
self::$lock_file_handle[$name] = fopen($lock_file, 'w'); self::$lock_file_handle[$name] = fopen($lock_file, 'w');
if (self::$lock_file_handle[$name] === false) { if (self::$lock_file_handle[$name] === false) {

View File

@@ -37,7 +37,7 @@ class ConnectionUtil
// 这里下面为连接准入,允许接入反向 WS // 这里下面为连接准入,允许接入反向 WS
if (ProcessStateManager::$process_mode['worker'] > 1) { if (ProcessStateManager::$process_mode['worker'] > 1) {
// 文件名格式为 .WS{fd}.{pid},文件内容是 impl 名称的 JSON 格式 // 文件名格式为 .WS{fd}.{pid},文件内容是 impl 名称的 JSON 格式
file_put_contents(zm_dir(ZM_STATE_DIR . '/.WS' . $fd . '.' . ProcessManager::getProcessId()), json_encode($handle)); file_put_contents(zm_dir(ZM_STATE_DIR . '/.WS' . $fd . '.' . ProcessManager::getProcessId()), json_encode($handle, JSON_THROW_ON_ERROR));
} }
return true; return true;
} }
@@ -53,7 +53,7 @@ class ConnectionUtil
// 这里下面为连接准入,允许接入反向 WS // 这里下面为连接准入,允许接入反向 WS
if (ProcessStateManager::$process_mode['worker'] > 1) { if (ProcessStateManager::$process_mode['worker'] > 1) {
// 文件名格式为 .WS{fd}.{pid},文件内容是 impl 名称的 JSON 格式 // 文件名格式为 .WS{fd}.{pid},文件内容是 impl 名称的 JSON 格式
file_put_contents(zm_dir(ZM_STATE_DIR . '/.WS' . $fd . '.' . ProcessManager::getProcessId()), json_encode(self::$connection_handles[$fd])); file_put_contents(zm_dir(ZM_STATE_DIR . '/.WS' . $fd . '.' . ProcessManager::getProcessId()), json_encode(self::$connection_handles[$fd], JSON_THROW_ON_ERROR));
} }
} }

View File

@@ -21,10 +21,7 @@ use ZM\Store\FileSystem;
*/ */
class HttpUtil class HttpUtil
{ {
/** private static ?RouteCollection $routes = null;
* @var RouteCollection
*/
private static $routes;
/** /**
* 解析 Uri用于匹配路由用的 * 解析 Uri用于匹配路由用的
@@ -42,10 +39,10 @@ class HttpUtil
// 使用UrlMatcher进行匹配Url // 使用UrlMatcher进行匹配Url
$matcher = new UrlMatcher(static::getRouteCollection(), $context); $matcher = new UrlMatcher(static::getRouteCollection(), $context);
$matched = $matcher->match($request->getUri()->getPath()); $matched = $matcher->match($request->getUri()->getPath());
} catch (ResourceNotFoundException $e) { } catch (ResourceNotFoundException) {
// 路由找不到会抛出异常,我们不需要这个异常,转换为状态码 // 路由找不到会抛出异常,我们不需要这个异常,转换为状态码
return ZM_ERR_ROUTE_NOT_FOUND; return ZM_ERR_ROUTE_NOT_FOUND;
} catch (MethodNotAllowedException $e) { } catch (MethodNotAllowedException) {
// 路由匹配到了,但该路由不能使用该方法,所以返回状态码(路由不允许) // 路由匹配到了,但该路由不能使用该方法,所以返回状态码(路由不允许)
return ZM_ERR_ROUTE_METHOD_NOT_ALLOWED; return ZM_ERR_ROUTE_METHOD_NOT_ALLOWED;
} }

View File

@@ -43,16 +43,14 @@ class ReflectionUtil
/** /**
* 将传入变量转换为字符串 * 将传入变量转换为字符串
*
* @param mixed $var
*/ */
public static function variableToString($var): string public static function variableToString(mixed $var): string
{ {
switch (true) { switch (true) {
case is_callable($var): case is_callable($var):
if (is_array($var)) { if (is_array($var)) {
if (is_object($var[0])) { if (is_object($var[0])) {
return get_class($var[0]) . '@' . $var[1]; return $var[0]::class . '@' . $var[1];
} }
return $var[0] . '::' . $var[1]; return $var[0] . '::' . $var[1];
} }
@@ -60,9 +58,9 @@ class ReflectionUtil
case is_string($var): case is_string($var):
return $var; return $var;
case is_array($var): case is_array($var):
return 'array' . json_encode($var); return 'array' . json_encode($var, JSON_THROW_ON_ERROR);
case is_object($var): case is_object($var):
return get_class($var); return $var::class;
case is_resource($var): case is_resource($var):
return 'resource(' . get_resource_type($var) . ')'; return 'resource(' . get_resource_type($var) . ')';
case is_null($var): case is_null($var):
@@ -83,7 +81,7 @@ class ReflectionUtil
* @param callable|string $callback 回调 * @param callable|string $callback 回调
* @throws \ReflectionException * @throws \ReflectionException
*/ */
public static function isNonStaticMethod($callback): bool public static function isNonStaticMethod(callable|array|string $callback): bool
{ {
if (is_array($callback) && is_string($callback[0])) { if (is_array($callback) && is_string($callback[0])) {
$reflection = new \ReflectionMethod($callback[0], $callback[1]); $reflection = new \ReflectionMethod($callback[0], $callback[1]);
@@ -103,7 +101,7 @@ class ReflectionUtil
* @param callable|string $callback 回调 * @param callable|string $callback 回调
* @throws \ReflectionException * @throws \ReflectionException
*/ */
public static function getCallReflector($callback): \ReflectionFunctionAbstract public static function getCallReflector(callable|string $callback): \ReflectionFunctionAbstract
{ {
if (is_string($callback) && str_contains($callback, '::')) { if (is_string($callback) && str_contains($callback, '::')) {
$callback = explode('::', $callback); $callback = explode('::', $callback);

View File

@@ -12,6 +12,6 @@ class ZMUtil
*/ */
public static function getComposerMetadata(?string $path = null): ?array public static function getComposerMetadata(?string $path = null): ?array
{ {
return json_decode(file_get_contents(($path ?? SOURCE_ROOT_DIR) . '/composer.json'), true); return json_decode(file_get_contents(($path ?? SOURCE_ROOT_DIR) . '/composer.json'), true, 512, JSON_THROW_ON_ERROR);
} }
} }

View File

@@ -94,9 +94,8 @@ class ZMConfigTest extends TestCase
/** /**
* @dataProvider providerTestGetValue * @dataProvider providerTestGetValue
* @param mixed $expected
*/ */
public function testGetValue(string $key, $expected): void public function testGetValue(string $key, mixed $expected): void
{ {
$this->assertSame($expected, self::$config->get($key)); $this->assertSame($expected, self::$config->get($key));
} }

View File

@@ -29,9 +29,7 @@ class PipelineTest extends TestCase
$pipe = new Pipeline(); $pipe = new Pipeline();
$a = $pipe->send('APP') $a = $pipe->send('APP')
->through([TimerMiddleware::class]) ->through([TimerMiddleware::class])
->then(function (string $value) { ->then(fn (string $value) => $value);
return $value;
});
$this->assertEquals('APP', $a); $this->assertEquals('APP', $a);
} }
} }

View File

@@ -34,9 +34,8 @@ class ReflectionUtilTest extends TestCase
/** /**
* @dataProvider provideTestVariableToString * @dataProvider provideTestVariableToString
* @param mixed $variable
*/ */
public function testVariableToString($variable, string $expected): void public function testVariableToString(mixed $variable, string $expected): void
{ {
$this->assertSame($expected, ReflectionUtil::variableToString($variable)); $this->assertSame($expected, ReflectionUtil::variableToString($variable));
} }
@@ -61,9 +60,8 @@ class ReflectionUtilTest extends TestCase
/** /**
* @dataProvider provideTestGetCallReflector * @dataProvider provideTestGetCallReflector
* @param mixed $callback
*/ */
public function testGetCallReflector($callback, \ReflectionFunctionAbstract $expected): void public function testGetCallReflector(mixed $callback, \ReflectionFunctionAbstract $expected): void
{ {
$this->assertEquals($expected, ReflectionUtil::getCallReflector($callback)); $this->assertEquals($expected, ReflectionUtil::getCallReflector($callback));
} }

View File

@@ -184,9 +184,7 @@ class ZMResultPrinter extends CliTestDoxPrinter
if ($this->colors) { if ($this->colors) {
$color = self::STATUS_STYLES[$result['status']]['color'] ?? ''; $color = self::STATUS_STYLES[$result['status']]['color'] ?? '';
$prefix = array_map(static function ($p) use ($color) { $prefix = array_map(static fn ($p) => Color::colorize($color, $p), self::PREFIX_DECORATED);
return Color::colorize($color, $p);
}, self::PREFIX_DECORATED);
} }
$out = ''; $out = '';