diff --git a/.gitignore b/.gitignore index 4012c815..095d42ed 100644 --- a/.gitignore +++ b/.gitignore @@ -13,10 +13,16 @@ composer.lock /runtime/ /tmp/ /temp/ + +# go-cqhttp快速安装启动相关(可能被废弃) /ext/go-cqhttp/data/ /ext/go-cqhttp/logs/ /ext/go-cqhttp/config.hjson /ext/go-cqhttp/device.json /ext/go-cqhttp/go-cqhttp /ext/go-cqhttp/session.token -.zm_worker_*.pid \ No newline at end of file + +.zm_worker_*.pid + +# Git Hook 的相关锁文件 +cghooks.lock \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 00000000..95bf29a5 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,76 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR12' => true, + '@Symfony' => true, + '@PhpCsFixer' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'list_syntax' => [ + 'syntax' => 'short', + ], + 'concat_space' => [ + 'spacing' => 'one', + ], + 'blank_line_before_statement' => [ + 'statements' => [ + 'declare', + ], + ], + 'ordered_imports' => [ + 'imports_order' => [ + 'class', + 'function', + 'const', + ], + 'sort_algorithm' => 'alpha', + ], + 'single_line_comment_style' => [ + 'comment_types' => [ + ], + ], + 'yoda_style' => [ + 'always_move_variable' => false, + 'equal' => false, + 'identical' => false, + ], + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', + ], + 'constant_case' => [ + 'case' => 'lower', + ], + 'class_attributes_separation' => true, + 'combine_consecutive_unsets' => true, + 'declare_strict_types' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_static_reference' => true, + 'no_useless_else' => true, + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => false, + 'not_operator_with_space' => false, + 'ordered_class_elements' => true, + 'php_unit_strict' => false, + 'phpdoc_separation' => false, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'multiline_comment_opening_closing' => true, + 'phpdoc_summary' => false, + 'class_reference_name_casing' => false, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('vendor') + ->exclude('docs') + ->in(__DIR__ . '/src') + ) + ->setUsingCache(false); diff --git a/composer.json b/composer.json index bb08b3b2..8dfac7a1 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,18 @@ "extra": { "exclude_annotate": [ "src/ZM" - ] + ], + "hooks": { + "post-merge": "composer install", + "pre-commit": [ + "echo committing as $(git config user.name)", + "./vendor/bin/php-cs-fixer fix --dry-run --diff ./src" + ], + "pre-push": [ + "./vendor/bin/php-cs-fixer fix --dry-run --diff ./src", + "composer analyse" + ] + } }, "authors": [ { @@ -21,7 +32,7 @@ "bin/watcher" ], "require": { - "php": ">=7.2", + "php": "^7.2 || ^7.3 || ^7.4 || ^8.0 || ^8.1", "ext-json": "*", "ext-posix": "*", "doctrine/annotations": "~1.12 || ~1.4.0", @@ -59,8 +70,22 @@ "Custom\\": "src/Custom" } }, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, "require-dev": { "swoole/ide-helper": "@dev", - "phpunit/phpunit": "^8.5 || ^9.0" + "phpunit/phpunit": "^8.5 || ^9.0", + "brainmaestro/composer-git-hooks": "^2.8", + "friendsofphp/php-cs-fixer": "^3.2 != 3.7.0", + "phpstan/phpstan": "^1.1" + }, + "scripts": { + "post-install-cmd": [ + "[ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/cghooks add" + ], + "analyse": "phpstan analyse --memory-limit 300M -l 0 ./src", + "cs-fix": "php-cs-fixer fix $1" } } \ No newline at end of file diff --git a/config/global.php b/config/global.php index 17eea1c6..78d2b3d7 100644 --- a/config/global.php +++ b/config/global.php @@ -1,41 +1,42 @@ set参数 */ +/* 对应swoole的server->set参数 */ $config['swoole'] = [ 'log_file' => $config['crash_dir'] . 'swoole_error.log', //'worker_num' => swoole_cpu_num(), //如果你只有一个 OneBot 实例连接到框架并且代码没有复杂的CPU密集计算,则可把这里改为1使用全局变量 'dispatch_mode' => 2, //包分配原则,见 https://wiki.swoole.com/#/server/setting?id=dispatch_mode 'max_coroutine' => 300000, - 'max_wait_time' => 5 + 'max_wait_time' => 5, //'task_worker_num' => 4, //'task_enable_coroutine' => true ]; - -/** 一些框架与框架运行时设置的调整 */ +/* 一些框架与框架运行时设置的调整 */ $config['runtime'] = [ 'swoole_coroutine_hook_flags' => SWOOLE_HOOK_ALL & (~SWOOLE_HOOK_CURL), 'swoole_server_mode' => SWOOLE_PROCESS, @@ -45,22 +46,22 @@ $config['runtime'] = [ 'save_console_log_file' => false, // 改为目标路径,则将 Console 输出的日志保存到文件 ]; -/** 轻量字符串缓存,默认开启 */ +/* 轻量字符串缓存,默认开启 */ $config['light_cache'] = [ 'size' => 512, //最多允许储存的条数(需要2的倍数) 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) 'persistence_path' => $config['zm_data'] . '_cache.json', - 'auto_save_interval' => 900 + 'auto_save_interval' => 900, ]; -/** 大容量跨进程变量存储(2.2.0可用) */ +/* 大容量跨进程变量存储(2.2.0可用) */ $config['worker_cache'] = [ 'worker' => 0, - 'transaction_timeout' => 30000 + 'transaction_timeout' => 30000, ]; -/** MySQL数据库连接信息,host留空则启动时不创建sql连接池 */ +/* MySQL数据库连接信息,host留空则启动时不创建sql连接池 */ $config['mysql_config'] = [ 'host' => '', 'port' => 3306, @@ -72,54 +73,54 @@ $config['mysql_config'] = [ 'pool_size' => 64, 'options' => [ PDO::ATTR_STRINGIFY_FETCHES => false, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC - ] + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ], ]; -/** Redis连接信息,host留空则启动时不创建Redis连接池 */ +/* Redis连接信息,host留空则启动时不创建Redis连接池 */ $config['redis_config'] = [ 'host' => '', 'port' => 6379, 'timeout' => 1, 'db_index' => 0, - 'auth' => '' + 'auth' => '', ]; -/** onebot连接约定的token */ +/* onebot连接约定的token */ $config['access_token'] = ''; -/** HTTP服务器固定请求头的返回 */ +/* HTTP服务器固定请求头的返回 */ $config['http_header'] = [ 'Server' => 'zhamao-framework', - 'Content-Type' => 'text/html; charset=utf-8' + 'Content-Type' => 'text/html; charset=utf-8', ]; -/** HTTP服务器在指定状态码下回复的页面(默认) */ +/* HTTP服务器在指定状态码下回复的页面(默认) */ $config['http_default_code_page'] = [ - '404' => '404.html' + '404' => '404.html', ]; -/** zhamao-framework在框架启动时初始化的atomic们 */ +/* zhamao-framework在框架启动时初始化的atomic们 */ $config['init_atomics'] = [ //'custom_atomic_name' => 0, //自定义添加的Atomic ]; -/** 终端日志显示等级(0-4) */ +/* 终端日志显示等级(0-4) */ $config['info_level'] = 2; -/** 上下文接口类 implemented from ContextInterface */ +/* 上下文接口类 implemented from ContextInterface */ $config['context_class'] = \ZM\Context\Context::class; -/** 静态文件访问 */ +/* 静态文件访问 */ $config['static_file_server'] = [ 'status' => false, 'document_root' => realpath(__DIR__ . '/../') . '/resources/html', 'document_index' => [ - 'index.html' - ] + 'index.html', + ], ]; -/** 机器人解析模块,关闭后无法使用如CQCommand等注解(上面的modules即将废弃) */ +/* 机器人解析模块,关闭后无法使用如CQCommand等注解(上面的modules即将废弃) */ $config['onebot'] = [ 'status' => true, 'single_bot_mode' => false, @@ -128,18 +129,18 @@ $config['onebot'] = [ 'message_command_policy' => 'interrupt', ]; -/** 一个远程简易终端,使用nc直接连接即可,但是不建议开放host为0.0.0.0(远程连接) */ +/* 一个远程简易终端,使用nc直接连接即可,但是不建议开放host为0.0.0.0(远程连接) */ $config['remote_terminal'] = [ 'status' => false, 'host' => '127.0.0.1', 'port' => 20002, - 'token' => '' + 'token' => '', ]; -/** 模块(插件)加载器的相关设置 */ +/* 模块(插件)加载器的相关设置 */ $config['module_loader'] = [ 'enable_hotload' => false, - 'load_path' => $config['zm_data'] . 'modules' + 'load_path' => $config['zm_data'] . 'modules', ]; return $config; diff --git a/instant-test.php b/instant-demo.php similarity index 53% rename from instant-test.php rename to instant-demo.php index fa4d7abc..e869537f 100644 --- a/instant-test.php +++ b/instant-demo.php @@ -1,6 +1,8 @@ onEvent(OnOpenEvent::class, ['connect_type' => 'qq'], function(ConnectionObject $conn) { - Console::info("机器人 " . $conn->getOption("connect_id") . " 已连接!"); +$weather->onEvent(OnOpenEvent::class, ['connect_type' => 'qq'], function (ConnectionObject $conn) { + Console::info('机器人 ' . $conn->getOption('connect_id') . ' 已连接!'); }); -$weather->onEvent(CQCommand::class, ['match' => '你好'], function() { - ctx()->reply("hello呀!"); +$weather->onEvent(CQCommand::class, ['match' => '你好'], function () { + ctx()->reply('hello呀!'); }); -$app = new ZMServer("app-name"); +$app = new ZMServer('app-name'); $app->addModule($weather); -$app->run(); \ No newline at end of file +$app->run(); diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..dcf8101f --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + reportUnmatchedIgnoredErrors: false + level: 0 + paths: + - ./src/ + ignoreErrors: + - '#Used constant OS_TYPE_(LINUX|WINDOWS) not found#' diff --git a/src/Custom/Annotation/Example.php b/src/Custom/Annotation/Example.php index 4c255730..c95908ba 100644 --- a/src/Custom/Annotation/Example.php +++ b/src/Custom/Annotation/Example.php @@ -1,5 +1,6 @@ reply("重启中..."); + public function reload() + { + ctx()->reply('重启中...'); ZMUtil::reload(); } /** * @CQCommand("我是谁") */ - public function whoami() { + public function whoami() + { $bot = ctx()->getRobot()->getLoginInfo(); - $bot_id = $bot["data"]["user_id"]; - $r = OneBotV11::get($bot_id); + $bot_id = $bot['data']['user_id']; + $r = OneBotV11::get($bot_id); $QQid = ctx()->getUserId(); - $nick = $r->getStrangerInfo($QQid)["data"]["nickname"]; - return "你是" . $nick . ",QQ号是" . $QQid; + $nick = $r->getStrangerInfo($QQid)['data']['nickname']; + return '你是' . $nick . ',QQ号是' . $QQid; } /** * 向机器人发送"你好啊",也可回复这句话 * @CQCommand(match="你好",alias={"你好啊","你是谁"}) */ - public function hello() { - return "你好啊,我是由炸毛框架构建的机器人!"; + public function hello() + { + return '你好啊,我是由炸毛框架构建的机器人!'; } /** * 一个最基本的第三方 API 接口使用示例 * @CQCommand("一言") */ - public function hitokoto() { - $api_result = ZMRequest::get("https://v1.hitokoto.cn/"); - if ($api_result === false) return "接口请求出错,请稍后再试!"; + public function hitokoto() + { + $api_result = ZMRequest::get('https://v1.hitokoto.cn/'); + if ($api_result === false) { + return '接口请求出错,请稍后再试!'; + } $obj = json_decode($api_result, true); - if ($obj === null) return "接口解析出错!可能返回了非法数据!"; - return $obj["hitokoto"] . "\n----「" . $obj["from"] . "」"; + if ($obj === null) { + return '接口解析出错!可能返回了非法数据!'; + } + return $obj['hitokoto'] . "\n----「" . $obj['from'] . '」'; } /** @@ -83,33 +92,36 @@ class Hello * @CQCommand(start_with="机器人",end_with="机器人",message_type="group") * @CQMessage(message_type="private",level=1) */ - public function turingAPI() { + public function turingAPI() + { $user_id = ctx()->getUserId(); - $api = ""; // 请在这里填入你的图灵机器人的apikey - if ($api === "") return false; //如果没有填入apikey则此功能关闭 + $api = ''; // 请在这里填入你的图灵机器人的apikey + if ($api === '') { + return false; + } //如果没有填入apikey则此功能关闭 if (($this->_running_annotation ?? null) instanceof CQCommand) { - $msg = ctx()->getFullArg("我在!有什么事吗?"); + $msg = ctx()->getFullArg('我在!有什么事吗?'); } else { $msg = ctx()->getMessage(); } ctx()->setMessage($msg); if (MessageUtil::matchCommand($msg, ctx()->getData())->status === false) { return TuringAPI::getTuringMsg($msg, $user_id, $api); - } else { - QQBot::getInstance()->handle(ctx()->getData(), ctx()->getCache("level") + 1); - //执行嵌套消息,递归层级+1 - return true; } + QQBot::getInstance()->handle(ctx()->getData(), ctx()->getCache('level') + 1); + //执行嵌套消息,递归层级+1 + return true; } /** * 响应at机器人的消息 * @CQBefore("message") */ - public function changeAt() { + public function changeAt() + { if (MessageUtil::isAtMe(ctx()->getMessage(), ctx()->getRobotId())) { - $msg = str_replace(CQ::at(ctx()->getRobotId()), "", ctx()->getMessage()); - ctx()->setMessage("机器人" . $msg); + $msg = str_replace(CQ::at(ctx()->getRobotId()), '', ctx()->getMessage()); + ctx()->setMessage('机器人' . $msg); Console::info(ctx()->getMessage()); } return true; @@ -123,15 +135,16 @@ class Hello * @CQCommand(pattern="*从*到*的随机数") * @return string */ - public function randNum() { + public function randNum() + { // 获取第一个数字类型的参数 - $num1 = ctx()->getNumArg("请输入第一个数字"); + $num1 = ctx()->getNumArg('请输入第一个数字'); // 获取第二个数字类型的参数 - $num2 = ctx()->getNumArg("请输入第二个数字"); + $num2 = ctx()->getNumArg('请输入第二个数字'); $a = min(intval($num1), intval($num2)); $b = max(intval($num1), intval($num2)); // 回复用户结果 - return "随机数是:" . mt_rand($a, $b); + return '随机数是:' . mt_rand($a, $b); } /** @@ -139,8 +152,9 @@ class Hello * @RequestMapping("/httpTimer") * @Middleware("timer") */ - public function timer() { - return "This page is used as testing TimerMiddleware! Do not use it in production."; + public function timer() + { + return 'This page is used as testing TimerMiddleware! Do not use it in production.'; } /** @@ -148,8 +162,9 @@ class Hello * @RequestMapping("/index") * @RequestMapping("/") */ - public function index() { - return "Hello Zhamao!"; + public function index() + { + return 'Hello Zhamao!'; } /** @@ -158,8 +173,9 @@ class Hello * @param $param * @return string */ - public function paramGet($param) { - return "Hello, " . $param["name"]; + public function paramGet($param) + { + return 'Hello, ' . $param['name']; } /** @@ -167,17 +183,18 @@ class Hello * @OnOpenEvent("qq") * @param $conn */ - public function onConnect(ConnectionObject $conn) { - Console::info("机器人 " . $conn->getOption("connect_id") . " 已连接!"); + public function onConnect(ConnectionObject $conn) + { + Console::info('机器人 ' . $conn->getOption('connect_id') . ' 已连接!'); } /** * 在机器人断开连接后向终端输出信息 * @OnCloseEvent("qq") - * @param ConnectionObject $conn */ - public function onDisconnect(ConnectionObject $conn) { - Console::info("机器人 " . $conn->getOption("connect_id") . " 已断开连接!"); + public function onDisconnect(ConnectionObject $conn) + { + Console::info('机器人 ' . $conn->getOption('connect_id') . ' 已断开连接!'); } /** @@ -185,7 +202,8 @@ class Hello * @OnRequestEvent(rule="ctx()->getRequest()->server['request_uri'] == '/favicon.ico'",level=200) * @throws InterruptException */ - public function onRequest() { + public function onRequest() + { EventDispatcher::interrupt(); } @@ -193,8 +211,9 @@ class Hello * 框架会默认关闭未知的WebSocket链接,因为这个绑定的事件,你可以根据你自己的需求进行修改 * @OnOpenEvent("default") */ - public function closeUnknownConn() { - Console::info("Unknown connection , I will close it."); + public function closeUnknownConn() + { + Console::info('Unknown connection , I will close it.'); server()->disconnect(ctx()->getConnection()->getFd()); } } diff --git a/src/Module/Middleware/TimerMiddleware.php b/src/Module/Middleware/TimerMiddleware.php index a1a2b504..3e386798 100644 --- a/src/Module/Middleware/TimerMiddleware.php +++ b/src/Module/Middleware/TimerMiddleware.php @@ -1,5 +1,7 @@ starttime = microtime(true); return true; } @@ -32,17 +33,18 @@ class TimerMiddleware implements MiddlewareInterface /** * @HandleAfter() */ - public function onAfter() { - Console::info("Using " . round((microtime(true) - $this->starttime) * 1000, 3) . " ms."); + public function onAfter() + { + Console::info('Using ' . round((microtime(true) - $this->starttime) * 1000, 3) . ' ms.'); } /** * @HandleException(\Exception::class) - * @param Exception $e * @throws Exception */ - public function onException(Exception $e) { - Console::error("Using " . round((microtime(true) - $this->starttime) * 1000, 3) . " ms but an Exception occurred."); + public function onException(Exception $e) + { + Console::error('Using ' . round((microtime(true) - $this->starttime) * 1000, 3) . ' ms but an Exception occurred.'); throw $e; } } diff --git a/src/ZM/API/CQ.php b/src/ZM/API/CQ.php index db8c7762..89b64166 100644 --- a/src/ZM/API/CQ.php +++ b/src/ZM/API/CQ.php @@ -1,11 +1,9 @@ - $v) { - $code .= "," . $k . "=" . self::escape($v, true); + $code .= ',' . $k . '=' . self::escape($v, true); } - $code .= "]"; + $code .= ']'; return $code; } /** * 反转义字符串中的CQ码敏感符号 - * @param $msg - * @param bool $is_content - * @return mixed + * @param mixed $msg + * @param mixed $is_content */ - public static function decode($msg, $is_content = false) { - $msg = str_replace(["&", "[", "]"], ["&", "[", "]"], $msg); - if ($is_content) $msg = str_replace(",", ",", $msg); + public static function decode($msg, $is_content = false) + { + $msg = str_replace(['&', '[', ']'], ['&', '[', ']'], $msg); + if ($is_content) { + $msg = str_replace(',', ',', $msg); + } return $msg; } - public static function replace($str) { - $str = str_replace("{{", "[", $str); - $str = str_replace("}}", "]", $str); - return $str; + public static function replace($str) + { + $str = str_replace('{{', '[', $str); + return str_replace('}}', ']', $str); } /** * 转义CQ码的特殊字符,同encode - * @param $msg - * @param bool $is_content - * @return mixed + * @param mixed $msg + * @param mixed $is_content */ - public static function escape($msg, $is_content = false) { - $msg = str_replace(["&", "[", "]"], ["&", "[", "]"], $msg); - if ($is_content) $msg = str_replace(",", ",", $msg); + public static function escape($msg, $is_content = false) + { + $msg = str_replace(['&', '[', ']'], ['&', '[', ']'], $msg); + if ($is_content) { + $msg = str_replace(',', ',', $msg); + } return $msg; } /** * 转义CQ码的特殊字符 - * @param $msg - * @param false $is_content - * @return mixed + * @param mixed $msg + * @param mixed $is_content */ - public static function encode($msg, $is_content = false) { - $msg = str_replace(["&", "[", "]"], ["&", "[", "]"], $msg); - if ($is_content) $msg = str_replace(",", ",", $msg); + public static function encode($msg, $is_content = false) + { + $msg = str_replace(['&', '[', ']'], ['&', '[', ']'], $msg); + if ($is_content) { + $msg = str_replace(',', ',', $msg); + } return $msg; } @@ -294,12 +314,13 @@ class CQ * @param $msg * @return string */ - public static function removeCQ($msg) { - $final = ""; + public static function removeCQ($msg) + { + $final = ''; $last_end = 0; foreach (self::getAllCQ($msg) as $v) { - $final .= mb_substr($msg, $last_end, $v["start"] - $last_end); - $last_end = $v["end"] + 1; + $final .= mb_substr($msg, $last_end, $v['start'] - $last_end); + $last_end = $v['end'] + 1; } $final .= mb_substr($msg, $last_end); return $final; @@ -307,55 +328,58 @@ class CQ /** * 获取消息中第一个CQ码 - * @param $msg - * @param bool $is_object - * @return array|CQObject|null + * @param mixed $msg + * @param mixed $is_object */ - public static function getCQ($msg, $is_object = false) { - if (($head = mb_strpos($msg, "[CQ:")) !== false) { + public static function getCQ($msg, $is_object = false) + { + if (($head = mb_strpos($msg, '[CQ:')) !== false) { $key_offset = mb_substr($msg, $head); - $close = mb_strpos($key_offset, "]"); - if ($close === false) return null; - $content = mb_substr($msg, $head + 4, $close + $head - mb_strlen($msg)); - $exp = explode(",", $content); - $cq["type"] = array_shift($exp); - foreach ($exp as $v) { - $ss = explode("=", $v); - $sk = array_shift($ss); - $cq["params"][$sk] = self::decode(implode("=", $ss), true); + $close = mb_strpos($key_offset, ']'); + if ($close === false) { + return null; } - $cq["start"] = $head; - $cq["end"] = $close + $head; + $content = mb_substr($msg, $head + 4, $close + $head - mb_strlen($msg)); + $exp = explode(',', $content); + $cq['type'] = array_shift($exp); + foreach ($exp as $v) { + $ss = explode('=', $v); + $sk = array_shift($ss); + $cq['params'][$sk] = self::decode(implode('=', $ss), true); + } + $cq['start'] = $head; + $cq['end'] = $close + $head; return !$is_object ? $cq : CQObject::fromArray($cq); - } else { - return null; } + return null; } /** * 获取消息中所有的CQ码 - * @param $msg - * @param bool $is_object - * @return array|CQObject[] + * @param mixed $msg + * @param mixed $is_object */ - public static function getAllCQ($msg, $is_object = false) { + public static function getAllCQ($msg, $is_object = false) + { $cqs = []; $offset = 0; - while (($head = mb_strpos(($submsg = mb_substr($msg, $offset)), "[CQ:")) !== false) { + while (($head = mb_strpos(($submsg = mb_substr($msg, $offset)), '[CQ:')) !== false) { $key_offset = mb_substr($submsg, $head); - $tmpmsg = mb_strpos($key_offset, "]"); - if ($tmpmsg === false) break; // 没闭合,不算CQ码 + $tmpmsg = mb_strpos($key_offset, ']'); + if ($tmpmsg === false) { + break; + } // 没闭合,不算CQ码 $content = mb_substr($submsg, $head + 4, $tmpmsg + $head - mb_strlen($submsg)); - $exp = explode(",", $content); + $exp = explode(',', $content); $cq = []; - $cq["type"] = array_shift($exp); + $cq['type'] = array_shift($exp); foreach ($exp as $v) { - $ss = explode("=", $v); + $ss = explode('=', $v); $sk = array_shift($ss); - $cq["params"][$sk] = self::decode(implode("=", $ss), true); + $cq['params'][$sk] = self::decode(implode('=', $ss), true); } - $cq["start"] = $offset + $head; - $cq["end"] = $offset + $tmpmsg + $head; + $cq['start'] = $offset + $head; + $cq['end'] = $offset + $tmpmsg + $head; $offset += $head + $tmpmsg + 1; $cqs[] = (!$is_object ? $cq : CQObject::fromArray($cq)); } diff --git a/src/ZM/API/CQAPI.php b/src/ZM/API/CQAPI.php index 76c9ae65..045ceb0e 100644 --- a/src/ZM/API/CQAPI.php +++ b/src/ZM/API/CQAPI.php @@ -1,5 +1,6 @@ getOption("type") === CONN_WEBSOCKET) + if ($connection->getOption('type') === CONN_WEBSOCKET) { return $this->processWebsocketAPI($connection, $reply, $function); - else - return $this->processHttpAPI($connection, $reply, $function); + } + + return $this->processHttpAPI($connection, $reply, $function); } - private function processWebsocketAPI($connection, $reply, $function = false) { - $api_id = ZMAtomic::get("wait_msg_id")->add(1); - $reply["echo"] = $api_id; + private function processWebsocketAPI($connection, $reply, $function = false) + { + $api_id = ZMAtomic::get('wait_msg_id')->add(1); + $reply['echo'] = $api_id; if (server()->push($connection->getFd(), json_encode($reply))) { if ($function === true) { $obj = [ - "data" => $reply, - "time" => microtime(true), - "self_id" => $connection->getOption("connect_id"), - "echo" => $api_id + 'data' => $reply, + 'time' => microtime(true), + 'self_id' => $connection->getOption('connect_id'), + 'echo' => $api_id, ]; - return CoMessage::yieldByWS($obj, ["echo"], 30); + return CoMessage::yieldByWS($obj, ['echo'], 30); } return true; - } else { - Console::warning(zm_internal_errcode("E00036") . "CQAPI send failed, websocket push error."); - $response = [ - "status" => "failed", - "retcode" => -1000, - "data" => null, - "self_id" => $connection->getOption("connect_id") - ]; - SpinLock::lock("wait_api"); - $r = LightCacheInside::get("wait_api", "wait_api"); - unset($r[$reply["echo"]]); - LightCacheInside::set("wait_api", "wait_api", $r); - SpinLock::unlock("wait_api"); - if ($function === true) return $response; - return false; } + Console::warning(zm_internal_errcode('E00036') . 'CQAPI send failed, websocket push error.'); + $response = [ + 'status' => 'failed', + 'retcode' => -1000, + 'data' => null, + 'self_id' => $connection->getOption('connect_id'), + ]; + SpinLock::lock('wait_api'); + $r = LightCacheInside::get('wait_api', 'wait_api'); + unset($r[$reply['echo']]); + LightCacheInside::set('wait_api', 'wait_api', $r); + SpinLock::unlock('wait_api'); + if ($function === true) { + return $response; + } + return false; } /** * @param $connection * @param $reply * @param null $function - * @return bool * @noinspection PhpUnusedParameterInspection */ - private function processHttpAPI($connection, $reply, $function = null): bool { - return false; - } - - public function getActionName($suffix, string $method) { - $postfix = ($suffix == OneBotV11::API_ASYNC ? '_async' : ($suffix == OneBotV11::API_RATE_LIMITED ? '_rate_limited' : '')); - $func_name = strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $method)); - return $func_name . $postfix; - } - - public function __call($name, $arguments) { + private function processHttpAPI($connection, $reply, $function = null): bool + { return false; } } diff --git a/src/ZM/API/GoCqhttpAPIV11.php b/src/ZM/API/GoCqhttpAPIV11.php index c1d9376e..e6e0c87f 100644 --- a/src/ZM/API/GoCqhttpAPIV11.php +++ b/src/ZM/API/GoCqhttpAPIV11.php @@ -1,15 +1,19 @@ processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 获取频道列表 - * @link https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E5%88%97%E8%A1%A8 + * @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E5%88%97%E8%A1%A8 * @return array|bool */ - public function getGuildList() { + public function getGuildList() + { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 通过访客获取频道元数据 - * @link https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E9%80%9A%E8%BF%87%E8%AE%BF%E5%AE%A2%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E5%85%83%E6%95%B0%E6%8D%AE + * @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E9%80%9A%E8%BF%87%E8%AE%BF%E5%AE%A2%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E5%85%83%E6%95%B0%E6%8D%AE * @param $guild_id * @return array|bool */ - public function getGuildMetaByGuest($guild_id) { + public function getGuildMetaByGuest($guild_id) + { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'guild_id' => $guild_id - ] + 'guild_id' => $guild_id, + ], ], $this->callback); } /** * 获取子频道列表 - * @link https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E5%AD%90%E9%A2%91%E9%81%93%E5%88%97%E8%A1%A8 + * @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E5%AD%90%E9%A2%91%E9%81%93%E5%88%97%E8%A1%A8 * @param $guild_id - * @param false $no_cache + * @param false $no_cache * @return array|bool */ - public function getGuildChannelList($guild_id, bool $no_cache = false) { + public function getGuildChannelList($guild_id, bool $no_cache = false) + { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'guild_id' => $guild_id, - 'no_cache' => $no_cache - ] + 'no_cache' => $no_cache, + ], ], $this->callback); } /** * 获取频道成员列表 - * @link https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E6%88%90%E5%91%98%E5%88%97%E8%A1%A8 + * @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E8%8E%B7%E5%8F%96%E9%A2%91%E9%81%93%E6%88%90%E5%91%98%E5%88%97%E8%A1%A8 * @param $guild_id * @return array|bool */ - public function getGuildMembers($guild_id) { + public function getGuildMembers($guild_id) + { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'guild_id' => $guild_id - ] + 'guild_id' => $guild_id, + ], ], $this->callback); } /** * 发送信息到子频道 - * @link https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E5%8F%91%E9%80%81%E4%BF%A1%E6%81%AF%E5%88%B0%E5%AD%90%E9%A2%91%E9%81%93 + * @see https://github.com/Mrs4s/go-cqhttp/blob/master/docs/guild.md#%E5%8F%91%E9%80%81%E4%BF%A1%E6%81%AF%E5%88%B0%E5%AD%90%E9%A2%91%E9%81%93 * @param $guild_id * @param $channel_id * @param $message * @return array|bool */ - public function sendGuildChannelMsg($guild_id, $channel_id, $message) { + public function sendGuildChannelMsg($guild_id, $channel_id, $message) + { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'guild_id' => $guild_id, 'channel_id' => $channel_id, - 'message' => $message - ] + 'message' => $message, + ], ], $this->callback); } } diff --git a/src/ZM/API/OneBotV11.php b/src/ZM/API/OneBotV11.php index f0b986b5..8ab33f63 100644 --- a/src/ZM/API/OneBotV11.php +++ b/src/ZM/API/OneBotV11.php @@ -1,5 +1,8 @@ -connection = $connection; + } + /** * @param $robot_id - * @return ZMRobot * @throws RobotNotFoundException + * @return ZMRobot */ public static function get($robot_id) { $r = ManagerGM::getAllByName('qq'); foreach ($r as $v) { - if ($v->getOption('connect_id') == $robot_id) return new ZMRobot($v); + if ($v->getOption('connect_id') == $robot_id) { + return new ZMRobot($v); + } } - throw new RobotNotFoundException("机器人 " . $robot_id . " 未连接到框架!"); + throw new RobotNotFoundException('机器人 ' . $robot_id . ' 未连接到框架!'); } /** - * @return ZMRobot * @throws RobotNotFoundException + * @return ZMRobot */ public static function getRandom() { $r = ManagerGM::getAllByName('qq'); - if ($r == []) throw new RobotNotFoundException("没有任何机器人连接到框架!"); + if ($r == []) { + throw new RobotNotFoundException('没有任何机器人连接到框架!'); + } return new ZMRobot($r[array_rand($r)]); } @@ -66,11 +80,6 @@ class OneBotV11 return $obj; } - public function __construct(ConnectionObject $connection) - { - $this->connection = $connection; - } - public function setCallback($callback = true) { $this->callback = $callback; @@ -92,11 +101,10 @@ class OneBotV11 /** * 发送私聊消息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_private_msg-%E5%8F%91%E9%80%81%E7%A7%81%E8%81%8A%E6%B6%88%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_private_msg-%E5%8F%91%E9%80%81%E7%A7%81%E8%81%8A%E6%B6%88%E6%81%AF * @param $user_id * @param $message - * @param bool $auto_escape - * @return array|bool|null + * @return null|array|bool */ public function sendPrivateMsg($user_id, $message, bool $auto_escape = false) { @@ -105,18 +113,17 @@ class OneBotV11 'params' => [ 'user_id' => $user_id, 'message' => $message, - 'auto_escape' => $auto_escape - ] + 'auto_escape' => $auto_escape, + ], ], $this->callback); } /** * 发送群消息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_group_msg-%E5%8F%91%E9%80%81%E7%BE%A4%E6%B6%88%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_group_msg-%E5%8F%91%E9%80%81%E7%BE%A4%E6%B6%88%E6%81%AF * @param $group_id * @param $message - * @param bool $auto_escape - * @return array|bool|null + * @return null|array|bool */ public function sendGroupMsg($group_id, $message, bool $auto_escape = false) { @@ -125,19 +132,18 @@ class OneBotV11 'params' => [ 'group_id' => $group_id, 'message' => $message, - 'auto_escape' => $auto_escape - ] + 'auto_escape' => $auto_escape, + ], ], $this->callback); } /** * 发送消息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_msg-%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_msg-%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF * @param $message_type * @param $target_id * @param $message - * @param bool $auto_escape - * @return array|bool|null + * @return null|array|bool */ public function sendMsg($message_type, $target_id, $message, bool $auto_escape = false) { @@ -147,65 +153,64 @@ class OneBotV11 'message_type' => $message_type, ($message_type == 'private' ? 'user' : $message_type) . '_id' => $target_id, 'message' => $message, - 'auto_escape' => $auto_escape - ] + 'auto_escape' => $auto_escape, + ], ], $this->callback); } /** * 撤回消息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#delete_msg-%E6%92%A4%E5%9B%9E%E6%B6%88%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#delete_msg-%E6%92%A4%E5%9B%9E%E6%B6%88%E6%81%AF * @param $message_id - * @return array|bool|null + * @return null|array|bool */ public function deleteMsg($message_id) { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'message_id' => $message_id - ] + 'message_id' => $message_id, + ], ], $this->callback); } /** * 获取消息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_msg-%E8%8E%B7%E5%8F%96%E6%B6%88%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_msg-%E8%8E%B7%E5%8F%96%E6%B6%88%E6%81%AF * @param $message_id - * @return array|bool|null + * @return null|array|bool */ public function getMsg($message_id) { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'message_id' => $message_id - ] + 'message_id' => $message_id, + ], ], $this->callback); } /** * 获取合并转发消息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_forward_msg-%E8%8E%B7%E5%8F%96%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91%E6%B6%88%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_forward_msg-%E8%8E%B7%E5%8F%96%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91%E6%B6%88%E6%81%AF * @param $id - * @return array|bool|null + * @return null|array|bool */ public function getForwardMsg($id) { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'id' => $id - ] + 'id' => $id, + ], ], $this->callback); } /** * 发送好友赞 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_like-%E5%8F%91%E9%80%81%E5%A5%BD%E5%8F%8B%E8%B5%9E + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#send_like-%E5%8F%91%E9%80%81%E5%A5%BD%E5%8F%8B%E8%B5%9E * @param $user_id - * @param int $times - * @return array|bool|null + * @return null|array|bool */ public function sendLike($user_id, int $times = 1) { @@ -213,18 +218,17 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'user_id' => $user_id, - 'times' => $times - ] + 'times' => $times, + ], ], $this->callback); } /** * 群组踢人 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_kick-%E7%BE%A4%E7%BB%84%E8%B8%A2%E4%BA%BA + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_kick-%E7%BE%A4%E7%BB%84%E8%B8%A2%E4%BA%BA * @param $group_id * @param $user_id - * @param bool $reject_add_request - * @return array|bool|null + * @return null|array|bool */ public function setGroupKick($group_id, $user_id, bool $reject_add_request = false) { @@ -233,18 +237,17 @@ class OneBotV11 'params' => [ 'group_id' => $group_id, 'user_id' => $user_id, - 'reject_add_request' => $reject_add_request - ] + 'reject_add_request' => $reject_add_request, + ], ], $this->callback); } /** * 群组单人禁言 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_ban-%E7%BE%A4%E7%BB%84%E5%8D%95%E4%BA%BA%E7%A6%81%E8%A8%80 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_ban-%E7%BE%A4%E7%BB%84%E5%8D%95%E4%BA%BA%E7%A6%81%E8%A8%80 * @param $group_id * @param $user_id - * @param int $duration - * @return array|bool|null + * @return null|array|bool */ public function setGroupBan($group_id, $user_id, int $duration = 1800) { @@ -253,18 +256,17 @@ class OneBotV11 'params' => [ 'group_id' => $group_id, 'user_id' => $user_id, - 'duration' => $duration - ] + 'duration' => $duration, + ], ], $this->callback); } /** * 群组匿名用户禁言 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_anonymous_ban-%E7%BE%A4%E7%BB%84%E5%8C%BF%E5%90%8D%E7%94%A8%E6%88%B7%E7%A6%81%E8%A8%80 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_anonymous_ban-%E7%BE%A4%E7%BB%84%E5%8C%BF%E5%90%8D%E7%94%A8%E6%88%B7%E7%A6%81%E8%A8%80 * @param $group_id * @param $anonymous_or_flag - * @param int $duration - * @return array|bool|null + * @return null|array|bool */ public function setGroupAnonymousBan($group_id, $anonymous_or_flag, int $duration = 1800) { @@ -273,17 +275,16 @@ class OneBotV11 'params' => [ 'group_id' => $group_id, (is_string($anonymous_or_flag) ? 'flag' : 'anonymous') => $anonymous_or_flag, - 'duration' => $duration - ] + 'duration' => $duration, + ], ], $this->callback); } /** * 群组全员禁言 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_whole_ban-%E7%BE%A4%E7%BB%84%E5%85%A8%E5%91%98%E7%A6%81%E8%A8%80 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_whole_ban-%E7%BE%A4%E7%BB%84%E5%85%A8%E5%91%98%E7%A6%81%E8%A8%80 * @param $group_id - * @param bool $enable - * @return array|bool|null + * @return null|array|bool */ public function setGroupWholeBan($group_id, bool $enable = true) { @@ -291,18 +292,17 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'group_id' => $group_id, - 'enable' => $enable - ] + 'enable' => $enable, + ], ], $this->callback); } /** * 群组设置管理员 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_admin-%E7%BE%A4%E7%BB%84%E8%AE%BE%E7%BD%AE%E7%AE%A1%E7%90%86%E5%91%98 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_admin-%E7%BE%A4%E7%BB%84%E8%AE%BE%E7%BD%AE%E7%AE%A1%E7%90%86%E5%91%98 * @param $group_id * @param $user_id - * @param bool $enable - * @return array|bool|null + * @return null|array|bool */ public function setGroupAdmin($group_id, $user_id, bool $enable = true) { @@ -311,17 +311,16 @@ class OneBotV11 'params' => [ 'group_id' => $group_id, 'user_id' => $user_id, - 'enable' => $enable - ] + 'enable' => $enable, + ], ], $this->callback); } /** * 群组匿名 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_anonymous-%E7%BE%A4%E7%BB%84%E5%8C%BF%E5%90%8D + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_anonymous-%E7%BE%A4%E7%BB%84%E5%8C%BF%E5%90%8D * @param $group_id - * @param bool $enable - * @return array|bool|null + * @return null|array|bool */ public function setGroupAnonymous($group_id, bool $enable = true) { @@ -329,18 +328,17 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'group_id' => $group_id, - 'enable' => $enable - ] + 'enable' => $enable, + ], ], $this->callback); } /** * 设置群名片(群备注) - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_card-%E8%AE%BE%E7%BD%AE%E7%BE%A4%E5%90%8D%E7%89%87%E7%BE%A4%E5%A4%87%E6%B3%A8 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_card-%E8%AE%BE%E7%BD%AE%E7%BE%A4%E5%90%8D%E7%89%87%E7%BE%A4%E5%A4%87%E6%B3%A8 * @param $group_id * @param $user_id - * @param string $card - * @return array|bool|null + * @return null|array|bool */ public function setGroupCard($group_id, $user_id, string $card = '') { @@ -349,17 +347,17 @@ class OneBotV11 'params' => [ 'group_id' => $group_id, 'user_id' => $user_id, - 'card' => $card - ] + 'card' => $card, + ], ], $this->callback); } /** * 设置群名 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_name-%E8%AE%BE%E7%BD%AE%E7%BE%A4%E5%90%8D + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_name-%E8%AE%BE%E7%BD%AE%E7%BE%A4%E5%90%8D * @param $group_id * @param $group_name - * @return array|bool|null + * @return null|array|bool */ public function setGroupName($group_id, $group_name) { @@ -367,17 +365,16 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'group_id' => $group_id, - 'group_name' => $group_name - ] + 'group_name' => $group_name, + ], ], $this->callback); } /** * 退出群组 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_leave-%E9%80%80%E5%87%BA%E7%BE%A4%E7%BB%84 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_leave-%E9%80%80%E5%87%BA%E7%BE%A4%E7%BB%84 * @param $group_id - * @param bool $is_dismiss - * @return array|bool|null + * @return null|array|bool */ public function setGroupLeave($group_id, bool $is_dismiss = false) { @@ -385,21 +382,19 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'group_id' => $group_id, - 'is_dismiss' => $is_dismiss - ] + 'is_dismiss' => $is_dismiss, + ], ], $this->callback); } /** * 设置群组专属头衔 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_special_title-%E8%AE%BE%E7%BD%AE%E7%BE%A4%E7%BB%84%E4%B8%93%E5%B1%9E%E5%A4%B4%E8%A1%94 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_special_title-%E8%AE%BE%E7%BD%AE%E7%BE%A4%E7%BB%84%E4%B8%93%E5%B1%9E%E5%A4%B4%E8%A1%94 * @param $group_id * @param $user_id - * @param string $special_title - * @param int $duration - * @return array|bool|null + * @return null|array|bool */ - public function setGroupSpecialTitle($group_id, $user_id, string $special_title = "", int $duration = -1) + public function setGroupSpecialTitle($group_id, $user_id, string $special_title = '', int $duration = -1) { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), @@ -407,41 +402,37 @@ class OneBotV11 'group_id' => $group_id, 'user_id' => $user_id, 'special_title' => $special_title, - 'duration' => $duration - ] + 'duration' => $duration, + ], ], $this->callback); } /** * 处理加好友请求 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_friend_add_request-%E5%A4%84%E7%90%86%E5%8A%A0%E5%A5%BD%E5%8F%8B%E8%AF%B7%E6%B1%82 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_friend_add_request-%E5%A4%84%E7%90%86%E5%8A%A0%E5%A5%BD%E5%8F%8B%E8%AF%B7%E6%B1%82 * @param $flag - * @param bool $approve - * @param string $remark - * @return array|bool|null + * @return null|array|bool */ - public function setFriendAddRequest($flag, bool $approve = true, string $remark = "") + public function setFriendAddRequest($flag, bool $approve = true, string $remark = '') { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'flag' => $flag, 'approve' => $approve, - 'remark' => $remark - ] + 'remark' => $remark, + ], ], $this->callback); } /** * 处理加群请求/邀请 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_add_request-%E5%A4%84%E7%90%86%E5%8A%A0%E7%BE%A4%E8%AF%B7%E6%B1%82%E9%82%80%E8%AF%B7 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_group_add_request-%E5%A4%84%E7%90%86%E5%8A%A0%E7%BE%A4%E8%AF%B7%E6%B1%82%E9%82%80%E8%AF%B7 * @param $flag * @param $sub_type - * @param bool $approve - * @param string $reason - * @return array|bool|null + * @return null|array|bool */ - public function setGroupAddRequest($flag, $sub_type, bool $approve = true, string $reason = "") + public function setGroupAddRequest($flag, $sub_type, bool $approve = true, string $reason = '') { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), @@ -449,15 +440,15 @@ class OneBotV11 'flag' => $flag, 'sub_type' => $sub_type, 'approve' => $approve, - 'reason' => $reason - ] + 'reason' => $reason, + ], ], $this->callback); } /** * 获取登录号信息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_login_info-%E8%8E%B7%E5%8F%96%E7%99%BB%E5%BD%95%E5%8F%B7%E4%BF%A1%E6%81%AF - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_login_info-%E8%8E%B7%E5%8F%96%E7%99%BB%E5%BD%95%E5%8F%B7%E4%BF%A1%E6%81%AF + * @return null|array|bool */ public function getLoginInfo() { @@ -466,10 +457,9 @@ class OneBotV11 /** * 获取陌生人信息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_stranger_info-%E8%8E%B7%E5%8F%96%E9%99%8C%E7%94%9F%E4%BA%BA%E4%BF%A1%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_stranger_info-%E8%8E%B7%E5%8F%96%E9%99%8C%E7%94%9F%E4%BA%BA%E4%BF%A1%E6%81%AF * @param $user_id - * @param bool $no_cache - * @return array|bool|null + * @return null|array|bool */ public function getStrangerInfo($user_id, bool $no_cache = false) { @@ -477,29 +467,28 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'user_id' => $user_id, - 'no_cache' => $no_cache - ] + 'no_cache' => $no_cache, + ], ], $this->callback); } /** * 获取好友列表 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_friend_list-%E8%8E%B7%E5%8F%96%E5%A5%BD%E5%8F%8B%E5%88%97%E8%A1%A8 - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_friend_list-%E8%8E%B7%E5%8F%96%E5%A5%BD%E5%8F%8B%E5%88%97%E8%A1%A8 + * @return null|array|bool */ public function getFriendList() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 获取群信息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_info-%E8%8E%B7%E5%8F%96%E7%BE%A4%E4%BF%A1%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_info-%E8%8E%B7%E5%8F%96%E7%BE%A4%E4%BF%A1%E6%81%AF * @param $group_id - * @param bool $no_cache - * @return array|bool|null + * @return null|array|bool */ public function getGroupInfo($group_id, bool $no_cache = false) { @@ -507,30 +496,29 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'group_id' => $group_id, - 'no_cache' => $no_cache - ] + 'no_cache' => $no_cache, + ], ], $this->callback); } /** * 获取群列表 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_list-%E8%8E%B7%E5%8F%96%E7%BE%A4%E5%88%97%E8%A1%A8 - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_list-%E8%8E%B7%E5%8F%96%E7%BE%A4%E5%88%97%E8%A1%A8 + * @return null|array|bool */ public function getGroupList() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 获取群成员信息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_member_info-%E8%8E%B7%E5%8F%96%E7%BE%A4%E6%88%90%E5%91%98%E4%BF%A1%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_member_info-%E8%8E%B7%E5%8F%96%E7%BE%A4%E6%88%90%E5%91%98%E4%BF%A1%E6%81%AF * @param $group_id * @param $user_id - * @param bool $no_cache - * @return array|bool|null + * @return null|array|bool */ public function getGroupMemberInfo($group_id, $user_id, bool $no_cache = false) { @@ -539,33 +527,33 @@ class OneBotV11 'params' => [ 'group_id' => $group_id, 'user_id' => $user_id, - 'no_cache' => $no_cache - ] + 'no_cache' => $no_cache, + ], ], $this->callback); } /** * 获取群成员列表 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_member_list-%E8%8E%B7%E5%8F%96%E7%BE%A4%E6%88%90%E5%91%98%E5%88%97%E8%A1%A8 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_member_list-%E8%8E%B7%E5%8F%96%E7%BE%A4%E6%88%90%E5%91%98%E5%88%97%E8%A1%A8 * @param $group_id - * @return array|bool|null + * @return null|array|bool */ public function getGroupMemberList($group_id) { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'group_id' => $group_id - ] + 'group_id' => $group_id, + ], ], $this->callback); } /** * 获取群荣誉信息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_honor_info-%E8%8E%B7%E5%8F%96%E7%BE%A4%E8%8D%A3%E8%AA%89%E4%BF%A1%E6%81%AF + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_group_honor_info-%E8%8E%B7%E5%8F%96%E7%BE%A4%E8%8D%A3%E8%AA%89%E4%BF%A1%E6%81%AF * @param $group_id * @param $type - * @return array|bool|null + * @return null|array|bool */ public function getGroupHonorInfo($group_id, $type) { @@ -573,45 +561,44 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'group_id' => $group_id, - 'type' => $type - ] + 'type' => $type, + ], ], $this->callback); } /** * 获取 CSRF Token - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_csrf_token-%E8%8E%B7%E5%8F%96-csrf-token - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_csrf_token-%E8%8E%B7%E5%8F%96-csrf-token + * @return null|array|bool */ public function getCsrfToken() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 获取 QQ 相关接口凭证 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_credentials-%E8%8E%B7%E5%8F%96-qq-%E7%9B%B8%E5%85%B3%E6%8E%A5%E5%8F%A3%E5%87%AD%E8%AF%81 - * @param string $domain - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_credentials-%E8%8E%B7%E5%8F%96-qq-%E7%9B%B8%E5%85%B3%E6%8E%A5%E5%8F%A3%E5%87%AD%E8%AF%81 + * @return null|array|bool */ - public function getCredentials(string $domain = "") + public function getCredentials(string $domain = '') { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'domain' => $domain - ] + 'domain' => $domain, + ], ], $this->callback); } /** * 获取语音 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_record-%E8%8E%B7%E5%8F%96%E8%AF%AD%E9%9F%B3 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_record-%E8%8E%B7%E5%8F%96%E8%AF%AD%E9%9F%B3 * @param $file * @param $out_format - * @return array|bool|null + * @return null|array|bool */ public function getRecord($file, $out_format) { @@ -619,109 +606,107 @@ class OneBotV11 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ 'file' => $file, - 'out_format' => $out_format - ] + 'out_format' => $out_format, + ], ], $this->callback); } /** * 获取图片 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_image-%E8%8E%B7%E5%8F%96%E5%9B%BE%E7%89%87 + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_image-%E8%8E%B7%E5%8F%96%E5%9B%BE%E7%89%87 * @param $file - * @return array|bool|null + * @return null|array|bool */ public function getImage($file) { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'file' => $file - ] + 'file' => $file, + ], ], $this->callback); } /** * 检查是否可以发送图片 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#can_send_image-%E6%A3%80%E6%9F%A5%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E5%8F%91%E9%80%81%E5%9B%BE%E7%89%87 - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#can_send_image-%E6%A3%80%E6%9F%A5%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E5%8F%91%E9%80%81%E5%9B%BE%E7%89%87 + * @return null|array|bool */ public function canSendImage() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 检查是否可以发送语音 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#can_send_record-%E6%A3%80%E6%9F%A5%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E5%8F%91%E9%80%81%E8%AF%AD%E9%9F%B3 - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#can_send_record-%E6%A3%80%E6%9F%A5%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E5%8F%91%E9%80%81%E8%AF%AD%E9%9F%B3 + * @return null|array|bool */ public function canSendRecord() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 获取运行状态 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_status-%E8%8E%B7%E5%8F%96%E8%BF%90%E8%A1%8C%E7%8A%B6%E6%80%81 - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_status-%E8%8E%B7%E5%8F%96%E8%BF%90%E8%A1%8C%E7%8A%B6%E6%80%81 + * @return null|array|bool */ public function getStatus() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 获取版本信息 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_version_info-%E8%8E%B7%E5%8F%96%E7%89%88%E6%9C%AC%E4%BF%A1%E6%81%AF - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#get_version_info-%E8%8E%B7%E5%8F%96%E7%89%88%E6%9C%AC%E4%BF%A1%E6%81%AF + * @return null|array|bool */ public function getVersionInfo() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 重启 OneBot 实现 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_restart-%E9%87%8D%E5%90%AF-onebot-%E5%AE%9E%E7%8E%B0 - * @param int $delay - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#set_restart-%E9%87%8D%E5%90%AF-onebot-%E5%AE%9E%E7%8E%B0 + * @return null|array|bool */ public function setRestart(int $delay = 0) { return $this->processAPI($this->connection, [ 'action' => $this->getActionName($this->prefix, __FUNCTION__), 'params' => [ - 'delay' => $delay - ] + 'delay' => $delay, + ], ], $this->callback); } /** * 清理缓存 - * @link https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#clean_cache-%E6%B8%85%E7%90%86%E7%BC%93%E5%AD%98 - * @return array|bool|null + * @see https://github.com/howmanybots/onebot/blob/master/v11/specs/api/public.md#clean_cache-%E6%B8%85%E7%90%86%E7%BC%93%E5%AD%98 + * @return null|array|bool */ public function cleanCache() { return $this->processAPI($this->connection, [ - 'action' => $this->getActionName($this->prefix, __FUNCTION__) + 'action' => $this->getActionName($this->prefix, __FUNCTION__), ], $this->callback); } /** * 获取内置支持的扩展API对象 * 现支持 go-cqhttp 的扩展API - * @param string $package_name - * @return mixed * @throws ZMKnownException + * @return mixed */ public function getExtendedAPI(string $package_name = 'go-cqhttp') { @@ -730,16 +715,15 @@ class OneBotV11 ]; if (isset($table[$package_name])) { return new $table[$package_name]($this->connection, $this->callback, $this->prefix); - } else { - throw new ZMKnownException(zm_internal_errcode('E00071'), '无法找到对应的调用扩展类'); } + throw new ZMKnownException(zm_internal_errcode('E00071'), '无法找到对应的调用扩展类'); } public function callExtendedAPI($action, $params = []) { return $this->processAPI($this->connection, [ 'action' => $action, - 'params' => $params + 'params' => $params, ], $this->callback); } -} \ No newline at end of file +} diff --git a/src/ZM/API/TuringAPI.php b/src/ZM/API/TuringAPI.php index 5b851386..fb56062a 100644 --- a/src/ZM/API/TuringAPI.php +++ b/src/ZM/API/TuringAPI.php @@ -1,9 +1,9 @@ 0, - "userInfo" => [ - "apiKey" => $api, - "userId" => $user_id - ] + 'reqType' => 0, + 'userInfo' => [ + 'apiKey' => $api, + 'userId' => $user_id, + ], ]; - if ($msg != "") { - $content["perception"]["inputText"]["text"] = $msg; + if ($msg != '') { + $content['perception']['inputText']['text'] = $msg; } $msg = trim($msg); - if (mb_strlen($msg) < 1 && !isset($url)) return "请说出你想说的话"; - if (isset($url)) { - $content["perception"]["inputImage"]["url"] = $url; - $content["reqType"] = 1; + if (mb_strlen($msg) < 1 && !isset($url)) { + return '请说出你想说的话'; } - if (!isset($content["perception"])) return "请说出你想说的话"; - $client = new Client("openapi.tuling123.com", 80); - $client->setHeaders(["Content-type" => "application/json"]); - $client->post("/openapi/api/v2", json_encode($content, JSON_UNESCAPED_UNICODE)); + if (isset($url)) { + $content['perception']['inputImage']['url'] = $url; + $content['reqType'] = 1; + } + if (!isset($content['perception'])) { + return '请说出你想说的话'; + } + $client = new Client('openapi.tuling123.com', 80); + $client->setHeaders(['Content-type' => 'application/json']); + $client->post('/openapi/api/v2', json_encode($content, JSON_UNESCAPED_UNICODE)); $api_return = json_decode($client->body, true); - if (!isset($api_return["intent"]["code"])) return "XD 哎呀,我脑子突然短路了,请稍后再问我吧!"; + if (!isset($api_return['intent']['code'])) { + return 'XD 哎呀,我脑子突然短路了,请稍后再问我吧!'; + } $status = self::getResultStatus($api_return); if ($status !== true) { - if ($status == "err:输入文本内容超长(上限150)") return "你的话太多了!!!"; - if ($api_return["intent"]["code"] == 4003) { - return "哎呀,我刚才有点走神了,可能忘记你说什么了,可以重说一遍吗"; + if ($status == 'err:输入文本内容超长(上限150)') { + return '你的话太多了!!!'; } - Console::error(zm_internal_errcode("E00038") . "图灵机器人发送错误!\n错误原始内容:" . $origin . "\n来自:" . $user_id . "\n错误信息:" . $status); + if ($api_return['intent']['code'] == 4003) { + return '哎呀,我刚才有点走神了,可能忘记你说什么了,可以重说一遍吗'; + } + Console::error(zm_internal_errcode('E00038') . "图灵机器人发送错误!\n错误原始内容:" . $origin . "\n来自:" . $user_id . "\n错误信息:" . $status); //echo json_encode($r, 128|256); - return "哎呀,我刚才有点走神了,要不一会儿换一种问题试试?"; + return '哎呀,我刚才有点走神了,要不一会儿换一种问题试试?'; } - $result = $api_return["results"]; + $result = $api_return['results']; //Console::info(Console::setColor(json_encode($result, 128 | 256), "green")); - $final = ""; + $final = ''; foreach ($result as $v) { - switch ($v["resultType"]) { - case "url": - $final .= "\n" . $v["values"]["url"]; + switch ($v['resultType']) { + case 'url': + $final .= "\n" . $v['values']['url']; break; - case "text": - $final .= "\n" . $v["values"]["text"]; + case 'text': + $final .= "\n" . $v['values']['text']; break; - case "image": - $final .= "\n" . CQ::image($v["values"]["image"]); + case 'image': + $final .= "\n" . CQ::image($v['values']['image']); break; } } return trim($final); } - public static function getResultStatus($r) { - switch ($r["intent"]["code"]) { + public static function getResultStatus($r) + { + switch ($r['intent']['code']) { case 5000: - return "err:无解析结果"; + return 'err:无解析结果'; case 4000: case 6000: - return "err:暂不支持该功能"; + return 'err:暂不支持该功能'; case 4001: - return "err:加密方式错误"; + return 'err:加密方式错误'; case 4005: case 4002: - return "err:无功能权限"; + return 'err:无功能权限'; case 4003: - return "err:该apikey没有可用请求次数"; + return 'err:该apikey没有可用请求次数'; case 4007: - return "err:apikey不合法"; + return 'err:apikey不合法'; case 4100: - return "err:userid获取失败"; + return 'err:userid获取失败'; case 4200: - return "err:上传格式错误"; + return 'err:上传格式错误'; case 4300: - return "err:批量操作超过限制"; + return 'err:批量操作超过限制'; case 4400: - return "err:没有上传合法userid"; + return 'err:没有上传合法userid'; case 4500: - return "err:userid申请个数超过限制"; + return 'err:userid申请个数超过限制'; case 4600: - return "err:输入内容为空"; + return 'err:输入内容为空'; case 4602: - return "err:输入文本内容超长(上限150)"; + return 'err:输入文本内容超长(上限150)'; case 7002: - return "err:上传信息失败"; + return 'err:上传信息失败'; case 8008: - return "err:服务器错误"; + return 'err:服务器错误'; default: return true; } } -} \ No newline at end of file +} diff --git a/src/ZM/API/ZMRobot.php b/src/ZM/API/ZMRobot.php index fb304856..23dd8c6e 100644 --- a/src/ZM/API/ZMRobot.php +++ b/src/ZM/API/ZMRobot.php @@ -1,17 +1,14 @@ - $v) { - $str .= "\n\t" . $k . " => "; - if (is_string($v)) $str .= "\"$v\""; - elseif (is_numeric($v)) $str .= $v; - elseif (is_bool($v)) $str .= ($v ? "TRUE" : "FALSE"); - elseif (is_array($v)) $str .= json_encode($v, JSON_UNESCAPED_UNICODE); - elseif ($v instanceof Closure) $str .= "@AnonymousFunction"; - elseif (is_null($v)) $str .= "NULL"; - else $str .= "@Unknown"; + $str .= "\n\t" . $k . ' => '; + if (is_string($v)) { + $str .= "\"{$v}\""; + } elseif (is_numeric($v)) { + $str .= $v; + } elseif (is_bool($v)) { + $str .= ($v ? 'TRUE' : 'FALSE'); + } elseif (is_array($v)) { + $str .= json_encode($v, JSON_UNESCAPED_UNICODE); + } elseif ($v instanceof Closure) { + $str .= '@AnonymousFunction'; + } elseif (is_null($v)) { + $str .= 'NULL'; + } else { + $str .= '@Unknown'; + } } return $str; } -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/AnnotationParser.php b/src/ZM/Annotation/AnnotationParser.php index c335de14..27a9c42f 100644 --- a/src/ZM/Annotation/AnnotationParser.php +++ b/src/ZM/Annotation/AnnotationParser.php @@ -1,13 +1,10 @@ start_time = microtime(true); //$this->loadAnnotationClasses(); $this->req_mapping[0] = [ 'id' => 0, 'pid' => -1, - 'name' => '/' + 'name' => '/', ]; } @@ -54,13 +58,14 @@ class AnnotationParser * 注册各个模块类的注解和模块level的排序 * @throws ReflectionException */ - public function registerMods() { + public function registerMods() + { foreach ($this->path_list as $path) { - Console::debug("parsing annotation in " . $path[0].":".$path[1]); + Console::debug('parsing annotation in ' . $path[0] . ':' . $path[1]); $all_class = ZMUtil::getClassesPsr4($path[0], $path[1]); $this->reader = new AnnotationReader(); foreach ($all_class as $v) { - Console::debug("正在检索 " . $v); + Console::debug('正在检索 ' . $v); $reflection_class = new ReflectionClass($v); $methods = $reflection_class->getMethods(ReflectionMethod::IS_PUBLIC); $class_annotations = $this->reader->getClassAnnotations($reflection_class); @@ -85,22 +90,21 @@ class AnnotationParser */ // 生成主树 - $this->annotation_map[$v]["class_annotations"] = $class_annotations; - $this->annotation_map[$v]["methods"] = $methods; + $this->annotation_map[$v]['class_annotations'] = $class_annotations; + $this->annotation_map[$v]['methods'] = $methods; foreach ($methods as $method) { - $this->annotation_map[$v]["methods_annotations"][$method->getName()] = $this->reader->getMethodAnnotations($method); + $this->annotation_map[$v]['methods_annotations'][$method->getName()] = $this->reader->getMethodAnnotations($method); } - - foreach ($this->annotation_map[$v]["class_annotations"] as $vs) { + foreach ($this->annotation_map[$v]['class_annotations'] as $vs) { $vs->class = $v; //预处理1:将适用于每一个函数的注解到类注解重新注解到每个函数下面 if ($vs instanceof ErgodicAnnotation) { - foreach (($this->annotation_map[$v]["methods"] ?? []) as $method) { + foreach (($this->annotation_map[$v]['methods'] ?? []) as $method) { $copy = clone $vs; $copy->method = $method->getName(); - $this->annotation_map[$v]["methods_annotations"][$method->getName()][] = $copy; + $this->annotation_map[$v]['methods_annotations'][$method->getName()][] = $copy; } } @@ -108,23 +112,24 @@ class AnnotationParser if ($vs instanceof Closed) { unset($this->annotation_map[$v]); continue 2; - } elseif ($vs instanceof MiddlewareClass) { + } + if ($vs instanceof MiddlewareClass) { //注册中间件本身的类,标记到 middlewares 属性中 - Console::debug("正在注册中间件 " . $reflection_class->getName()); + Console::debug('正在注册中间件 ' . $reflection_class->getName()); $rs = $this->registerMiddleware($vs, $reflection_class); - $this->middlewares[$rs["name"]] = $rs; + $this->middlewares[$rs['name']] = $rs; } } $inserted = []; //预处理3:处理每个函数上面的特殊注解,就是需要操作一些东西的 - foreach (($this->annotation_map[$v]["methods_annotations"] ?? []) as $method_name => $methods_annotations) { + foreach (($this->annotation_map[$v]['methods_annotations'] ?? []) as $method_name => $methods_annotations) { foreach ($methods_annotations as $method_anno) { - /** @var AnnotationBase $method_anno */ + /* @var AnnotationBase $method_anno */ $method_anno->class = $v; $method_anno->method = $method_name; - if (!($method_anno instanceof Middleware) && ($middlewares = ZMConfig::get("global", "runtime")["global_middleware_binding"][get_class($method_anno)] ?? []) !== []) { + if (!($method_anno instanceof Middleware) && ($middlewares = ZMConfig::get('global', 'runtime')['global_middleware_binding'][get_class($method_anno)] ?? []) !== []) { if (!isset($inserted[$v][$method_name])) { // 在这里在其他中间件前插入插入全局的中间件 foreach ($middlewares as $middleware) { @@ -146,23 +151,25 @@ class AnnotationParser } } } - Console::debug("解析注解完毕!"); + Console::debug('解析注解完毕!'); } - public function generateAnnotationEvents(): array { + public function generateAnnotationEvents(): array + { $o = []; foreach ($this->annotation_map as $obj) { // 这里的ErgodicAnnotation是为了解决类上的注解可穿透到方法上的问题 - foreach (($obj["class_annotations"] ?? []) as $class_annotation) { - if ($class_annotation instanceof ErgodicAnnotation) continue; - else $o[get_class($class_annotation)][] = $class_annotation; + foreach (($obj['class_annotations'] ?? []) as $class_annotation) { + if ($class_annotation instanceof ErgodicAnnotation) { + continue; + } + $o[get_class($class_annotation)][] = $class_annotation; } - foreach (($obj["methods_annotations"] ?? []) as $methods_annotations) { + foreach (($obj['methods_annotations'] ?? []) as $methods_annotations) { foreach ($methods_annotations as $annotation) { $o[get_class($annotation)][] = $annotation; } } - } foreach ($o as $k => $v) { $this->sortByLevel($o, $k); @@ -170,55 +177,36 @@ class AnnotationParser return $o; } - /** - * @return array - */ - public function getMiddlewares(): array { return $this->middlewares; } + public function getMiddlewares(): array + { + return $this->middlewares; + } - /** - * @return array - */ - public function getMiddlewareMap(): array { return $this->middleware_map; } + public function getMiddlewareMap(): array + { + return $this->middleware_map; + } - /** - * @return array - */ - public function getReqMapping(): array { return $this->req_mapping; } + public function getReqMapping(): array + { + return $this->req_mapping; + } /** * @param $path * @param $indoor_name */ - public function addRegisterPath($path, $indoor_name) { $this->path_list[] = [$path, $indoor_name]; } - - //private function below - - private function registerMiddleware(MiddlewareClass $vs, ReflectionClass $reflection_class): array { - $result = [ - "class" => "\\" . $reflection_class->getName(), - "name" => $vs->name - ]; - - foreach ($reflection_class->getMethods() as $vss) { - $method_annotations = $this->reader->getMethodAnnotations($vss); - foreach ($method_annotations as $vsss) { - if ($vsss instanceof HandleBefore) $result["before"] = $vss->getName(); - if ($vsss instanceof HandleAfter) $result["after"] = $vss->getName(); - if ($vsss instanceof HandleException) { - $result["exceptions"][$vsss->class_name] = $vss->getName(); - } - } - } - return $result; + public function addRegisterPath($path, $indoor_name) + { + $this->path_list[] = [$path, $indoor_name]; } /** - * @internal 用于 level 排序 * @param $events - * @param string $class_name - * @param string $prefix + * @internal 用于 level 排序 */ - public function sortByLevel(&$events, string $class_name, $prefix = "") { + public function sortByLevel(&$events, string $class_name, string $prefix = '') + { if (is_a($class_name, Level::class, true)) { $class_name .= $prefix; usort($events[$class_name], function ($a, $b) { @@ -232,12 +220,13 @@ class AnnotationParser /** * @throws AnnotationException */ - public function verifyMiddlewares() { - if ((ZMConfig::get("global", "runtime")["middleware_error_policy"] ?? 1) === 2) { + public function verifyMiddlewares() + { + if ((ZMConfig::get('global', 'runtime')['middleware_error_policy'] ?? 1) === 2) { //我承认套三层foreach很不优雅,但是这个会很快的。 - foreach($this->middleware_map as $class => $v) { - foreach ($v as $method => $vs) { - foreach($vs as $mid) { + foreach ($this->middleware_map as $v) { + foreach ($v as $vs) { + foreach ($vs as $mid) { if (!isset($this->middlewares[$mid->middleware])) { throw new AnnotationException("Annotation parse error: Unknown MiddlewareClass named \"{$mid->middleware}\"!"); } @@ -246,4 +235,35 @@ class AnnotationParser } } } + + public function getRunTime() + { + return microtime(true) - $this->start_time; + } + + //private function below + + private function registerMiddleware(MiddlewareClass $vs, ReflectionClass $reflection_class): array + { + $result = [ + 'class' => '\\' . $reflection_class->getName(), + 'name' => $vs->name, + ]; + + foreach ($reflection_class->getMethods() as $vss) { + $method_annotations = $this->reader->getMethodAnnotations($vss); + foreach ($method_annotations as $vsss) { + if ($vsss instanceof HandleBefore) { + $result['before'] = $vss->getName(); + } + if ($vsss instanceof HandleAfter) { + $result['after'] = $vss->getName(); + } + if ($vsss instanceof HandleException) { + $result['exceptions'][$vsss->class_name] = $vss->getName(); + } + } + } + return $result; + } } diff --git a/src/ZM/Annotation/CQ/CQAPIResponse.php b/src/ZM/Annotation/CQ/CQAPIResponse.php index 67001d66..45d4b89a 100644 --- a/src/ZM/Annotation/CQ/CQAPIResponse.php +++ b/src/ZM/Annotation/CQ/CQAPIResponse.php @@ -1,16 +1,15 @@ level; } /** * @param mixed $level */ - public function setLevel($level) { + public function setLevel($level) + { $this->level = $level; } } diff --git a/src/ZM/Annotation/CQ/CQBefore.php b/src/ZM/Annotation/CQ/CQBefore.php index 5ec379b4..3fa93f72 100644 --- a/src/ZM/Annotation/CQ/CQBefore.php +++ b/src/ZM/Annotation/CQ/CQBefore.php @@ -1,9 +1,9 @@ level; } /** * @param mixed $level */ - public function setLevel($level) { + public function setLevel($level) + { $this->level = $level; } - -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/CQ/CQCommand.php b/src/ZM/Annotation/CQ/CQCommand.php index 7ec493d7..68bbb7d6 100644 --- a/src/ZM/Annotation/CQ/CQCommand.php +++ b/src/ZM/Annotation/CQ/CQCommand.php @@ -1,5 +1,6 @@ level; } + public function getLevel(): int + { + return $this->level; + } /** * @param int $level */ - public function setLevel($level) { $this->level = $level; } - + public function setLevel($level) + { + $this->level = $level; + } } diff --git a/src/ZM/Annotation/CQ/CQMessage.php b/src/ZM/Annotation/CQ/CQMessage.php index d87f8e62..cc847750 100644 --- a/src/ZM/Annotation/CQ/CQMessage.php +++ b/src/ZM/Annotation/CQ/CQMessage.php @@ -1,5 +1,6 @@ level; } + public function getLevel(): int + { + return $this->level; + } - public function setLevel($level) { + public function setLevel($level) + { $this->level = $level; } -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/CQ/CQMetaEvent.php b/src/ZM/Annotation/CQ/CQMetaEvent.php index 1da58459..7cb91a22 100644 --- a/src/ZM/Annotation/CQ/CQMetaEvent.php +++ b/src/ZM/Annotation/CQ/CQMetaEvent.php @@ -1,5 +1,6 @@ level; } + public function getLevel(): int + { + return $this->level; + } /** * @param int $level */ - public function setLevel($level) { + public function setLevel($level) + { $this->level = $level; } -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/CQ/CQNotice.php b/src/ZM/Annotation/CQ/CQNotice.php index f73ef5be..481bde05 100644 --- a/src/ZM/Annotation/CQ/CQNotice.php +++ b/src/ZM/Annotation/CQ/CQNotice.php @@ -1,5 +1,6 @@ level; } /** * @param int $level */ - public function setLevel($level) { + public function setLevel($level) + { $this->level = $level; } -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/CQ/CQRequest.php b/src/ZM/Annotation/CQ/CQRequest.php index 6d51a459..a58eec76 100644 --- a/src/ZM/Annotation/CQ/CQRequest.php +++ b/src/ZM/Annotation/CQ/CQRequest.php @@ -1,5 +1,6 @@ level; } /** * @param int $level */ - public function setLevel($level) { + public function setLevel($level) + { $this->level = $level; } -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/Command/TerminalCommand.php b/src/ZM/Annotation/Command/TerminalCommand.php index 335ac96e..1497231b 100644 --- a/src/ZM/Annotation/Command/TerminalCommand.php +++ b/src/ZM/Annotation/Command/TerminalCommand.php @@ -1,5 +1,6 @@ type; } - /** - * @param string $type - */ - public function setType(string $type) { + public function setType(string $type) + { $this->type = $type; } } diff --git a/src/ZM/Annotation/Swoole/OnSwooleEventBase.php b/src/ZM/Annotation/Swoole/OnSwooleEventBase.php index f0607e0a..a877dfd2 100644 --- a/src/ZM/Annotation/Swoole/OnSwooleEventBase.php +++ b/src/ZM/Annotation/Swoole/OnSwooleEventBase.php @@ -1,9 +1,9 @@ rule !== "" ? $this->rule : true; + public function getRule() + { + return $this->rule !== '' ? $this->rule : true; } - /** - * @param string $rule - */ - public function setRule(string $rule) { + public function setRule(string $rule) + { $this->rule = $rule; } - /** - * @return int - */ - public function getLevel(): int { + public function getLevel(): int + { return $this->level; } /** * @param int $level */ - public function setLevel($level) { + public function setLevel($level) + { $this->level = $level; } -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/Swoole/OnTask.php b/src/ZM/Annotation/Swoole/OnTask.php index b0ae0b68..4f45c7ca 100644 --- a/src/ZM/Annotation/Swoole/OnTask.php +++ b/src/ZM/Annotation/Swoole/OnTask.php @@ -1,5 +1,6 @@ rule; } -} \ No newline at end of file +} diff --git a/src/ZM/Annotation/Swoole/OnTaskEvent.php b/src/ZM/Annotation/Swoole/OnTaskEvent.php index 32740058..4194051e 100644 --- a/src/ZM/Annotation/Swoole/OnTaskEvent.php +++ b/src/ZM/Annotation/Swoole/OnTaskEvent.php @@ -1,5 +1,6 @@ setDescription("Build an \".phar\" file | 将项目构建一个phar包"); - $this->setHelp("此功能将会把整个项目打包为phar"); - $this->addOption("target", "D", InputOption::VALUE_REQUIRED, "Output Directory | 指定输出目录"); + protected function configure() + { + $this->setDescription('Build an ".phar" file | 将项目构建一个phar包'); + $this->setHelp('此功能将会把整个项目打包为phar'); + $this->addOption('target', 'D', InputOption::VALUE_REQUIRED, 'Output Directory | 指定输出目录'); // ... } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { $this->output = $output; - $target_dir = $input->getOption("target") ?? (WORKING_DIR); - if (mb_strpos($target_dir, "../")) $target_dir = realpath($target_dir); + $target_dir = $input->getOption('target') ?? (WORKING_DIR); + if (mb_strpos($target_dir, '../')) { + $target_dir = realpath($target_dir); + } if ($target_dir === false) { - $output->writeln(TermColor::color8(31) . zm_internal_errcode("E00039") . "Error: No such file or directory (" . $target_dir . ")" . TermColor::RESET); + $output->writeln(TermColor::color8(31) . zm_internal_errcode('E00039') . 'Error: No such file or directory (' . $target_dir . ')' . TermColor::RESET); return 1; } - $output->writeln("Target: " . $target_dir); - if (mb_substr($target_dir, -1, 1) !== '/') $target_dir .= "/"; + $output->writeln('Target: ' . $target_dir); + if (mb_substr($target_dir, -1, 1) !== '/') { + $target_dir .= '/'; + } if (ini_get('phar.readonly') == 1) { - $output->writeln(TermColor::color8(31) . zm_internal_errcode("E00040") . "You need to set \"phar.readonly\" to \"Off\"!"); - $output->writeln(TermColor::color8(31) . "See: https://stackoverflow.com/questions/34667606/cant-enable-phar-writing"); + $output->writeln(TermColor::color8(31) . zm_internal_errcode('E00040') . 'You need to set "phar.readonly" to "Off"!'); + $output->writeln(TermColor::color8(31) . 'See: https://stackoverflow.com/questions/34667606/cant-enable-phar-writing'); return 1; } if (!is_dir($target_dir)) { - $output->writeln(TermColor::color8(31) . zm_internal_errcode("E00039") . "Error: No such file or directory ($target_dir)" . TermColor::RESET); + $output->writeln(TermColor::color8(31) . zm_internal_errcode('E00039') . "Error: No such file or directory ({$target_dir})" . TermColor::RESET); return 1; } - $filename = "server.phar"; + $filename = 'server.phar'; $this->build($target_dir, $filename); return 0; } - private function build($target_dir, $filename) { + private function build($target_dir, $filename) + { @unlink($target_dir . $filename); $phar = new Phar($target_dir . $filename); $phar->startBuffering(); @@ -62,7 +71,7 @@ class BuildCommand extends Command $all = DataProvider::scanDirFiles(DataProvider::getSourceRootDir(), true, true); $all = array_filter($all, function ($x) { - $dirs = preg_match("/(^(bin|config|resources|src|vendor)\/|^(composer\.json|README\.md)$)/", $x); + $dirs = preg_match('/(^(bin|config|resources|src|vendor)\\/|^(composer\\.json|README\\.md)$)/', $x); return !($dirs !== 1); }); @@ -71,15 +80,15 @@ class BuildCommand extends Command $archive_dir = DataProvider::getSourceRootDir(); foreach ($all as $k => $v) { - $phar->addFile($archive_dir . "/" . $v, $v); - $progress->current($k + 1, "Adding " . $v); + $phar->addFile($archive_dir . '/' . $v, $v); + $progress->current($k + 1, 'Adding ' . $v); } $phar->setStub( "#!/usr/bin/env php\n" . - $phar->createDefaultStub(LOAD_MODE == 0 ? "src/entry.php" : "vendor/zhamao/framework/src/entry.php") + $phar->createDefaultStub(LOAD_MODE == 0 ? 'src/entry.php' : 'vendor/zhamao/framework/src/entry.php') ); $phar->stopBuffering(); - $this->output->writeln("Successfully built. Location: " . $target_dir . "$filename"); + $this->output->writeln('Successfully built. Location: ' . $target_dir . "{$filename}"); } } diff --git a/src/ZM/Command/CheckConfigCommand.php b/src/ZM/Command/CheckConfigCommand.php index 4f991a94..ace9f562 100644 --- a/src/ZM/Command/CheckConfigCommand.php +++ b/src/ZM/Command/CheckConfigCommand.php @@ -1,5 +1,6 @@ setDescription("检查配置文件是否和框架当前版本有更新"); + protected function configure() + { + $this->setDescription('检查配置文件是否和框架当前版本有更新'); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { if (LOAD_MODE !== 1) { - $output->writeln("仅限在Composer依赖模式中使用此命令!"); + $output->writeln('仅限在Composer依赖模式中使用此命令!'); return 1; } - $current_cfg = getcwd() . "/config/"; - $remote_cfg = include_once FRAMEWORK_ROOT_DIR . "/config/global.php"; - if (file_exists($current_cfg . "global.php")) { - $this->check($remote_cfg, "global.php", $output); + $current_cfg = getcwd() . '/config/'; + $remote_cfg = include_once FRAMEWORK_ROOT_DIR . '/config/global.php'; + if (file_exists($current_cfg . 'global.php')) { + $this->check($remote_cfg, 'global.php', $output); } - if (file_exists($current_cfg . "global.development.php")) { - $this->check($remote_cfg, "global.development.php", $output); + if (file_exists($current_cfg . 'global.development.php')) { + $this->check($remote_cfg, 'global.development.php', $output); } - if (file_exists($current_cfg . "global.staging.php")) { - $this->check($remote_cfg, "global.staging.php", $output); + if (file_exists($current_cfg . 'global.staging.php')) { + $this->check($remote_cfg, 'global.staging.php', $output); } - if (file_exists($current_cfg . "global.production.php")) { - $this->check($remote_cfg, "global.production.php", $output); + if (file_exists($current_cfg . 'global.production.php')) { + $this->check($remote_cfg, 'global.production.php', $output); } if ($this->need_update === true) { - $output->writeln("有配置文件需要更新,详情见文档 `https://framework.zhamao.xin/update/config`"); + $output->writeln('有配置文件需要更新,详情见文档 `https://framework.zhamao.xin/update/config`'); } else { - $output->writeln("配置文件暂无更新!"); + $output->writeln('配置文件暂无更新!'); } return 0; } /** - * @noinspection PhpIncludeInspection + * @param mixed $remote + * @param mixed $local */ - private function check($remote, $local, OutputInterface $out) { - $local_file = include_once WORKING_DIR . "/config/".$local; + private function check($remote, $local, OutputInterface $out) + { + $local_file = include_once WORKING_DIR . '/config/' . $local; if ($local_file === true) { - $local_file = ZMConfig::get("global"); + $local_file = ZMConfig::get('global'); } - foreach($remote as $k => $v) { + foreach ($remote as $k => $v) { if (!isset($local_file[$k])) { - $out->writeln("配置文件 ".$local . " 需要更新!(当前配置文件缺少 `$k` 字段配置)"); + $out->writeln('配置文件 ' . $local . " 需要更新!(当前配置文件缺少 `{$k}` 字段配置)"); $this->need_update = true; } } diff --git a/src/ZM/Command/Daemon/DaemonCommand.php b/src/ZM/Command/Daemon/DaemonCommand.php index 8bf9ec8e..27d17dce 100644 --- a/src/ZM/Command/Daemon/DaemonCommand.php +++ b/src/ZM/Command/Daemon/DaemonCommand.php @@ -1,9 +1,9 @@ writeln("未检测到正在运行的守护进程或框架进程!"); + if ($file === false || posix_getsid(intval($file['pid'])) === false) { + $output->writeln('未检测到正在运行的守护进程或框架进程!'); Framework::removeProcessState(ZM_PROCESS_MASTER); - die(); + exit(1); } $this->daemon_file = $file; return 0; } -} \ No newline at end of file +} diff --git a/src/ZM/Command/Daemon/DaemonReloadCommand.php b/src/ZM/Command/Daemon/DaemonReloadCommand.php index e06cce56..0b0fe80f 100644 --- a/src/ZM/Command/Daemon/DaemonReloadCommand.php +++ b/src/ZM/Command/Daemon/DaemonReloadCommand.php @@ -1,5 +1,6 @@ setDescription("重载框架"); + protected function configure() + { + $this->setDescription('重载框架'); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { parent::execute($input, $output); - Process::kill(intval($this->daemon_file["pid"]), SIGUSR1); - $output->writeln("成功重载!"); + Process::kill(intval($this->daemon_file['pid']), SIGUSR1); + $output->writeln('成功重载!'); return 0; } } diff --git a/src/ZM/Command/Daemon/DaemonStatusCommand.php b/src/ZM/Command/Daemon/DaemonStatusCommand.php index 0ab44a8c..19ab4b8d 100644 --- a/src/ZM/Command/Daemon/DaemonStatusCommand.php +++ b/src/ZM/Command/Daemon/DaemonStatusCommand.php @@ -1,5 +1,6 @@ setDescription("查看框架的运行状态"); + protected function configure() + { + $this->setDescription('查看框架的运行状态'); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { parent::execute($input, $output); - $output->writeln("框架" . ($this->daemon_file["daemon"] ? "以守护进程模式" : "") . "运行中,pid:" . $this->daemon_file["pid"] . ""); - if ($this->daemon_file["daemon"]) { - $output->writeln("----- 以下是stdout内容 -----"); - $stdout = file_get_contents($this->daemon_file["stdout"]); + $output->writeln('框架' . ($this->daemon_file['daemon'] ? '以守护进程模式' : '') . '运行中,pid:' . $this->daemon_file['pid'] . ''); + if ($this->daemon_file['daemon']) { + $output->writeln('----- 以下是stdout内容 -----'); + $stdout = file_get_contents($this->daemon_file['stdout']); $stdout = explode("\n", $stdout); for ($i = 15; $i > 0; --$i) { - if (isset($stdout[count($stdout) - $i])) + if (isset($stdout[count($stdout) - $i])) { echo $stdout[count($stdout) - $i] . PHP_EOL; + } } } return 0; diff --git a/src/ZM/Command/Daemon/DaemonStopCommand.php b/src/ZM/Command/Daemon/DaemonStopCommand.php index 8e95aa56..f36e4e04 100644 --- a/src/ZM/Command/Daemon/DaemonStopCommand.php +++ b/src/ZM/Command/Daemon/DaemonStopCommand.php @@ -1,5 +1,6 @@ setDescription("停止运行的框架"); + protected function configure() + { + $this->setDescription('停止运行的框架'); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { parent::execute($input, $output); - Process::kill(intval($this->daemon_file["pid"]), SIGTERM); + Process::kill(intval($this->daemon_file['pid']), SIGTERM); $i = 10; while (Framework::getProcessState(ZM_PROCESS_MASTER) !== false && $i > 0) { sleep(1); --$i; } if ($i === 0) { - $output->writeln("停止失败,请检查进程pid #" . $this->daemon_file["pid"] . " 是否响应!"); + $output->writeln('停止失败,请检查进程pid #' . $this->daemon_file['pid'] . ' 是否响应!'); } else { - $output->writeln("成功停止!"); + $output->writeln('成功停止!'); } return 0; } diff --git a/src/ZM/Command/Generate/SystemdGenerateCommand.php b/src/ZM/Command/Generate/SystemdGenerateCommand.php index 93f0d0b9..14519631 100644 --- a/src/ZM/Command/Generate/SystemdGenerateCommand.php +++ b/src/ZM/Command/Generate/SystemdGenerateCommand.php @@ -1,9 +1,9 @@ setDescription("生成框架的 systemd 配置文件"); + protected function configure() + { + $this->setDescription('生成框架的 systemd 配置文件'); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config'); $path = $this->generate(); - $output->writeln("成功生成 systemd 文件,位置:" . $path . ""); - $output->writeln("有关如何使用 systemd 配置文件,请访问 `https://github.com/zhamao-robot/zhamao-framework/issues/36`"); + $output->writeln('成功生成 systemd 文件,位置:' . $path . ''); + $output->writeln('有关如何使用 systemd 配置文件,请访问 `https://github.com/zhamao-robot/zhamao-framework/issues/36`'); return 0; } - private function generate() { + private function generate() + { $s = "[Unit]\nDescription=zhamao-framework Daemon\nAfter=rc-local.service\n\n[Service]\nType=simple"; - $s .= "\nUser=" . exec("whoami"); + $s .= "\nUser=" . exec('whoami'); $s .= "\nGroup=" . exec("groups | awk '{print $1}'"); $s .= "\nWorkingDirectory=" . getcwd(); global $argv; $s .= "\nExecStart=" . PHP_BINARY . " {$argv[0]} server"; $s .= "\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\n"; - @mkdir(getcwd() . "/resources/"); - file_put_contents(ZMConfig::get("global", "zm_data") . "zhamao.service", $s); - return ZMConfig::get("global", "zm_data") . "zhamao.service"; + @mkdir(getcwd() . '/resources/'); + file_put_contents(ZMConfig::get('global', 'zm_data') . 'zhamao.service', $s); + return ZMConfig::get('global', 'zm_data') . 'zhamao.service'; } } diff --git a/src/ZM/Command/InitCommand.php b/src/ZM/Command/InitCommand.php index ab6aa75d..3a25c57c 100644 --- a/src/ZM/Command/InitCommand.php +++ b/src/ZM/Command/InitCommand.php @@ -1,5 +1,6 @@ setDescription("Initialize framework starter | 初始化框架运行的基础文件"); + private $extract_files = [ + '/zhamao', + '/config/global.php', + '/.gitignore', + '/config/file_header.json', + '/config/console_color.json', + '/config/motd.txt', + '/src/Module/Example/Hello.php', + '/src/Module/Middleware/TimerMiddleware.php', + '/src/Custom/global_function.php', + ]; + + protected function configure() + { + $this->setDescription('Initialize framework starter | 初始化框架运行的基础文件'); $this->setDefinition([ - new InputOption("force", "F", null, "强制重制,覆盖现有文件") + new InputOption('force', 'F', null, '强制重制,覆盖现有文件'), ]); $this->setHelp("此命令将会解压以下文件到项目的根目录:\n" . implode("\n", $this->getExtractFiles())); // ... } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { if (LOAD_MODE === 1) { // 从composer依赖而来的项目模式,最基本的需要初始化的模式 - $output->writeln("Initializing files"); + $output->writeln('Initializing files'); $base_path = WORKING_DIR; - $args = $input->getOption("force"); + $args = $input->getOption('force'); foreach ($this->extract_files as $file) { if (!file_exists($base_path . $file) || $args) { $info = pathinfo($file); - @mkdir($base_path . $info["dirname"], 0777, true); - echo "Copying " . $file . PHP_EOL; - $package_name = (json_decode(file_get_contents(__DIR__ . "/../../../composer.json"), true)["name"]); - copy($base_path . "/vendor/" . $package_name . $file, $base_path . $file); + @mkdir($base_path . $info['dirname'], 0777, true); + echo 'Copying ' . $file . PHP_EOL; + $package_name = (json_decode(file_get_contents(__DIR__ . '/../../../composer.json'), true)['name']); + copy($base_path . '/vendor/' . $package_name . $file, $base_path . $file); } else { - echo "Skipping " . $file . " , file exists." . PHP_EOL; + echo 'Skipping ' . $file . ' , file exists.' . PHP_EOL; } } - chmod($base_path . "/zhamao", 0755); + chmod($base_path . '/zhamao', 0755); $autoload = [ - "psr-4" => [ - "Module\\" => "src/Module", - "Custom\\" => "src/Custom" + 'psr-4' => [ + 'Module\\' => 'src/Module', + 'Custom\\' => 'src/Custom', + ], + 'files' => [ + 'src/Custom/global_function.php', ], - "files" => [ - "src/Custom/global_function.php" - ] ]; - if (file_exists($base_path . "/composer.json")) { - $composer = json_decode(file_get_contents($base_path . "/composer.json"), true); - if (!isset($composer["autoload"])) { - $composer["autoload"] = $autoload; + if (file_exists($base_path . '/composer.json')) { + $composer = json_decode(file_get_contents($base_path . '/composer.json'), true); + if (!isset($composer['autoload'])) { + $composer['autoload'] = $autoload; } else { - foreach ($autoload["psr-4"] as $k => $v) { - if (!isset($composer["autoload"]["psr-4"][$k])) $composer["autoload"]["psr-4"][$k] = $v; + foreach ($autoload['psr-4'] as $k => $v) { + if (!isset($composer['autoload']['psr-4'][$k])) { + $composer['autoload']['psr-4'][$k] = $v; + } } - foreach ($autoload["files"] as $v) { - if (!in_array($v, $composer["autoload"]["files"])) $composer["autoload"]["files"][] = $v; + foreach ($autoload['files'] as $v) { + if (!in_array($v, $composer['autoload']['files'])) { + $composer['autoload']['files'][] = $v; + } } } - file_put_contents($base_path . "/composer.json", json_encode($composer, 64 | 128 | 256)); - $output->writeln("Executing composer command: `composer dump-autoload`"); - exec("composer dump-autoload"); + file_put_contents($base_path . '/composer.json', json_encode($composer, 64 | 128 | 256)); + $output->writeln('Executing composer command: `composer dump-autoload`'); + exec('composer dump-autoload'); echo PHP_EOL; } else { - echo(zm_internal_errcode("E00041") . "Error occurred. Please check your updates.\n"); + echo zm_internal_errcode('E00041') . "Error occurred. Please check your updates.\n"; return 1; } - $output->writeln("Done!"); + $output->writeln('Done!'); return 0; - } elseif (LOAD_MODE === 2) { //从phar启动的框架包,初始化的模式 + } + if (LOAD_MODE === 2) { //从phar启动的框架包,初始化的模式 $phar_link = new Phar(__DIR__); - $current_dir = pathinfo($phar_link->getPath())["dirname"]; + $current_dir = pathinfo($phar_link->getPath())['dirname']; chdir($current_dir); - $phar_link = "phar://" . $phar_link->getPath(); + $phar_link = 'phar://' . $phar_link->getPath(); foreach ($this->extract_files as $file) { if (!file_exists($current_dir . $file)) { $info = pathinfo($file); - @mkdir($current_dir . $info["dirname"], 0777, true); - echo "Copying " . $file . PHP_EOL; + @mkdir($current_dir . $info['dirname'], 0777, true); + echo 'Copying ' . $file . PHP_EOL; file_put_contents($current_dir . $file, file_get_contents($phar_link . $file)); } else { - echo "Skipping " . $file . " , file exists." . PHP_EOL; + echo 'Skipping ' . $file . ' , file exists.' . PHP_EOL; } } } - $output->writeln(zm_internal_errcode("E00042") . "initialization must be started with composer-project mode!"); + $output->writeln(zm_internal_errcode('E00042') . 'initialization must be started with composer-project mode!'); return 1; } - private function getExtractFiles(): array { + private function getExtractFiles(): array + { return $this->extract_files; } } diff --git a/src/ZM/Command/Module/ModuleListCommand.php b/src/ZM/Command/Module/ModuleListCommand.php index 0ac5f9b8..c6e9dc08 100644 --- a/src/ZM/Command/Module/ModuleListCommand.php +++ b/src/ZM/Command/Module/ModuleListCommand.php @@ -1,9 +1,9 @@ setDescription("查看所有模块信息"); - $this->setHelp("此功能将会把炸毛框架的模块列举出来。"); + protected function configure() + { + $this->setDescription('查看所有模块信息'); + $this->setHelp('此功能将会把炸毛框架的模块列举出来。'); // ... } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config'); - ZMConfig::setEnv($args["env"] ?? ""); - if (ZMConfig::get("global") === false) { - die (zm_internal_errcode("E00007") . "Global config load failed: " . ZMConfig::$last_error . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"); + ZMConfig::setEnv($args['env'] ?? ''); + if (ZMConfig::get('global') === false) { + exit(zm_internal_errcode('E00007') . 'Global config load failed: ' . ZMConfig::$last_error . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"); } //定义常量 /** @noinspection PhpIncludeInspection */ - include_once DataProvider::getFrameworkRootDir() . "/src/ZM/global_defines.php"; + include_once DataProvider::getFrameworkRootDir() . '/src/ZM/global_defines.php'; Console::init( - ZMConfig::get("global", "info_level") ?? 2, + ZMConfig::get('global', 'info_level') ?? 2, null, - $args["log-theme"] ?? "default", - ($o = ZMConfig::get("console_color")) === false ? [] : $o + $args['log-theme'] ?? 'default', + ($o = ZMConfig::get('console_color')) === false ? [] : $o ); - $timezone = ZMConfig::get("global", "timezone") ?? "Asia/Shanghai"; + $timezone = ZMConfig::get('global', 'timezone') ?? 'Asia/Shanghai'; date_default_timezone_set($timezone); $list = ModuleManager::getConfiguredModules(); foreach ($list as $v) { - echo "[" . Console::setColor($v["name"], "green") . "]" . PHP_EOL; - $out_list = ["类型" => "源码(source)"]; - if (isset($v["version"])) $out_list["版本"] = $v["version"]; - if (isset($v["description"])) $out_list["描述"] = $v["description"]; - $out_list["目录"] = str_replace(DataProvider::getSourceRootDir() . "/", "", $v["module-path"]); + echo '[' . Console::setColor($v['name'], 'green') . ']' . PHP_EOL; + $out_list = ['类型' => '源码(source)']; + if (isset($v['version'])) { + $out_list['版本'] = $v['version']; + } + if (isset($v['description'])) { + $out_list['描述'] = $v['description']; + } + $out_list['目录'] = str_replace(DataProvider::getSourceRootDir() . '/', '', $v['module-path']); $this->printList($out_list); } if ($list === []) { - echo Console::setColor("没有发现已编写打包配置文件(zm.json)的模块!", "yellow") . PHP_EOL; + echo Console::setColor('没有发现已编写打包配置文件(zm.json)的模块!', 'yellow') . PHP_EOL; } $list = ModuleManager::getPackedModules(); foreach ($list as $v) { - echo "[" . Console::setColor($v["name"], "gold") . "]" . PHP_EOL; - $out_list = ["类型" => "模块包(phar)"]; - if (isset($v["module-config"]["version"])) $out_list["版本"] = $v["module-config"]["version"]; - if (isset($v["module-config"]["description"])) $out_list["描述"] = $v["module-config"]["description"]; - $out_list["位置"] = str_replace(DataProvider::getSourceRootDir() . "/", "", $v["phar-path"]); + echo '[' . Console::setColor($v['name'], 'gold') . ']' . PHP_EOL; + $out_list = ['类型' => '模块包(phar)']; + if (isset($v['module-config']['version'])) { + $out_list['版本'] = $v['module-config']['version']; + } + if (isset($v['module-config']['description'])) { + $out_list['描述'] = $v['module-config']['description']; + } + $out_list['位置'] = str_replace(DataProvider::getSourceRootDir() . '/', '', $v['phar-path']); $this->printList($out_list); } if ($list === []) { - echo Console::setColor("没有发现已打包且装载的模块!", "yellow") . PHP_EOL; + echo Console::setColor('没有发现已打包且装载的模块!', 'yellow') . PHP_EOL; } return 0; } - private function printList($list) { + private function printList($list) + { foreach ($list as $k => $v) { - echo "\t" . $k . ": " . Console::setColor($v, "yellow") . PHP_EOL; + echo "\t" . $k . ': ' . Console::setColor($v, 'yellow') . PHP_EOL; } } -} \ No newline at end of file +} diff --git a/src/ZM/Command/Module/ModulePackCommand.php b/src/ZM/Command/Module/ModulePackCommand.php index ba40d617..80840b2b 100644 --- a/src/ZM/Command/Module/ModulePackCommand.php +++ b/src/ZM/Command/Module/ModulePackCommand.php @@ -1,9 +1,9 @@ addArgument("module-name", InputArgument::REQUIRED); - $this->setDescription("将配置好的模块构建一个phar包"); - $this->setHelp("此功能将会把炸毛框架的模块打包为\".phar\",供发布和执行。"); - $this->addOption("target", "D", InputOption::VALUE_REQUIRED, "Output Directory | 指定输出目录"); + protected function configure() + { + $this->addArgument('module-name', InputArgument::REQUIRED); + $this->setDescription('将配置好的模块构建一个phar包'); + $this->setHelp('此功能将会把炸毛框架的模块打包为".phar",供发布和执行。'); + $this->addOption('target', 'D', InputOption::VALUE_REQUIRED, 'Output Directory | 指定输出目录'); // ... } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config'); - ZMConfig::setEnv($args["env"] ?? ""); - if (ZMConfig::get("global") === false) { - die (zm_internal_errcode("E00007") . "Global config load failed: " . ZMConfig::$last_error . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"); + ZMConfig::setEnv($args['env'] ?? ''); + if (ZMConfig::get('global') === false) { + exit(zm_internal_errcode('E00007') . 'Global config load failed: ' . ZMConfig::$last_error . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"); } //定义常量 - include_once DataProvider::getFrameworkRootDir()."/src/ZM/global_defines.php"; + include_once DataProvider::getFrameworkRootDir() . '/src/ZM/global_defines.php'; Console::init( - ZMConfig::get("global", "info_level") ?? 2, + ZMConfig::get('global', 'info_level') ?? 2, null, - $args["log-theme"] ?? "default", - ($o = ZMConfig::get("console_color")) === false ? [] : $o + $args['log-theme'] ?? 'default', + ($o = ZMConfig::get('console_color')) === false ? [] : $o ); - $timezone = ZMConfig::get("global", "timezone") ?? "Asia/Shanghai"; + $timezone = ZMConfig::get('global', 'timezone') ?? 'Asia/Shanghai'; date_default_timezone_set($timezone); $list = ModuleManager::getConfiguredModules(); - if (!isset($list[$input->getArgument("module-name")])) { - $output->writeln("不存在模块 ".$input->getArgument("module-name")." !"); + if (!isset($list[$input->getArgument('module-name')])) { + $output->writeln('不存在模块 ' . $input->getArgument('module-name') . ' !'); return 1; } - $result = ModuleManager::packModule($list[$input->getArgument("module-name")], $input->getOption("target")); - if ($result) Console::success("打包完成!"); - else Console::error("打包失败!"); + $result = ModuleManager::packModule($list[$input->getArgument('module-name')], $input->getOption('target')); + if ($result) { + Console::success('打包完成!'); + } else { + Console::error('打包失败!'); + } return 0; } -} \ No newline at end of file +} diff --git a/src/ZM/Command/Module/ModuleUnpackCommand.php b/src/ZM/Command/Module/ModuleUnpackCommand.php index f7d55df1..190c6b23 100644 --- a/src/ZM/Command/Module/ModuleUnpackCommand.php +++ b/src/ZM/Command/Module/ModuleUnpackCommand.php @@ -1,9 +1,9 @@ setDefinition([ - new InputArgument("module-name", InputArgument::REQUIRED), - new InputOption("overwrite-light-cache", null, null, "覆盖现有的LightCache项目"), - new InputOption("overwrite-zm-data", null, null, "覆盖现有的zm_data文件"), - new InputOption("overwrite-source", null, null, "覆盖现有的源码文件"), - new InputOption("ignore-depends", null, null, "解包时忽略检查依赖") + new InputArgument('module-name', InputArgument::REQUIRED), + new InputOption('overwrite-light-cache', null, null, '覆盖现有的LightCache项目'), + new InputOption('overwrite-zm-data', null, null, '覆盖现有的zm_data文件'), + new InputOption('overwrite-source', null, null, '覆盖现有的源码文件'), + new InputOption('ignore-depends', null, null, '解包时忽略检查依赖'), ]); - $this->setDescription("解包一个phar模块到src目录"); - $this->setHelp("此功能将phar格式的模块包解包到src目录下。"); + $this->setDescription('解包一个phar模块到src目录'); + $this->setHelp('此功能将phar格式的模块包解包到src目录下。'); // ... } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config'); - ZMConfig::setEnv($args["env"] ?? ""); - if (ZMConfig::get("global") === false) { - die (zm_internal_errcode("E00007") . "Global config load failed: " . ZMConfig::$last_error . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"); + ZMConfig::setEnv($args['env'] ?? ''); + if (ZMConfig::get('global') === false) { + exit(zm_internal_errcode('E00007') . 'Global config load failed: ' . ZMConfig::$last_error . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"); } //定义常量 /** @noinspection PhpIncludeInspection */ - include_once DataProvider::getFrameworkRootDir()."/src/ZM/global_defines.php"; + include_once DataProvider::getFrameworkRootDir() . '/src/ZM/global_defines.php'; Console::init( - ZMConfig::get("global", "info_level") ?? 4, + ZMConfig::get('global', 'info_level') ?? 4, null, - $args["log-theme"] ?? "default", - ($o = ZMConfig::get("console_color")) === false ? [] : $o + $args['log-theme'] ?? 'default', + ($o = ZMConfig::get('console_color')) === false ? [] : $o ); - $timezone = ZMConfig::get("global", "timezone") ?? "Asia/Shanghai"; + $timezone = ZMConfig::get('global', 'timezone') ?? 'Asia/Shanghai'; date_default_timezone_set($timezone); $list = ModuleManager::getPackedModules(); - if (!isset($list[$input->getArgument("module-name")])) { - $output->writeln("不存在打包的模块 ".$input->getArgument("module-name")." !"); + if (!isset($list[$input->getArgument('module-name')])) { + $output->writeln('不存在打包的模块 ' . $input->getArgument('module-name') . ' !'); return 1; } - $result = ModuleManager::unpackModule($list[$input->getArgument("module-name")], $input->getOptions()); - if ($result) Console::success("解压完成!"); - else Console::error("解压失败!"); + $result = ModuleManager::unpackModule($list[$input->getArgument('module-name')], $input->getOptions()); + if ($result) { + Console::success('解压完成!'); + } else { + Console::error('解压失败!'); + } return 0; } -} \ No newline at end of file +} diff --git a/src/ZM/Command/PureHttpCommand.php b/src/ZM/Command/PureHttpCommand.php index cb4c6f38..e41c0c58 100644 --- a/src/ZM/Command/PureHttpCommand.php +++ b/src/ZM/Command/PureHttpCommand.php @@ -1,9 +1,9 @@ setDescription("Run a simple http server | 启动一个简单的文件 HTTP 服务器"); - $this->setHelp("直接运行可以启动"); + protected function configure() + { + $this->setDescription('Run a simple http server | 启动一个简单的文件 HTTP 服务器'); + $this->setHelp('直接运行可以启动'); $this->addArgument('dir', InputArgument::REQUIRED, 'Your directory'); - $this->addOption("host", 'H', InputOption::VALUE_REQUIRED, "启动监听地址"); - $this->addOption("port", 'P', InputOption::VALUE_REQUIRED, "启动监听地址的端口"); + $this->addOption('host', 'H', InputOption::VALUE_REQUIRED, '启动监听地址'); + $this->addOption('port', 'P', InputOption::VALUE_REQUIRED, '启动监听地址的端口'); // ... } - protected function execute(InputInterface $input, OutputInterface $output): int { - $tty_width = explode(" ", trim(exec("stty size")))[1]; + protected function execute(InputInterface $input, OutputInterface $output): int + { + $tty_width = explode(' ', trim(exec('stty size')))[1]; if (realpath($input->getArgument('dir') ?? '.') === false) { - $output->writeln("Directory error(" . ($input->getArgument('dir') ?? '.') . "): no such file or directory."); + $output->writeln('Directory error(' . ($input->getArgument('dir') ?? '.') . '): no such file or directory.'); return self::FAILURE; } ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config'); - $global = ZMConfig::get("global"); - $host = $input->getOption("host") ?? $global["host"]; - $port = $input->getOption("port") ?? $global["port"]; + $global = ZMConfig::get('global'); + $host = $input->getOption('host') ?? $global['host']; + $port = $input->getOption('port') ?? $global['port']; - $index = ["index.html", "index.htm"]; + $index = ['index.html', 'index.htm']; $out = [ - "listen" => $host.":".$port, - "version" => ZM_VERSION, - "web_root" => realpath($input->getArgument('dir') ?? '.'), - "index" => implode(",", $index) + 'listen' => $host . ':' . $port, + 'version' => ZM_VERSION, + 'web_root' => realpath($input->getArgument('dir') ?? '.'), + 'index' => implode(',', $index), ]; Framework::printProps($out, $tty_width); $server = new Server($host, $port); - $server->set(ZMConfig::get("global", "swoole")); + $server->set(ZMConfig::get('global', 'swoole')); Console::init(2, $server); - ZMAtomic::$atomics["request"] = []; + ZMAtomic::$atomics['request'] = []; for ($i = 0; $i < 32; ++$i) { - ZMAtomic::$atomics["request"][$i] = new Atomic(0); + ZMAtomic::$atomics['request'][$i] = new Atomic(0); } - $server->on("request", function (Request $request, Response $response) use ($input, $index, $server) { - ZMAtomic::$atomics["request"][$server->worker_id]->add(1); + $server->on('request', function (Request $request, Response $response) use ($input, $index, $server) { + ZMAtomic::$atomics['request'][$server->worker_id]->add(1); HttpUtil::handleStaticPage( - $request->server["request_uri"], + $request->server['request_uri'], $response, [ - "document_root" => realpath($input->getArgument('dir') ?? '.'), - "document_index" => $index - ]); + 'document_root' => realpath($input->getArgument('dir') ?? '.'), + 'document_index' => $index, + ] + ); //echo "\r" . Coroutine::stats()["coroutine_peak_num"]; }); - $server->on("start", function ($server) { + $server->on('start', function ($server) { Process::signal(SIGINT, function () use ($server) { echo "\r"; - Console::warning("Server interrupted by keyboard."); + Console::warning('Server interrupted by keyboard.'); for ($i = 0; $i < 32; ++$i) { - $num = ZMAtomic::$atomics["request"][$i]->get(); - if ($num != 0) - echo "[$i]: " . $num . "\n"; + $num = ZMAtomic::$atomics['request'][$i]->get(); + if ($num != 0) { + echo "[{$i}]: " . $num . "\n"; + } } $server->shutdown(); $server->stop(); }); - Console::success("Server started. Use Ctrl+C to stop."); + Console::success('Server started. Use Ctrl+C to stop.'); }); $server->start(); // return this if there was no problem running the command // (it's equivalent to returning int(0)) return 0; - // or return this if some error happened during the execution // (it's equivalent to returning int(1)) // return 1; diff --git a/src/ZM/Command/RunServerCommand.php b/src/ZM/Command/RunServerCommand.php index d3a59f7c..43eea118 100644 --- a/src/ZM/Command/RunServerCommand.php +++ b/src/ZM/Command/RunServerCommand.php @@ -1,5 +1,6 @@ setAliases(['server:start']); - $this->setDefinition([ - new InputOption("debug-mode", "D", null, "开启调试模式 (这将关闭协程化)"), - new InputOption("log-debug", null, null, "调整消息等级到debug (log-level=4)"), - new InputOption("log-verbose", null, null, "调整消息等级到verbose (log-level=3)"), - new InputOption("log-info", null, null, "调整消息等级到info (log-level=2)"), - new InputOption("log-warning", null, null, "调整消息等级到warning (log-level=1)"), - new InputOption("log-error", null, null, "调整消息等级到error (log-level=0)"), - new InputOption("log-theme", null, InputOption::VALUE_REQUIRED, "改变终端的主题配色"), - new InputOption("disable-console-input", null, null, "禁止终端输入内容 (废弃)"), - new InputOption("interact", null, null, "打开终端输入"), - new InputOption("remote-terminal", null, null, "启用远程终端,配置使用global.php中的"), - new InputOption("disable-coroutine", null, null, "关闭协程Hook"), - new InputOption("daemon", null, null, "以守护进程的方式运行框架"), - new InputOption("worker-num", null, InputOption::VALUE_REQUIRED, "启动框架时运行的 Worker 进程数量"), - new InputOption("task-worker-num", null, InputOption::VALUE_REQUIRED, "启动框架时运行的 TaskWorker 进程数量"), - new InputOption("watch", null, null, "监听 src/ 目录的文件变化并热更新"), - new InputOption("show-php-ver", null, null, "启动时显示PHP和Swoole版本"), - new InputOption("env", null, InputOption::VALUE_REQUIRED, "设置环境类型 (production, development, staging)"), - new InputOption("disable-safe-exit", null, null, "关闭安全退出(关闭后按CtrlC时直接杀死进程)"), - new InputOption("preview", null, null, "只显示参数,不启动服务器"), - new InputOption("force-load-module", null, InputOption::VALUE_OPTIONAL, "强制打包状态下加载模块(使用英文逗号分割多个)"), - new InputOption("polling-watch", null, null, "强制启用轮询模式监听"), - ]); - $this->setDescription("Run zhamao-framework | 启动框架"); - $this->setHelp("直接运行可以启动"); + public static function exportDefinition() + { + $cmd = new self(); + $cmd->configure(); + return $cmd->getDefinition(); } - protected function execute(InputInterface $input, OutputInterface $output): int { - if (($opt = $input->getOption("env")) !== null) { - if (!in_array($opt, ["production", "staging", "development", ""])) { - $output->writeln(" \"--env\" option only accept production, development, staging and [empty] ! "); + protected function configure() + { + $this->setAliases(['server:start']); + $this->setDefinition([ + new InputOption('debug-mode', 'D', null, '开启调试模式 (这将关闭协程化)'), + new InputOption('log-debug', null, null, '调整消息等级到debug (log-level=4)'), + new InputOption('log-verbose', null, null, '调整消息等级到verbose (log-level=3)'), + new InputOption('log-info', null, null, '调整消息等级到info (log-level=2)'), + new InputOption('log-warning', null, null, '调整消息等级到warning (log-level=1)'), + new InputOption('log-error', null, null, '调整消息等级到error (log-level=0)'), + new InputOption('log-theme', null, InputOption::VALUE_REQUIRED, '改变终端的主题配色'), + new InputOption('disable-console-input', null, null, '禁止终端输入内容 (废弃)'), + new InputOption('interact', null, null, '打开终端输入'), + new InputOption('remote-terminal', null, null, '启用远程终端,配置使用global.php中的'), + new InputOption('disable-coroutine', null, null, '关闭协程Hook'), + new InputOption('daemon', null, null, '以守护进程的方式运行框架'), + new InputOption('worker-num', null, InputOption::VALUE_REQUIRED, '启动框架时运行的 Worker 进程数量'), + new InputOption('task-worker-num', null, InputOption::VALUE_REQUIRED, '启动框架时运行的 TaskWorker 进程数量'), + new InputOption('watch', null, null, '监听 src/ 目录的文件变化并热更新'), + new InputOption('show-php-ver', null, null, '启动时显示PHP和Swoole版本'), + new InputOption('env', null, InputOption::VALUE_REQUIRED, '设置环境类型 (production, development, staging)'), + new InputOption('disable-safe-exit', null, null, '关闭安全退出(关闭后按CtrlC时直接杀死进程)'), + new InputOption('preview', null, null, '只显示参数,不启动服务器'), + new InputOption('force-load-module', null, InputOption::VALUE_OPTIONAL, '强制打包状态下加载模块(使用英文逗号分割多个)'), + new InputOption('polling-watch', null, null, '强制启用轮询模式监听'), + ]); + $this->setDescription('Run zhamao-framework | 启动框架'); + $this->setHelp('直接运行可以启动'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + if (($opt = $input->getOption('env')) !== null) { + if (!in_array($opt, ['production', 'staging', 'development', ''])) { + $output->writeln(' "--env" option only accept production, development, staging and [empty] ! '); return 1; } } $state = Framework::getProcessState(ZM_PROCESS_MASTER); if (is_array($state) && posix_getsid($state['pid'] ?? -1) !== false) { $output->writeln("检测到已经在 pid: {$state['pid']} 进程启动了框架!"); - $output->writeln("不可以同时启动两个框架!"); + $output->writeln('不可以同时启动两个框架!'); return 1; } (new Framework($input->getOptions()))->start(); return 0; } - - public static function exportDefinition() { - $cmd = new self(); - $cmd->configure(); - return $cmd->getDefinition(); - } } diff --git a/src/ZM/Command/Server/ServerReloadCommand.php b/src/ZM/Command/Server/ServerReloadCommand.php index 7885949c..8d87503c 100644 --- a/src/ZM/Command/Server/ServerReloadCommand.php +++ b/src/ZM/Command/Server/ServerReloadCommand.php @@ -1,5 +1,6 @@ setDescription("重载框架"); + protected function configure() + { + $this->setDescription('重载框架'); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { parent::execute($input, $output); - Process::kill(intval($this->daemon_file["pid"]), SIGUSR1); - $output->writeln("成功重载!"); + Process::kill(intval($this->daemon_file['pid']), SIGUSR1); + $output->writeln('成功重载!'); return 0; } } diff --git a/src/ZM/Command/Server/ServerStatusCommand.php b/src/ZM/Command/Server/ServerStatusCommand.php index 21838fe0..d3abb6ff 100644 --- a/src/ZM/Command/Server/ServerStatusCommand.php +++ b/src/ZM/Command/Server/ServerStatusCommand.php @@ -1,5 +1,7 @@ setDescription("查看框架的运行状态"); + protected function configure() + { + $this->setDescription('查看框架的运行状态'); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { parent::execute($input, $output); - $output->writeln("框架" . ($this->daemon_file["daemon"] ? "以守护进程模式" : "") . "运行中,pid:" . $this->daemon_file["pid"] . ""); - if ($this->daemon_file["daemon"]) { - $output->writeln("----- 以下是stdout内容 -----"); - $stdout = file_get_contents($this->daemon_file["stdout"]); + $output->writeln('框架' . ($this->daemon_file['daemon'] ? '以守护进程模式' : '') . '运行中,pid:' . $this->daemon_file['pid'] . ''); + if ($this->daemon_file['daemon']) { + $output->writeln('----- 以下是stdout内容 -----'); + $stdout = file_get_contents($this->daemon_file['stdout']); $stdout = explode("\n", $stdout); for ($i = 15; $i > 0; --$i) { - if (isset($stdout[count($stdout) - $i])) + if (isset($stdout[count($stdout) - $i])) { echo $stdout[count($stdout) - $i] . PHP_EOL; + } } } return 0; } } -{ - -} \ No newline at end of file diff --git a/src/ZM/Command/Server/ServerStopCommand.php b/src/ZM/Command/Server/ServerStopCommand.php index 8fc48459..233fe6de 100644 --- a/src/ZM/Command/Server/ServerStopCommand.php +++ b/src/ZM/Command/Server/ServerStopCommand.php @@ -1,5 +1,6 @@ setDescription("停止运行的框架"); + protected function configure() + { + $this->setDescription('停止运行的框架'); $this->setDefinition([ new InputOption('force', 'f', InputOption::VALUE_NONE, '强制停止'), ]); } - protected function execute(InputInterface $input, OutputInterface $output): int { + protected function execute(InputInterface $input, OutputInterface $output): int + { if ($input->getOption('force') !== false) { $file_path = _zm_pid_dir(); $list = DataProvider::scanDirFiles($file_path, false, true); - foreach($list as $file) { + foreach ($list as $file) { $name = explode('.', $file); if (end($name) == 'pid') { - $pid = file_get_contents($file_path.'/'.$file); + $pid = file_get_contents($file_path . '/' . $file); Process::kill($pid, SIGKILL); } elseif ($file === 'master.json') { - $json = json_decode(file_get_contents($file_path.'/'.$file), true); + $json = json_decode(file_get_contents($file_path . '/' . $file), true); Process::kill($json['pid'], SIGKILL); } - unlink($file_path.'/'.$file); + unlink($file_path . '/' . $file); } } else { parent::execute($input, $output); } - Process::kill(intval($this->daemon_file["pid"]), SIGTERM); + Process::kill(intval($this->daemon_file['pid']), SIGTERM); $i = 10; while (Framework::getProcessState(ZM_PROCESS_MASTER) !== false && $i > 0) { sleep(1); --$i; } if ($i === 0) { - $output->writeln("停止失败,请检查进程pid #" . $this->daemon_file["pid"] . " 是否响应!"); - $output->writeln("或者可以尝试使用参数 --force 来强行杀死所有进程"); + $output->writeln('停止失败,请检查进程pid #' . $this->daemon_file['pid'] . ' 是否响应!'); + $output->writeln('或者可以尝试使用参数 --force 来强行杀死所有进程'); } else { - $output->writeln("成功停止!"); + $output->writeln('成功停止!'); } return 0; } diff --git a/src/ZM/ConsoleApplication.php b/src/ZM/ConsoleApplication.php index a6e9302f..3d43ba0d 100644 --- a/src/ZM/ConsoleApplication.php +++ b/src/ZM/ConsoleApplication.php @@ -1,11 +1,14 @@ addCommands([ @@ -88,12 +92,12 @@ class ConsoleApplication extends Application new ServerStopCommand(), new ServerReloadCommand(), new PureHttpCommand(), //纯HTTP服务器指令 - new SystemdGenerateCommand() + new SystemdGenerateCommand(), ]); if (LOAD_MODE === 1) { $this->add(new CheckConfigCommand()); } - if (Phar::running() === "") { + if (Phar::running() === '') { $this->add(new BuildCommand()); $this->add(new InitCommand()); $this->add(new ModulePackCommand()); @@ -106,16 +110,13 @@ class ConsoleApplication extends Application return $this; } - /** - * @param InputInterface|null $input - * @param OutputInterface|null $output - * @return int - */ - public function run(InputInterface $input = null, OutputInterface $output = null): int { + public function run(InputInterface $input = null, OutputInterface $output = null): int + { try { return parent::run($input, $output); } catch (Exception $e) { - die(zm_internal_errcode("E00005") . "{$e->getMessage()} at {$e->getFile()}({$e->getLine()})"); + echo zm_internal_errcode('E00005') . "{$e->getMessage()} at {$e->getFile()}({$e->getLine()})" . PHP_EOL; + exit(1); } } } diff --git a/src/ZM/Context/Context.php b/src/ZM/Context/Context.php index b4a4b67b..248e15ec 100644 --- a/src/ZM/Context/Context.php +++ b/src/ZM/Context/Context.php @@ -1,14 +1,15 @@ cid = $cid; } + public function __construct($cid) + { + $this->cid = $cid; + } /** * @return Server */ - public function getServer(): ?Server { return self::$context[$this->cid]["server"] ?? server(); } + public function getServer(): ?Server + { + return self::$context[$this->cid]['server'] ?? server(); + } - /** - * @return Frame|null - */ - public function getFrame(): ?Frame { return self::$context[$this->cid]["frame"] ?? null; } + public function getFrame(): ?Frame + { + return self::$context[$this->cid]['frame'] ?? null; + } - public function getFd(): ?int { return self::$context[$this->cid]["fd"] ?? $this->getFrame()->fd ?? null; } + public function getFd(): ?int + { + return self::$context[$this->cid]['fd'] ?? $this->getFrame()->fd ?? null; + } /** * @return mixed */ - public function getData() { return self::$context[$this->cid]["data"] ?? null; } + public function getData() + { + return self::$context[$this->cid]['data'] ?? null; + } - public function setData($data) { self::$context[$this->cid]["data"] = $data; } + public function setData($data) + { + self::$context[$this->cid]['data'] = $data; + } - /** - * @return Request|null - */ - public function getRequest(): ?Request { return self::$context[$this->cid]["request"] ?? null; } + public function getRequest(): ?Request + { + return self::$context[$this->cid]['request'] ?? null; + } - /** - * @return Response|null - */ - public function getResponse(): ?Response { return self::$context[$this->cid]["response"] ?? null; } + public function getResponse(): ?Response + { + return self::$context[$this->cid]['response'] ?? null; + } - /** @return ConnectionObject|null */ - public function getConnection(): ?ConnectionObject { return ManagerGM::get($this->getFd()); } + public function getConnection(): ?ConnectionObject + { + return ManagerGM::get($this->getFd()); + } - /** - * @return int|null - */ - public function getCid(): ?int { return $this->cid; } + public function getCid(): ?int + { + return $this->cid; + } - /** - * @return ZMRobot|null - */ - public function getRobot(): ?ZMRobot { + public function getRobot(): ?ZMRobot + { $conn = ManagerGM::get($this->getFrame()->fd); return $conn instanceof ConnectionObject ? new ZMRobot($conn) : null; } - public function getMessage() { - if ((ZMConfig::get("global", "onebot")["message_convert_string"] ?? true) === true && is_array($msg = $this->getOriginMessage())) { + public function getMessage() + { + if ((ZMConfig::get('global', 'onebot')['message_convert_string'] ?? true) === true && is_array($msg = $this->getOriginMessage())) { return MessageUtil::arrayToStr($msg); - } else { - return self::$context[$this->cid]["data"]["message"] ?? null; } + return self::$context[$this->cid]['data']['message'] ?? null; } - public function setMessage($msg) { + public function setMessage($msg) + { if (is_string($msg) && is_array($this->getOriginMessage())) { $msg = MessageUtil::strToArray($msg); } - self::$context[$this->cid]["data"]["message"] = $msg; + self::$context[$this->cid]['data']['message'] = $msg; } - public function getUserId() { return $this->getData()["user_id"] ?? null; } + public function getUserId() + { + return $this->getData()['user_id'] ?? null; + } - public function setUserId($id) { self::$context[$this->cid]["data"]["user_id"] = $id; } + public function setUserId($id) + { + self::$context[$this->cid]['data']['user_id'] = $id; + } - public function getGroupId() { return $this->getData()["group_id"] ?? null; } + public function getGroupId() + { + return $this->getData()['group_id'] ?? null; + } - public function setGroupId($id) { self::$context[$this->cid]["data"]["group_id"] = $id; } + public function setGroupId($id) + { + self::$context[$this->cid]['data']['group_id'] = $id; + } - public function getDiscussId() { return $this->getData()["discuss_id"] ?? null; } + public function getDiscussId() + { + return $this->getData()['discuss_id'] ?? null; + } - public function setDiscussId($id) { self::$context[$this->cid]["data"]["discuss_id"] = $id; } + public function setDiscussId($id) + { + self::$context[$this->cid]['data']['discuss_id'] = $id; + } - public function getMessageType(): ?string { return $this->getData()["message_type"] ?? null; } + public function getMessageType(): ?string + { + return $this->getData()['message_type'] ?? null; + } - public function setMessageType($type) { self::$context[$this->cid]["data"]["message_type"] = $type; } + public function setMessageType($type) + { + self::$context[$this->cid]['data']['message_type'] = $type; + } - public function getRobotId() { return $this->getData()["self_id"] ?? null; } + public function getRobotId() + { + return $this->getData()['self_id'] ?? null; + } - public function getCache($key) { return self::$context[$this->cid]["cache"][$key] ?? null; } + public function getCache($key) + { + return self::$context[$this->cid]['cache'][$key] ?? null; + } - public function setCache($key, $value) { self::$context[$this->cid]["cache"][$key] = $value; } + public function setCache($key, $value) + { + self::$context[$this->cid]['cache'][$key] = $value; + } - public function getCQResponse() { return self::$context[$this->cid]["cq_response"] ?? null; } + public function getCQResponse() + { + return self::$context[$this->cid]['cq_response'] ?? null; + } /** * only can used by cq->message event function * @param $msg - * @param bool $yield + * @param bool $yield * @return array|bool */ - public function reply($msg, $yield = false) { + public function reply($msg, $yield = false) + { $data = $this->getData(); $conn = $this->getConnection(); if (!is_array($msg)) { - switch ($this->getData()["message_type"]) { - case "group": - case "private": - case "discuss": - $this->setCache("has_reply", true); - $operation["reply"] = $msg; - $operation["at_sender"] = false; - return (new ZMRobot($conn))->setCallback($yield)->callExtendedAPI(".handle_quick_operation", [ - "context" => $data, - "operation" => $operation + switch ($this->getData()['message_type']) { + case 'group': + case 'private': + case 'discuss': + $this->setCache('has_reply', true); + $operation['reply'] = $msg; + $operation['at_sender'] = false; + return (new ZMRobot($conn))->setCallback($yield)->callExtendedAPI('.handle_quick_operation', [ + 'context' => $data, + 'operation' => $operation, ]); } return false; - } else { - $operation = $msg; - return (new ZMRobot($conn))->setCallback(false)->callExtendedAPI(".handle_quick_operation", [ - "context" => $data, - "operation" => $operation - ]); } + $operation = $msg; + return (new ZMRobot($conn))->setCallback(false)->callExtendedAPI('.handle_quick_operation', [ + 'context' => $data, + 'operation' => $operation, + ]); } /** * @param $msg - * @param false $yield - * @return void + * @param bool $yield * @throws InterruptException */ - public function finalReply($msg, $yield = false) { - self::$context[$this->cid]["cache"]["block_continue"] = true; - if ($msg != "") $this->reply($msg, $yield); + public function finalReply($msg, $yield = false) + { + self::$context[$this->cid]['cache']['block_continue'] = true; + if ($msg != '') { + $this->reply($msg, $yield); + } EventDispatcher::interrupt(); } /** - * @param string $prompt - * @param int $timeout - * @param string $timeout_prompt - * @return string + * @param string $prompt + * @param int $timeout + * @param string $timeout_prompt * @throws InvalidArgumentException * @throws WaitTimeoutException + * @return string * @noinspection PhpMissingReturnTypeInspection */ - public function waitMessage($prompt = "", $timeout = 600, $timeout_prompt = "") { - if (!isset($this->getData()["user_id"], $this->getData()["message"], $this->getData()["self_id"])) - throw new InvalidArgumentException("协程等待参数缺失"); + public function waitMessage($prompt = '', $timeout = 600, $timeout_prompt = '') + { + if (!isset($this->getData()['user_id'], $this->getData()['message'], $this->getData()['self_id'])) { + throw new InvalidArgumentException('协程等待参数缺失'); + } - Console::debug("==== 开始等待输入 ===="); - if ($prompt != "") $this->reply($prompt); + Console::debug('==== 开始等待输入 ===='); + if ($prompt != '') { + $this->reply($prompt); + } try { - $r = CoMessage::yieldByWS($this->getData(), ["user_id", "self_id", "message_type", onebot_target_id_name($this->getMessageType())], $timeout); + $r = CoMessage::yieldByWS($this->getData(), ['user_id', 'self_id', 'message_type', onebot_target_id_name($this->getMessageType())], $timeout); } catch (Exception $e) { $r = false; } if ($r === false) { throw new WaitTimeoutException($this, $timeout_prompt); } - if (is_array($r["message"]) && (ZMConfig::get("global", "onebot")["message_convert_string"] ?? true) === true) { - return MessageUtil::arrayToStr($r["message"]); - } else { - return $r["message"]; + if (is_array($r['message']) && (ZMConfig::get('global', 'onebot')['message_convert_string'] ?? true) === true) { + return MessageUtil::arrayToStr($r['message']); } + return $r['message']; } /** * @param $mode * @param $prompt_msg - * @return mixed|string * @throws InvalidArgumentException * @throws WaitTimeoutException + * @return mixed|string */ - public function getArgs($mode, $prompt_msg) { - $arg = ctx()->getCache("match") ?? []; + public function getArgs($mode, $prompt_msg) + { + $arg = ctx()->getCache('match') ?? []; switch ($mode) { case ZM_MATCH_ALL: $p = $arg; - return trim(implode(" ", $p)) == "" ? $this->waitMessage($prompt_msg) : trim(implode(" ", $p)); + return trim(implode(' ', $p)) == '' ? $this->waitMessage($prompt_msg) : trim(implode(' ', $p)); case ZM_MATCH_NUMBER: foreach ($arg as $k => $v) { if (is_numeric($v)) { array_splice($arg, $k, 1); - ctx()->setCache("match", $arg); + ctx()->setCache('match', $arg); return $v; } } @@ -214,60 +273,84 @@ class Context implements ContextInterface if (isset($arg[0])) { $a = $arg[0]; array_splice($arg, 0, 1); - ctx()->setCache("match", $arg); + ctx()->setCache('match', $arg); return $a; - } else { - return $this->waitMessage($prompt_msg); } + return $this->waitMessage($prompt_msg); } throw new InvalidArgumentException(); } /** - * @param string $prompt_msg - * @return int|mixed|string + * @param string $prompt_msg * @throws InvalidArgumentException * @throws WaitTimeoutException + * @return int|mixed|string */ - public function getNextArg($prompt_msg = "") { return $this->getArgs(ZM_MATCH_FIRST, $prompt_msg); } + public function getNextArg($prompt_msg = '') + { + return $this->getArgs(ZM_MATCH_FIRST, $prompt_msg); + } /** - * @param string $prompt_msg - * @return int|mixed|string + * @param string $prompt_msg * @throws InvalidArgumentException * @throws WaitTimeoutException + * @return int|mixed|string */ - public function getFullArg($prompt_msg = "") { return $this->getArgs(ZM_MATCH_ALL, $prompt_msg); } + public function getFullArg($prompt_msg = '') + { + return $this->getArgs(ZM_MATCH_ALL, $prompt_msg); + } /** - * @param string $prompt_msg - * @return int|mixed|string + * @param string $prompt_msg * @throws InvalidArgumentException * @throws WaitTimeoutException + * @return int|mixed|string */ - public function getNumArg($prompt_msg = "") { return $this->getArgs(ZM_MATCH_NUMBER, $prompt_msg); } + public function getNumArg($prompt_msg = '') + { + return $this->getArgs(ZM_MATCH_NUMBER, $prompt_msg); + } /** @noinspection PhpMissingReturnTypeInspection */ - public function cloneFromParent() { + public function cloneFromParent() + { set_coroutine_params(self::$context[Coroutine::getPcid()] ?? self::$context[$this->cid]); return context(); } - public function copy() { return self::$context[$this->cid]; } - - public function getOption() { return self::getCache("match"); } - - public function getOriginMessage() { return self::$context[$this->cid]["data"]["message"] ?? null; } - - public function getArrayMessage(): array { - $msg = $this->getOriginMessage(); - if (is_array($msg)) return $msg; - else return MessageUtil::strToArray($msg); + public function copy() + { + return self::$context[$this->cid]; } - public function getStringMessage(): string { + public function getOption() + { + return self::getCache('match'); + } + + public function getOriginMessage() + { + return self::$context[$this->cid]['data']['message'] ?? null; + } + + public function getArrayMessage(): array + { $msg = $this->getOriginMessage(); - if (is_string($msg)) return $msg; - else return MessageUtil::arrayToStr($msg); + if (is_array($msg)) { + return $msg; + } + return MessageUtil::strToArray($msg); + } + + public function getStringMessage(): string + { + $msg = $this->getOriginMessage(); + if (is_string($msg)) { + return $msg; + } + return MessageUtil::arrayToStr($msg); } } diff --git a/src/ZM/Context/ContextInterface.php b/src/ZM/Context/ContextInterface.php index 8b7554d8..068be3d9 100644 --- a/src/ZM/Context/ContextInterface.php +++ b/src/ZM/Context/ContextInterface.php @@ -1,15 +1,15 @@ -fetchAllAssociative("select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=?;", [$db_name]); + public static function initTableList($db_name) + { + if (!extension_loaded('mysqlnd')) { + throw new DbException('Can not find mysqlnd PHP extension.'); + } + $result = MySQLManager::getWrapper()->fetchAllAssociative('select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=?;', [$db_name]); foreach ($result as $v) { self::$table_list[] = $v['TABLE_NAME']; } @@ -37,18 +41,18 @@ class DB /** * @param $table_name - * @return Table * @throws DbException */ - public static function table($table_name): Table { + public static function table($table_name): Table + { if (Table::getTableInstance($table_name) === null) { - if (in_array($table_name, self::$table_list)) + if (in_array($table_name, self::$table_list)) { return new Table($table_name); - elseif (SqlPoolStorage::$sql_pool !== null) { - throw new DbException("Table " . $table_name . " not exist in database."); - } else { - throw new DbException("Database connection not exist or connect failed. Please check sql configuration"); } + if (SqlPoolStorage::$sql_pool !== null) { + throw new DbException('Table ' . $table_name . ' not exist in database.'); + } + throw new DbException('Database connection not exist or connect failed. Please check sql configuration'); } return Table::getTableInstance($table_name); } @@ -57,23 +61,24 @@ class DB * @param $line * @throws DbException */ - public static function statement($line) { + public static function statement($line) + { self::rawQuery($line, []); } /** * @param $line - * @return bool * @throws DbException */ - public static function unprepared($line): bool { + public static function unprepared($line): bool + { try { $conn = SqlPoolStorage::$sql_pool->getConnection(); if ($conn === false) { SqlPoolStorage::$sql_pool->putConnection(null); - throw new DbException("无法连接SQL!" . $line); + throw new DbException('无法连接SQL!' . $line); } - $result = $conn->query($line) === false ? false : true; + $result = !($conn->query($line) === false); SqlPoolStorage::$sql_pool->putConnection($conn); return $result; } catch (DBException $e) { @@ -82,58 +87,58 @@ class DB } } - /** - * @param string $line - * @param array $params - * @param int $fetch_mode - * @return mixed - * @throws DbException - */ - public static function rawQuery(string $line, $params = [], $fetch_mode = ZM_DEFAULT_FETCH_MODE) { - if (!is_array($params)) $params = [$params]; - Console::debug("MySQL: " . $line . " | " . implode(", ", $params)); + public static function rawQuery(string $line, $params = [], $fetch_mode = ZM_DEFAULT_FETCH_MODE) + { + if (!is_array($params)) { + $params = [$params]; + } + Console::debug('MySQL: ' . $line . ' | ' . implode(', ', $params)); try { - if (SqlPoolStorage::$sql_pool === null) throw new DbException("未连接到任何数据库!"); + if (SqlPoolStorage::$sql_pool === null) { + throw new DbException('未连接到任何数据库!'); + } $conn = SqlPoolStorage::$sql_pool->getConnection(); if ($conn === false) { SqlPoolStorage::$sql_pool->putConnection(null); - throw new DbException("无法连接SQL!" . $line); + throw new DbException('无法连接SQL!' . $line); } $ps = $conn->prepare($line); if ($ps === false) { SqlPoolStorage::$sql_pool->putConnection(null); - /** @noinspection PhpUndefinedFieldInspection */ - throw new DbException("SQL语句查询错误," . $line . ",错误信息:" . $conn->error); - } else { - if (!($ps instanceof PDOStatement) && !($ps instanceof PDOStatementProxy)) { - var_dump($ps); - SqlPoolStorage::$sql_pool->putConnection(null); - throw new DbException("语句查询错误!返回的不是 PDOStatement" . $line); - } - if ($params == []) $result = $ps->execute(); - elseif (!is_array($params)) { - $result = $ps->execute([$params]); - } else $result = $ps->execute($params); - if ($result !== true) { - SqlPoolStorage::$sql_pool->putConnection(null); - throw new DBException("语句[$line]错误!" . $ps->errorInfo()[2]); - //echo json_encode(debug_backtrace(), 128 | 256); - } - SqlPoolStorage::$sql_pool->putConnection($conn); - return $ps->fetchAll($fetch_mode); + /* @noinspection PhpUndefinedFieldInspection */ + throw new DbException('SQL语句查询错误,' . $line . ',错误信息:' . $conn->error); } + if (!($ps instanceof PDOStatement) && !($ps instanceof PDOStatementProxy)) { + var_dump($ps); + SqlPoolStorage::$sql_pool->putConnection(null); + throw new DbException('语句查询错误!返回的不是 PDOStatement' . $line); + } + if ($params == []) { + $result = $ps->execute(); + } elseif (!is_array($params)) { + $result = $ps->execute([$params]); + } else { + $result = $ps->execute($params); + } + if ($result !== true) { + SqlPoolStorage::$sql_pool->putConnection(null); + throw new DBException("语句[{$line}]错误!" . $ps->errorInfo()[2]); + //echo json_encode(debug_backtrace(), 128 | 256); + } + SqlPoolStorage::$sql_pool->putConnection($conn); + return $ps->fetchAll($fetch_mode); } catch (DbException $e) { - if (mb_strpos($e->getMessage(), "has gone away") !== false) { + if (mb_strpos($e->getMessage(), 'has gone away') !== false) { zm_sleep(0.2); - Console::warning("Gone away of MySQL! retrying!"); + Console::warning('Gone away of MySQL! retrying!'); return self::rawQuery($line, $params); } Console::warning($e->getMessage()); throw $e; } catch (PDOException $e) { - if (mb_strpos($e->getMessage(), "has gone away") !== false) { + if (mb_strpos($e->getMessage(), 'has gone away') !== false) { zm_sleep(0.2); - Console::warning("Gone away of MySQL! retrying!"); + Console::warning('Gone away of MySQL! retrying!'); return self::rawQuery($line, $params); } Console::warning($e->getMessage()); @@ -141,7 +146,8 @@ class DB } } - public static function isTableExists($table): bool { + public static function isTableExists($table): bool + { return in_array($table, self::$table_list); } } diff --git a/src/ZM/DB/DeleteBody.php b/src/ZM/DB/DeleteBody.php index 61d95d1a..64a963bc 100644 --- a/src/ZM/DB/DeleteBody.php +++ b/src/ZM/DB/DeleteBody.php @@ -1,14 +1,13 @@ table = $table; } /** - * @return mixed * @throws DbException + * @return mixed */ - public function save() { - list($sql, $param) = $this->getWhereSQL(); - return DB::rawQuery("DELETE FROM " . $this->table->getTableName() . " WHERE " . $sql, $param); + public function save() + { + [$sql, $param] = $this->getWhereSQL(); + return DB::rawQuery('DELETE FROM ' . $this->table->getTableName() . ' WHERE ' . $sql, $param); } } diff --git a/src/ZM/DB/InsertBody.php b/src/ZM/DB/InsertBody.php index 4db10693..860f195a 100644 --- a/src/ZM/DB/InsertBody.php +++ b/src/ZM/DB/InsertBody.php @@ -1,14 +1,13 @@ table = $table; $this->row = $row; } @@ -32,7 +32,8 @@ class InsertBody /** * @throws DbException */ - public function save() { + public function save() + { DB::rawQuery('INSERT INTO ' . $this->table->getTableName() . ' VALUES (' . implode(',', array_fill(0, count($this->row), '?')) . ')', $this->row); } } diff --git a/src/ZM/DB/SelectBody.php b/src/ZM/DB/SelectBody.php index 863666c7..e324179f 100644 --- a/src/ZM/DB/SelectBody.php +++ b/src/ZM/DB/SelectBody.php @@ -1,14 +1,13 @@ table = $table; $this->select_thing = $select_thing; } /** - * @return null * @throws DbException */ - public function get() { return $this->fetchAll(); } - - /** - * @throws DbException - */ - public function count(): int { - $this->select_thing = ["count(*)"]; - $str = $this->queryPrepare(); - $this->result = DB::rawQuery($str[0], $str[1]); - return intval($this->result[0]["count(*)"]); + public function get() + { + return $this->fetchAll(); } /** - * @param int $fetch_mode - * @return null * @throws DbException */ - public function fetchAll($fetch_mode = ZM_DEFAULT_FETCH_MODE) { + public function count(): int + { + $this->select_thing = ['count(*)']; + $str = $this->queryPrepare(); + $this->result = DB::rawQuery($str[0], $str[1]); + return intval($this->result[0]['count(*)']); + } + + /** + * @param int $fetch_mode + * @throws DbException + */ + public function fetchAll($fetch_mode = ZM_DEFAULT_FETCH_MODE) + { $this->execute($fetch_mode); return $this->getResult(); } /** - * @return mixed|null * @throws DbException + * @return null|mixed */ - public function fetchFirst() { + public function fetchFirst() + { return $this->fetchAll()[0] ?? null; } /** - * @param null $key - * @return mixed|null + * @param null $key * @throws DbException + * @return null|mixed */ - public function value($key = null) { + public function value($key = null) + { $r = $this->fetchFirst(); - if ($r === null) return null; - if ($key === null) + if ($r === null) { + return null; + } + if ($key === null) { return current($r); - else return $r[$key] ?? null; + } + return $r[$key] ?? null; } /** - * @param int $fetch_mode + * @param int $fetch_mode * @throws DbException */ - public function execute($fetch_mode = ZM_DEFAULT_FETCH_MODE) { + public function execute($fetch_mode = ZM_DEFAULT_FETCH_MODE) + { $str = $this->queryPrepare(); $this->result = DB::rawQuery($str[0], $str[1], $fetch_mode); } - public function getResult() { return $this->result; } + public function getResult() + { + return $this->result; + } - public function equals(SelectBody $body): bool { - if ($this->select_thing != $body->getSelectThing()) return false; - elseif ($this->where_thing == $body->getWhereThing()) return false; - else return true; + public function equals(SelectBody $body): bool + { + if ($this->select_thing != $body->getSelectThing()) { + return false; + } + if ($this->where_thing == $body->getWhereThing()) { + return false; + } + return true; } /** * @return mixed */ - public function getSelectThing() { return $this->select_thing; } + public function getSelectThing() + { + return $this->select_thing; + } - /** - * @return array - */ - public function getWhereThing(): array { return $this->where_thing; } + public function getWhereThing(): array + { + return $this->where_thing; + } - private function queryPrepare(): array { - $msg = "SELECT " . implode(", ", $this->select_thing) . " FROM " . $this->table->getTableName(); + private function queryPrepare(): array + { + $msg = 'SELECT ' . implode(', ', $this->select_thing) . ' FROM ' . $this->table->getTableName(); $sql = $this->table->paintWhereSQL($this->where_thing['='] ?? [], '='); if ($sql[0] != '') { - $msg .= " WHERE " . $sql[0]; + $msg .= ' WHERE ' . $sql[0]; $array = $sql[1]; $sql = $this->table->paintWhereSQL($this->where_thing['!='] ?? [], '!='); - if ($sql[0] != '') $msg .= " AND " . $sql[0]; + if ($sql[0] != '') { + $msg .= ' AND ' . $sql[0]; + } $array = array_merge($array, $sql[1]); } return [$msg, $array ?? []]; diff --git a/src/ZM/DB/Table.php b/src/ZM/DB/Table.php index d166a1e5..cb8914c6 100644 --- a/src/ZM/DB/Table.php +++ b/src/ZM/DB/Table.php @@ -1,71 +1,87 @@ -table_name = $table_name; self::$table_instance[$table_name] = $this; } - public static function getTableInstance($table_name) { - if (isset(self::$table_instance[$table_name])) return self::$table_instance[$table_name]; - else return null; + public static function getTableInstance($table_name) + { + if (isset(self::$table_instance[$table_name])) { + return self::$table_instance[$table_name]; + } + return null; } - public function select($what = []) { - return new SelectBody($this, $what == [] ? ["*"] : $what); + public function select($what = []) + { + return new SelectBody($this, $what == [] ? ['*'] : $what); } - public function where($column, $operation_or_value, $value = null) { - return (new SelectBody($this, ["*"]))->where($column, $operation_or_value, $value); + public function where($column, $operation_or_value, $value = null) + { + return (new SelectBody($this, ['*']))->where($column, $operation_or_value, $value); } - public function insert($row) { + public function insert($row) + { $this->cache = []; return new InsertBody($this, $row); } - public function update(array $set_value) { + public function update(array $set_value) + { $this->cache = []; return new UpdateBody($this, $set_value); } - public function delete() { + public function delete() + { $this->cache = []; return new DeleteBody($this); } - public function statement() { + public function statement() + { $this->cache = []; //TODO: 无返回的statement语句 } - public function paintWhereSQL($rule, $operator) { - if ($rule == []) return ["", []]; - $msg = ""; + public function paintWhereSQL($rule, $operator) + { + if ($rule == []) { + return ['', []]; + } + $msg = ''; $param = []; foreach ($rule as $k => $v) { - if ($msg == "") { - $msg .= $k . " $operator ? "; + if ($msg == '') { + $msg .= $k . " {$operator} ? "; } else { - $msg .= " AND " . $k . " $operator ?"; + $msg .= ' AND ' . $k . " {$operator} ?"; } $param[] = $v; } @@ -75,6 +91,8 @@ class Table /** * @return mixed */ - public function getTableName() { return $this->table_name; } - + public function getTableName() + { + return $this->table_name; + } } diff --git a/src/ZM/DB/UpdateBody.php b/src/ZM/DB/UpdateBody.php index 0b7e8395..0d36664e 100644 --- a/src/ZM/DB/UpdateBody.php +++ b/src/ZM/DB/UpdateBody.php @@ -1,14 +1,13 @@ table = $table; $this->set_value = $set_value; } @@ -37,20 +36,23 @@ class UpdateBody /** * @throws DbException */ - public function save() { + public function save() + { $arr = []; $msg = []; foreach ($this->set_value as $k => $v) { - $msg [] = $k . ' = ?'; + $msg[] = $k . ' = ?'; $arr[] = $v; } - if (($msg ?? []) == []) throw new DbException('update value sets can not be empty!'); + if (($msg ?? []) == []) { + throw new DbException('update value sets can not be empty!'); + } $line = 'UPDATE ' . $this->table->getTableName() . ' SET ' . implode(', ', $msg); if ($this->where_thing != []) { - list($sql, $param) = $this->getWhereSQL(); + [$sql, $param] = $this->getWhereSQL(); $arr = array_merge($arr, $param); $line .= ' WHERE ' . $sql; } return DB::rawQuery($line, $arr); } -} \ No newline at end of file +} diff --git a/src/ZM/DB/WhereBody.php b/src/ZM/DB/WhereBody.php index cf7b17c8..83f2a500 100644 --- a/src/ZM/DB/WhereBody.php +++ b/src/ZM/DB/WhereBody.php @@ -1,38 +1,48 @@ -where_thing[$operation_or_value][$column] = $value; - elseif (!in_array($operation_or_value, ['=', '!=', '>', '<', '>=', '<=', 'IN', 'in'])) $this->where_thing['='][$column] = $operation_or_value; - else $this->where_thing['='][$column] = $operation_or_value; + public function where($column, $operation_or_value, $value = null) + { + if ($value !== null) { + $this->where_thing[$operation_or_value][$column] = $value; + } elseif (!in_array($operation_or_value, ['=', '!=', '>', '<', '>=', '<=', 'IN', 'in'])) { + $this->where_thing['='][$column] = $operation_or_value; + } else { + $this->where_thing['='][$column] = $operation_or_value; + } return $this; } - protected function getWhereSQL() { + protected function getWhereSQL() + { $param = []; $msg = ''; foreach ($this->where_thing as $k => $v) { foreach ($v as $ks => $vs) { if ($param != []) { - $msg .= ' AND ' . $ks . " $k ?"; + $msg .= ' AND ' . $ks . " {$k} ?"; } else { - $msg .= "$ks $k ?"; + $msg .= "{$ks} {$k} ?"; } - $param [] = $vs; + $param[] = $vs; } } - if ($msg == '') $msg = 1; + if ($msg == '') { + $msg = 1; + } return [$msg, $param]; } } diff --git a/src/ZM/Entity/CQObject.php b/src/ZM/Entity/CQObject.php index 8f5035ee..0d0987ff 100644 --- a/src/ZM/Entity/CQObject.php +++ b/src/ZM/Entity/CQObject.php @@ -1,18 +1,22 @@ type = $type; $this->params = $params; $this->start = $start; @@ -20,7 +24,8 @@ class CQObject } } - public static function fromArray($arr): CQObject { - return new CQObject($arr["type"], $arr["params"] ?? [], $arr["start"], $arr["end"]); + public static function fromArray($arr): CQObject + { + return new CQObject($arr['type'], $arr['params'] ?? [], $arr['start'], $arr['end']); } -} \ No newline at end of file +} diff --git a/src/ZM/Entity/MatchResult.php b/src/ZM/Entity/MatchResult.php index d345f797..ab770374 100644 --- a/src/ZM/Entity/MatchResult.php +++ b/src/ZM/Entity/MatchResult.php @@ -1,17 +1,19 @@ class = $class; + $this->eid = ZMAtomic::get('_event_id')->add(1); + $list = LightCacheInside::get('wait_api', 'event_trace'); + if (isset($list[$class])) { + $this->log = true; + } + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 开始分发事件: " . $class); + } + } /** - * @param null $return_var + * @param mixed $return_var * @throws InterruptException */ - public static function interrupt($return_var = null) { + public static function interrupt($return_var = null) + { throw new InterruptException($return_var); } - public static function enableEventTrace($event_class) { - SpinLock::lock("_event_trace"); - $list = LightCacheInside::get("wait_api", "event_trace"); + public static function enableEventTrace($event_class) + { + SpinLock::lock('_event_trace'); + $list = LightCacheInside::get('wait_api', 'event_trace'); $list[$event_class] = true; - LightCacheInside::set("wait_api", "event_trace", $list); - SpinLock::unlock("_event_trace"); + LightCacheInside::set('wait_api', 'event_trace', $list); + SpinLock::unlock('_event_trace'); } - public static function disableEventTrace($event_class) { - SpinLock::lock("_event_trace"); - $list = LightCacheInside::get("wait_api", "event_trace"); + public static function disableEventTrace($event_class) + { + SpinLock::lock('_event_trace'); + $list = LightCacheInside::get('wait_api', 'event_trace'); unset($list[$event_class]); - LightCacheInside::set("wait_api", "event_trace", $list); - SpinLock::unlock("_event_trace"); + LightCacheInside::set('wait_api', 'event_trace', $list); + SpinLock::unlock('_event_trace'); } - public function __construct(string $class = '') { - $this->class = $class; - $this->eid = ZMAtomic::get("_event_id")->add(1); - $list = LightCacheInside::get("wait_api", "event_trace"); - if (isset($list[$class])) $this->log = true; - if ($this->log) Console::verbose("[事件分发{$this->eid}] 开始分发事件: " . $class); - } - - public function setRuleFunction(callable $rule = null): EventDispatcher { - if ($this->log) Console::verbose("[事件分发{$this->eid}] 设置事件rule: " . $this->class); + public function setRuleFunction(callable $rule = null): EventDispatcher + { + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 设置事件rule: " . $this->class); + } $this->rule = $rule; return $this; } - public function setReturnFunction(callable $return_func): EventDispatcher { - if ($this->log) Console::verbose("[事件分发{$this->eid}] 设置事件returnFunc: " . $this->class); + public function setReturnFunction(callable $return_func): EventDispatcher + { + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 设置事件returnFunc: " . $this->class); + } $this->return_func = $return_func; return $this; } /** - * @param mixed ...$params + * @param mixed ...$params * @throws Exception */ - public function dispatchEvents(...$params) { + public function dispatchEvents(...$params) + { try { foreach ((EventManager::$events[$this->class] ?? []) as $v) { $this->dispatchEvent($v, $this->rule, ...$params); - if ($this->log) Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . "::" . (is_string($v->method) ? $v->method : "{closure}") . " 分发结束。"); - if ($this->status == self::STATUS_BEFORE_FAILED || $this->status == self::STATUS_RULE_FAILED) continue; + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . '::' . (is_string($v->method) ? $v->method : '{closure}') . ' 分发结束。'); + } + if ($this->status == self::STATUS_BEFORE_FAILED || $this->status == self::STATUS_RULE_FAILED) { + continue; + } if (is_callable($this->return_func) && $this->status === self::STATUS_NORMAL) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . "::" . $v->method . " 正在执行返回值处理函数 ..."); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 单一对象 " . $v->class . '::' . $v->method . ' 正在执行返回值处理函数 ...'); + } ($this->return_func)($this->store); } } - if ($this->status === self::STATUS_RULE_FAILED) $this->status = self::STATUS_NORMAL; + if ($this->status === self::STATUS_RULE_FAILED) { + $this->status = self::STATUS_NORMAL; + } //TODO:没有过滤before的false,可能会导致一些问题,先观望一下 } catch (InterruptException $e) { $this->store = $e->return_var; $this->status = self::STATUS_INTERRUPTED; - } catch (Exception | Error $e) { + } catch (Exception|Error $e) { $this->status = self::STATUS_EXCEPTION; throw $e; } } /** - * @param mixed $v - * @param null $rule_func - * @param mixed ...$params - * @return bool + * @param mixed $v + * @param null $rule_func + * @param mixed ...$params * @throws InterruptException * @throws AnnotationException + * @return bool * @noinspection PhpMissingReturnTypeInspection */ - public function dispatchEvent($v, $rule_func = null, ...$params) { + public function dispatchEvent($v, $rule_func = null, ...$params) + { $q_c = $v->class; $q_f = $v->method; - if (($q_c ?? "") === "" && ($q_f instanceof Closure)) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] 闭包函数的事件触发过程!"); + if (($q_c ?? '') === '' && ($q_f instanceof Closure)) { + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 闭包函数的事件触发过程!"); + } if ($rule_func !== null && !$rule_func($v)) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] 闭包函数下的 ruleFunc 判断为 false, 拒绝执行此方法。"); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 闭包函数下的 ruleFunc 判断为 false, 拒绝执行此方法。"); + } $this->status = self::STATUS_RULE_FAILED; return false; } @@ -132,42 +171,55 @@ class EventDispatcher $this->status = self::STATUS_NORMAL; return true; } - if ($this->log) Console::verbose("[事件分发{$this->eid}] 正在判断 " . $q_c . "::" . $q_f . " 方法下的 ruleFunc ..."); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 正在判断 " . $q_c . '::' . $q_f . ' 方法下的 ruleFunc ...'); + } if ($rule_func !== null && !$rule_func($v)) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法下的 ruleFunc 判断为 false, 拒绝执行此方法。"); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] " . $q_c . '::' . $q_f . ' 方法下的 ruleFunc 判断为 false, 拒绝执行此方法。'); + } $this->status = self::STATUS_RULE_FAILED; return false; } - if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法下的 ruleFunc 为真,继续执行方法本身 ..."); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] " . $q_c . '::' . $q_f . ' 方法下的 ruleFunc 为真,继续执行方法本身 ...'); + } if (isset(EventManager::$middleware_map[$q_c][$q_f])) { $middlewares = EventManager::$middleware_map[$q_c][$q_f]; - if ($this->log) Console::verbose("[事件分发{$this->eid}] " . $q_c . "::" . $q_f . " 方法还绑定了 Middleware:" . implode(", ", array_map(function ($x) { return $x->middleware; }, $middlewares))); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] " . $q_c . '::' . $q_f . ' 方法还绑定了 Middleware:' . implode(', ', array_map(function ($x) { return $x->middleware; }, $middlewares))); + } $before_result = true; $r = []; foreach ($middlewares as $k => $middleware) { if (!isset(EventManager::$middlewares[$middleware->middleware])) { - if ((ZMConfig::get("global", "runtime")["middleware_error_policy"] ?? 1) == 1) + if ((ZMConfig::get('global', 'runtime')['middleware_error_policy'] ?? 1) == 1) { throw new AnnotationException("Annotation parse error: Unknown MiddlewareClass named \"{$middleware->middleware}\"!"); - else - continue; + } + continue; } $middleware_obj = EventManager::$middlewares[$middleware->middleware]; - $before = $middleware_obj["class"]; + $before = $middleware_obj['class']; //var_dump($middleware_obj); $r[$k] = new $before(); $r[$k]->class = $q_c; $r[$k]->method = $q_f; $r[$k]->middleware = $middleware; $r[$k]->current_event = $v; - if (isset($middleware_obj["before"])) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 存在前置事件,执行中 ..."); - $rs = $middleware_obj["before"]; - $before_result = $r[$k]->$rs(...$params); + if (isset($middleware_obj['before'])) { + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] Middleware 存在前置事件,执行中 ..."); + } + $rs = $middleware_obj['before']; + $before_result = $r[$k]->{$rs}(...$params); if ($before_result === false) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 前置事件为 false,停止执行原事件,开始执行下一事件。"); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] Middleware 前置事件为 false,停止执行原事件,开始执行下一事件。"); + } break; - } else { - if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 前置事件为 true,继续执行原事件。"); + } + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] Middleware 前置事件为 true,继续执行原事件。"); } } } @@ -175,21 +227,31 @@ class EventDispatcher try { $q_o = ZMUtil::getModInstance($q_c); $q_o->_running_annotation = $v; - if ($this->log) Console::verbose("[事件分发{$this->eid}] 正在执行方法 " . $q_c . "::" . $q_f . " ..."); - $this->store = $q_o->$q_f(...$params); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 正在执行方法 " . $q_c . '::' . $q_f . ' ...'); + } + $this->store = $q_o->{$q_f}(...$params); } catch (Exception $e) { if ($e instanceof InterruptException) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] 检测到事件阻断调用,正在跳出事件分发器 ..."); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 检测到事件阻断调用,正在跳出事件分发器 ..."); + } throw $e; } - if ($this->log) Console::verbose("[事件分发{$this->eid}] 方法 " . $q_c . "::" . $q_f . " 执行过程中抛出了异常,正在倒序查找 Middleware 中的捕获方法 ..."); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 方法 " . $q_c . '::' . $q_f . ' 执行过程中抛出了异常,正在倒序查找 Middleware 中的捕获方法 ...'); + } for ($i = count($middlewares) - 1; $i >= 0; --$i) { $middleware_obj = EventManager::$middlewares[$middlewares[$i]->middleware]; - if (!isset($middleware_obj["exceptions"])) continue; - foreach ($middleware_obj["exceptions"] as $name => $method) { + if (!isset($middleware_obj['exceptions'])) { + continue; + } + foreach ($middleware_obj['exceptions'] as $name => $method) { if ($e instanceof $name) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] 方法 " . $q_c . "::" . $q_f . " 的异常 " . get_class($e) . " 被 Middleware:" . $middlewares[$i] . " 下的 " . get_class($r[$i]) . "::" . $method . " 捕获。"); - $r[$i]->$method($e); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 方法 " . $q_c . '::' . $q_f . ' 的异常 ' . get_class($e) . ' 被 Middleware:' . $middlewares[$i] . ' 下的 ' . get_class($r[$i]) . '::' . $method . ' 捕获。'); + } + $r[$i]->{$method}($e); self::interrupt(); } } @@ -199,10 +261,14 @@ class EventDispatcher $cnts = count($middlewares) - 1; for ($i = $cnts; $i >= 0; --$i) { $middleware_obj = EventManager::$middlewares[$middlewares[$i]->middleware]; - if (isset($middleware_obj["after"], $r[$i])) { - if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 存在后置事件,执行中 ..."); - $r[$i]->{$middleware_obj["after"]}(...$params); - if ($this->log) Console::verbose("[事件分发{$this->eid}] Middleware 后置事件执行完毕!"); + if (isset($middleware_obj['after'], $r[$i])) { + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] Middleware 存在后置事件,执行中 ..."); + } + $r[$i]->{$middleware_obj['after']}(...$params); + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] Middleware 后置事件执行完毕!"); + } } } $this->status = self::STATUS_NORMAL; @@ -210,27 +276,24 @@ class EventDispatcher } $this->status = self::STATUS_BEFORE_FAILED; return false; - } else { - $q_o = ZMUtil::getModInstance($q_c); - $q_o->_running_annotation = $v; - if ($this->log) Console::verbose("[事件分发{$this->eid}] 正在执行方法 " . $q_c . "::" . $q_f . " ..."); - $this->store = $q_o->$q_f(...$params); - $this->status = self::STATUS_NORMAL; - return true; } + $q_o = ZMUtil::getModInstance($q_c); + $q_o->_running_annotation = $v; + if ($this->log) { + Console::verbose("[事件分发{$this->eid}] 正在执行方法 " . $q_c . '::' . $q_f . ' ...'); + } + $this->store = $q_o->{$q_f}(...$params); + $this->status = self::STATUS_NORMAL; + return true; } - /** - * @return int - */ - public function getEid(): int { + public function getEid(): int + { return $this->eid; } - /** - * @return string - */ - public function getClass(): string { + public function getClass(): string + { return $this->class; } } diff --git a/src/ZM/Event/EventManager.php b/src/ZM/Event/EventManager.php index 3f6620ae..52dc52b1 100644 --- a/src/ZM/Event/EventManager.php +++ b/src/ZM/Event/EventManager.php @@ -1,9 +1,10 @@ method instanceof \Closure) { - Console::debug("Adding event $event_name at @Anonymous"); + public static function addEvent($event_name, ?AnnotationBase $event_obj) + { + if ($event_obj->method instanceof Closure) { + Console::debug("Adding event {$event_name} at @Anonymous"); } else { - Console::debug("Adding event $event_name at " . ($event_obj->class) . ":" . ($event_obj->method)); + Console::debug("Adding event {$event_name} at " . ($event_obj->class) . ':' . ($event_obj->method)); } self::$events[$event_name][] = $event_obj; (new AnnotationParser())->sortByLevel(self::$events, $event_name); @@ -36,7 +41,8 @@ class EventManager /** * @throws AnnotationException */ - public static function loadEventByParser(AnnotationParser $parser) { + public static function loadEventByParser(AnnotationParser $parser) + { self::$events = $parser->generateAnnotationEvents(); self::$middlewares = $parser->getMiddlewares(); self::$middleware_map = $parser->getMiddlewareMap(); @@ -48,33 +54,36 @@ class EventManager * 注册所有计时器给每个进程 * @throws Exception */ - public static function registerTimerTick() { + public static function registerTimerTick() + { $dispatcher = new EventDispatcher(OnTick::class); foreach (self::$events[OnTick::class] ?? [] as $vss) { - if (server()->worker_id !== $vss->worker_id && $vss->worker_id != -1) return; + if (server()->worker_id !== $vss->worker_id && $vss->worker_id != -1) { + return; + } //echo server()->worker_id.PHP_EOL; $plain_class = $vss->class; - Console::debug("Added Middleware-based timer: " . $plain_class . " -> " . $vss->method); + Console::debug('Added Middleware-based timer: ' . $plain_class . ' -> ' . $vss->method); Timer::tick($vss->tick_ms, function () use ($vss, $dispatcher) { set_coroutine_params([]); - if (ZMAtomic::get("stop_signal")->get() != 0) { + if (ZMAtomic::get('stop_signal')->get() != 0) { Timer::clearAll(); return; } try { $dispatcher->dispatchEvent($vss, null); } catch (Exception $e) { - Console::error(zm_internal_errcode("E00034") . "Uncaught error from TimerTick: " . $e->getMessage() . " at " . $e->getFile() . "({$e->getLine()})"); + Console::error(zm_internal_errcode('E00034') . 'Uncaught error from TimerTick: ' . $e->getMessage() . ' at ' . $e->getFile() . "({$e->getLine()})"); } catch (Error $e) { - Console::error(zm_internal_errcode("E00034") . "Uncaught fatal error from TimerTick: " . $e->getMessage()); - echo Console::setColor($e->getTraceAsString(), "gray"); - Console::error("Please check your code!"); + Console::error(zm_internal_errcode('E00034') . 'Uncaught fatal error from TimerTick: ' . $e->getMessage()); + echo Console::setColor($e->getTraceAsString(), 'gray'); + Console::error('Please check your code!'); } }); } - $conf = ZMConfig::get("global", "worker_cache") ?? ["worker" => 0]; - if (server()->worker_id == $conf["worker"]) { - zm_timer_tick(ZMConfig::get("global", "light_cache")["auto_save_interval"] * 1000, function () { + $conf = ZMConfig::get('global', 'worker_cache') ?? ['worker' => 0]; + if (server()->worker_id == $conf['worker']) { + zm_timer_tick(ZMConfig::get('global', 'light_cache')['auto_save_interval'] * 1000, function () { LightCache::savePersistence(); }); } diff --git a/src/ZM/Event/EventTracer.php b/src/ZM/Event/EventTracer.php index 9960c00c..1ca84d70 100644 --- a/src/ZM/Event/EventTracer.php +++ b/src/ZM/Event/EventTracer.php @@ -1,22 +1,23 @@ class, $current_event->method)) return null; + if (!isset($current_event->class, $current_event->method)) { + return null; + } return EventManager::$middleware_map[$current_event->class][$current_event->method] ?? []; } - public static function getEventTraceList() { + public static function getEventTraceList() + { $result = []; $list = debug_backtrace(); foreach ($list as $v) { - if ((($v["object"] ?? null) instanceof EventDispatcher) && $v["function"] == "dispatchEvent") { - $result[] = $v["args"][0]; + if ((($v['object'] ?? null) instanceof EventDispatcher) && $v['function'] == 'dispatchEvent') { + $result[] = $v['args'][0]; } } return $result; } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent.php b/src/ZM/Event/SwooleEvent.php index b5834ee2..8ba12570 100644 --- a/src/ZM/Event/SwooleEvent.php +++ b/src/ZM/Event/SwooleEvent.php @@ -1,9 +1,9 @@ get(), SIGUSR1); + Process::kill(zm_atomic('_#worker_' . $i)->get(), SIGUSR1); + } + $conf = ZMConfig::get('global', 'runtime')['reload_delay_time'] ?? 800; + if ($conf !== 0) { + usleep($conf * 1000); } - $conf = ZMConfig::get("global", "runtime")["reload_delay_time"] ?? 800; - if ($conf !== 0) usleep($conf * 1000); } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnClose.php b/src/ZM/Event/SwooleEvent/OnClose.php index f94a47ac..60ee2c10 100644 --- a/src/ZM/Event/SwooleEvent/OnClose.php +++ b/src/ZM/Event/SwooleEvent/OnClose.php @@ -1,9 +1,9 @@ $server, "connection" => $conn, "fd" => $fd]); + if ($conn === null) { + return; + } + set_coroutine_params(['server' => $server, 'connection' => $conn, 'fd' => $fd]); $dispatcher1 = new EventDispatcher(OnCloseEvent::class); $dispatcher1->setRuleFunction(function ($v) { - return $v->connect_type == ctx()->getConnection()->getName() && eval("return " . $v->getRule() . ";"); + return $v->connect_type == ctx()->getConnection()->getName() && eval('return ' . $v->getRule() . ';'); }); $dispatcher = new EventDispatcher(OnSwooleEvent::class); $dispatcher->setRuleFunction(function ($v) { if ($v->getRule() == '') { return strtolower($v->type) == 'close'; - } else { - /** @noinspection PhpUnreachableStatementInspection */ - if (strtolower($v->type) == 'close' && eval("return " . $v->getRule() . ";")) return true; - else return false; } + if (strtolower($v->type) == 'close' && eval('return ' . $v->getRule() . ';')) { + return true; + } + return false; }); try { - $obb_onebot = ZMConfig::get("global", "onebot") ?? - ZMConfig::get("global", "modules")["onebot"] ?? - ["status" => true, "single_bot_mode" => false, "message_level" => 99999]; - if ($conn->getName() === 'qq' && $obb_onebot["status"] === true) { - if ($obb_onebot["single_bot_mode"]) { - LightCacheInside::set("connect", "conn_fd", -1); + $obb_onebot = ZMConfig::get('global', 'onebot') ?? + ZMConfig::get('global', 'modules')['onebot'] ?? + ['status' => true, 'single_bot_mode' => false, 'message_level' => 99999]; + if ($conn->getName() === 'qq' && $obb_onebot['status'] === true) { + if ($obb_onebot['single_bot_mode']) { + LightCacheInside::set('connect', 'conn_fd', -1); } } $dispatcher1->dispatchEvents($conn); $dispatcher->dispatchEvents($conn); } catch (Exception $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00016") . "Uncaught exception " . get_class($e) . " when calling \"close\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00016') . 'Uncaught exception ' . get_class($e) . ' when calling "close": ' . $error_msg); Console::trace(); } catch (Error $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00016") . "Uncaught " . get_class($e) . " when calling \"close\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00016') . 'Uncaught ' . get_class($e) . ' when calling "close": ' . $error_msg); Console::trace(); } ManagerGM::popConnect($fd); } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnManagerStart.php b/src/ZM/Event/SwooleEvent/OnManagerStart.php index c7c7e3d9..80d9e758 100644 --- a/src/ZM/Event/SwooleEvent/OnManagerStart.php +++ b/src/ZM/Event/SwooleEvent/OnManagerStart.php @@ -1,11 +1,15 @@ -manager_pid); - ProcessManager::createUserProcess('monitor', function() use ($server){ - Process::signal(SIGINT, function() { - Console::success("用户进程检测到了Ctrl+C"); + ProcessManager::createUserProcess('monitor', function () use ($server) { + Process::signal(SIGINT, function () { + Console::success('用户进程检测到了Ctrl+C'); }); - if (Framework::$argv["watch"]) { + if (Framework::$argv['watch']) { if (extension_loaded('inotify')) { - Console::info("Enabled File watcher, framework will reload automatically."); - /** @noinspection PhpUndefinedFieldInspection */ + Console::info('Enabled File watcher, framework will reload automatically.'); + /* @noinspection PhpUndefinedFieldInspection */ Framework::$server->inotify = $fd = inotify_init(); - $this->addWatcher(DataProvider::getSourceRootDir() . "/src", $fd); + $this->addWatcher(DataProvider::getSourceRootDir() . '/src', $fd); Event::add($fd, function () use ($fd) { $r = inotify_read($fd); - Console::verbose("File updated: " . $r[0]["name"]); + Console::verbose('File updated: ' . $r[0]['name']); ZMUtil::reload(); }); - Framework::$argv["polling-watch"] = false; // 如果开启了inotify则关闭轮询热更新 + Framework::$argv['polling-watch'] = false; // 如果开启了inotify则关闭轮询热更新 } else { - Console::warning(zm_internal_errcode("E00024") . "你还没有安装或启用 inotify 扩展,将默认使用轮询检测模式开启热更新!"); - Framework::$argv["polling-watch"] = true; + Console::warning(zm_internal_errcode('E00024') . '你还没有安装或启用 inotify 扩展,将默认使用轮询检测模式开启热更新!'); + Framework::$argv['polling-watch'] = true; } } - if (Framework::$argv["polling-watch"]) { + if (Framework::$argv['polling-watch']) { self::$watch = swoole_timer_tick(3000, function () use ($server) { $data = (DataProvider::scanDirFiles(DataProvider::getSourceRootDir() . '/src/')); - $hash = md5(""); + $hash = md5(''); foreach ($data as $file) { $hash = md5($hash . md5_file($file)); } - if (self::$last_hash == "") { + if (self::$last_hash == '') { self::$last_hash = $hash; } elseif (self::$last_hash !== $hash) { self::$last_hash = $hash; @@ -75,8 +80,8 @@ class OnManagerStart implements SwooleEvent } }); } - if (Framework::$argv["interact"]) { - Console::info("Interact mode"); + if (Framework::$argv['interact']) { + Console::info('Interact mode'); ZMBuf::$terminal = $r = STDIN; Event::add($r, function () use ($r) { $fget = fgets($r); @@ -85,13 +90,15 @@ class OnManagerStart implements SwooleEvent return; } $var = trim($fget); - if ($var == "stop") Event::del($r); + if ($var == 'stop') { + Event::del($r); + } try { Terminal::executeCommand($var); } catch (Exception $e) { - Console::error(zm_internal_errcode("E00025") . "Uncaught exception " . get_class($e) . ": " . $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"); + Console::error(zm_internal_errcode('E00025') . 'Uncaught exception ' . get_class($e) . ': ' . $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'); } catch (Error $e) { - Console::error(zm_internal_errcode("E00025") . "Uncaught error " . get_class($e) . ": " . $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"); + Console::error(zm_internal_errcode('E00025') . 'Uncaught error ' . get_class($e) . ': ' . $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'); } }); } @@ -106,20 +113,21 @@ class OnManagerStart implements SwooleEvent }); $dispatcher->dispatchEvents($server); */ - Console::verbose("进程 Manager 已启动"); + Console::verbose('进程 Manager 已启动'); } - private function addWatcher($maindir, $fd) { + private function addWatcher($maindir, $fd) + { $dir = scandir($maindir); - if ($dir[0] == ".") { + if ($dir[0] == '.') { unset($dir[0], $dir[1]); } foreach ($dir as $subdir) { - if (is_dir($maindir . "/" . $subdir)) { - Console::debug("添加监听目录:" . $maindir . "/" . $subdir); - inotify_add_watch($fd, $maindir . "/" . $subdir, IN_ATTRIB | IN_ISDIR); - $this->addWatcher($maindir . "/" . $subdir, $fd); + if (is_dir($maindir . '/' . $subdir)) { + Console::debug('添加监听目录:' . $maindir . '/' . $subdir); + inotify_add_watch($fd, $maindir . '/' . $subdir, IN_ATTRIB | IN_ISDIR); + $this->addWatcher($maindir . '/' . $subdir, $fd); } } } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnManagerStop.php b/src/ZM/Event/SwooleEvent/OnManagerStop.php index e6f7926e..c1b92bf7 100644 --- a/src/ZM/Event/SwooleEvent/OnManagerStop.php +++ b/src/ZM/Event/SwooleEvent/OnManagerStop.php @@ -1,9 +1,9 @@ pid) !== false) Process::kill($v->pid, SIGTERM); + if (posix_getsid($v->pid) !== false) { + Process::kill($v->pid, SIGTERM); + } } - Console::verbose("进程 Manager 已停止!"); + Console::verbose('进程 Manager 已停止!'); Framework::removeProcessState(ZM_PROCESS_MANAGER); } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnMessage.php b/src/ZM/Event/SwooleEvent/OnMessage.php index 9cc8ffe3..00501c19 100644 --- a/src/ZM/Event/SwooleEvent/OnMessage.php +++ b/src/ZM/Event/SwooleEvent/OnMessage.php @@ -1,9 +1,9 @@ fd . ": " . TermColor::ITALIC . $frame->data . TermColor::RESET); + public function onCall($server, Frame $frame) + { + Console::debug('Calling Swoole "message" from fd=' . $frame->fd . ': ' . TermColor::ITALIC . $frame->data . TermColor::RESET); unset(Context::$context[Coroutine::getCid()]); $conn = ManagerGM::get($frame->fd); - set_coroutine_params(["server" => $server, "frame" => $frame, "connection" => $conn]); + set_coroutine_params(['server' => $server, 'frame' => $frame, 'connection' => $conn]); $dispatcher1 = new EventDispatcher(OnMessageEvent::class); $dispatcher1->setRuleFunction(function ($v) { - if ($v->getRule() == '') return true; - else return eval("return " . $v->getRule() . ";"); + if ($v->getRule() == '') { + return true; + } + return eval('return ' . $v->getRule() . ';'); }); - $dispatcher = new EventDispatcher(OnSwooleEvent::class); $dispatcher->setRuleFunction(function ($v) { if ($v->getRule() == '') { return strtolower($v->type) == 'message'; - } else { - /** @noinspection PhpUnreachableStatementInspection - * @noinspection RedundantSuppression - */ - if (strtolower($v->type) == 'message' && eval("return " . $v->getRule() . ";")) return true; - else return false; } + /* @noinspection PhpUnreachableStatementInspection + * @noinspection RedundantSuppression + */ + if (strtolower($v->type) == 'message' && eval('return ' . $v->getRule() . ';')) { + return true; + } + return false; }); try { //$starttime = microtime(true); @@ -55,14 +57,13 @@ class OnMessage implements SwooleEvent $dispatcher->dispatchEvents($conn); //Console::success("Used ".round((microtime(true) - $starttime) * 1000, 3)." ms!"); } catch (Exception $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00017") . "Uncaught exception " . get_class($e) . " when calling \"message\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00017') . 'Uncaught exception ' . get_class($e) . ' when calling "message": ' . $error_msg); Console::trace(); } catch (Error $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00017") . "Uncaught " . get_class($e) . " when calling \"message\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00017') . 'Uncaught ' . get_class($e) . ' when calling "message": ' . $error_msg); Console::trace(); } - } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnOpen.php b/src/ZM/Event/SwooleEvent/OnOpen.php index 99e88a8a..a87fce63 100644 --- a/src/ZM/Event/SwooleEvent/OnOpen.php +++ b/src/ZM/Event/SwooleEvent/OnOpen.php @@ -1,9 +1,9 @@ fd); + public function onCall($server, Request $request) + { + Console::debug('Calling Swoole "open" event from fd=' . $request->fd); unset(Context::$context[Coroutine::getCid()]); - $type = strtolower($request->header["x-client-role"] ?? $request->get["type"] ?? ""); - $access_token = explode(" ", $request->header["authorization"] ?? "")[1] ?? $request->get["token"] ?? ""; - $token = ZMConfig::get("global", "access_token"); + $type = strtolower($request->header['x-client-role'] ?? $request->get['type'] ?? ''); + $access_token = explode(' ', $request->header['authorization'] ?? '')[1] ?? $request->get['token'] ?? ''; + $token = ZMConfig::get('global', 'access_token'); if ($token instanceof Closure) { if (!$token($access_token)) { $server->close($request->fd); - Console::warning(zm_internal_errcode("E00018") . "Unauthorized access_token: " . $access_token); + Console::warning(zm_internal_errcode('E00018') . 'Unauthorized access_token: ' . $access_token); return; } } elseif (is_string($token)) { - if ($access_token !== $token && $token !== "") { + if ($access_token !== $token && $token !== '') { $server->close($request->fd); - Console::warning(zm_internal_errcode("E00019") . "Unauthorized access_token: " . $access_token); + Console::warning(zm_internal_errcode('E00019') . 'Unauthorized access_token: ' . $access_token); return; } } $type_conn = ManagerGM::getTypeClassName($type); ManagerGM::pushConnect($request->fd, $type_conn); $conn = ManagerGM::get($request->fd); - set_coroutine_params(["server" => $server, "request" => $request, "connection" => $conn, "fd" => $request->fd]); - $conn->setOption("connect_id", strval($request->header["x-self-id"] ?? "")); + set_coroutine_params(['server' => $server, 'request' => $request, 'connection' => $conn, 'fd' => $request->fd]); + $conn->setOption('connect_id', strval($request->header['x-self-id'] ?? '')); $dispatcher1 = new EventDispatcher(OnOpenEvent::class); $dispatcher1->setRuleFunction(function ($v) { - return ctx()->getConnection()->getName() == $v->connect_type && eval("return " . $v->getRule() . ";"); + return ctx()->getConnection()->getName() == $v->connect_type && eval('return ' . $v->getRule() . ';'); }); $dispatcher = new EventDispatcher(OnSwooleEvent::class); $dispatcher->setRuleFunction(function ($v) { if ($v->getRule() == '') { return strtolower($v->type) == 'open'; - } else { - if (strtolower($v->type) == 'open' && eval("return " . $v->getRule() . ";")) return true; - else return false; } + if (strtolower($v->type) == 'open' && eval('return ' . $v->getRule() . ';')) { + return true; + } + return false; }); try { - $obb_onebot = ZMConfig::get("global", "onebot") ?? - ZMConfig::get("global", "modules")["onebot"] ?? - ["status" => true, "single_bot_mode" => false, "message_level" => 99]; - $onebot_status = $obb_onebot["status"]; + $obb_onebot = ZMConfig::get('global', 'onebot') ?? + ZMConfig::get('global', 'modules')['onebot'] ?? + ['status' => true, 'single_bot_mode' => false, 'message_level' => 99]; + $onebot_status = $obb_onebot['status']; if ($conn->getName() === 'qq' && $onebot_status === true) { - if ($obb_onebot["single_bot_mode"]) { - LightCacheInside::set("connect", "conn_fd", $request->fd); + if ($obb_onebot['single_bot_mode']) { + LightCacheInside::set('connect', 'conn_fd', $request->fd); } } $dispatcher1->dispatchEvents($conn); $dispatcher->dispatchEvents($conn); } catch (Exception $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00020") . "Uncaught exception " . get_class($e) . " when calling \"open\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00020') . 'Uncaught exception ' . get_class($e) . ' when calling "open": ' . $error_msg); Console::trace(); } catch (Error $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00020") . "Uncaught " . get_class($e) . " when calling \"open\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00020') . 'Uncaught ' . get_class($e) . ' when calling "open": ' . $error_msg); Console::trace(); } } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnPipeMessage.php b/src/ZM/Event/SwooleEvent/OnPipeMessage.php index 0a4f541d..4bfa420a 100644 --- a/src/ZM/Event/SwooleEvent/OnPipeMessage.php +++ b/src/ZM/Event/SwooleEvent/OnPipeMessage.php @@ -1,9 +1,11 @@ -getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00021") . "Uncaught exception " . get_class($e) . " when calling \"pipeMessage\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00021') . 'Uncaught exception ' . get_class($e) . ' when calling "pipeMessage": ' . $error_msg); Console::trace(); } catch (Error $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00021") . "Uncaught " . get_class($e) . " when calling \"pipeMessage\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00021') . 'Uncaught ' . get_class($e) . ' when calling "pipeMessage": ' . $error_msg); Console::trace(); } } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnRequest.php b/src/ZM/Event/SwooleEvent/OnRequest.php index 8869cf95..07536ee2 100644 --- a/src/ZM/Event/SwooleEvent/OnRequest.php +++ b/src/ZM/Event/SwooleEvent/OnRequest.php @@ -1,9 +1,9 @@ $v) { + foreach (ZMConfig::get('global')['http_header'] as $k => $v) { $response->setHeader($k, $v); } unset(Context::$context[Coroutine::getCid()]); - Console::debug("Calling Swoole \"request\" event from fd=" . $request->fd); - set_coroutine_params(["request" => $request, "response" => $response]); + Console::debug('Calling Swoole "request" event from fd=' . $request->fd); + set_coroutine_params(['request' => $request, 'response' => $response]); $dis1 = new EventDispatcher(OnRequestEvent::class); $dis1->setRuleFunction(function ($v) { - /** @noinspection PhpUnreachableStatementInspection */ - return eval("return " . $v->getRule() . ";") ? true : false; + return eval('return ' . $v->getRule() . ';') ? true : false; }); $dis = new EventDispatcher(OnSwooleEvent::class); $dis->setRuleFunction(function ($v) { if ($v->getRule() == '') { return strtolower($v->type) == 'request'; - } else { - /** @noinspection PhpUnreachableStatementInspection */ - if (strtolower($v->type) == 'request' && eval("return " . $v->getRule() . ";")) return true; - else return false; } + if (strtolower($v->type) == 'request' && eval('return ' . $v->getRule() . ';')) { + return true; + } + return false; }); try { $dis1->dispatchEvents($request, $response); $dis->dispatchEvents($request, $response); if ($dis->status === EventDispatcher::STATUS_NORMAL && $dis1->status === EventDispatcher::STATUS_NORMAL) { - $result = HttpUtil::parseUri($request, $response, $request->server["request_uri"], $node, $params); + $result = HttpUtil::parseUri($request, $response, $request->server['request_uri'], $node, $params); if ($result === true) { - ctx()->setCache("params", $params); + ctx()->setCache('params', $params); $dispatcher = new EventDispatcher(RequestMapping::class); $div = new RequestMapping(); - $div->route = $node["route"]; + $div->route = $node['route']; $div->params = $params; - $div->method = $node["method"]; - $div->request_method = $node["request_method"]; - $div->class = $node["class"]; + $div->method = $node['method']; + $div->request_method = $node['request_method']; + $div->class = $node['class']; //Console::success("正在执行路由:".$node["method"]); $dispatcher->dispatchEvent($div, null, $params, $request, $response); - if (is_string($dispatcher->store) && !$response->isEnd()) $response->end($dispatcher->store); + if (is_string($dispatcher->store) && !$response->isEnd()) { + $response->end($dispatcher->store); + } } } if (!$response->isEnd()) { @@ -81,31 +82,35 @@ class OnRequest implements SwooleEvent // do nothing } catch (Exception $e) { $response->status(500); - Console::info($request->server["remote_addr"] . ":" . $request->server["remote_port"] . - " [" . $response->getStatusCode() . "] " . $request->server["request_uri"] + Console::info( + $request->server['remote_addr'] . ':' . $request->server['remote_port'] . + ' [' . $response->getStatusCode() . '] ' . $request->server['request_uri'] ); if (!$response->isEnd()) { - if (ZMConfig::get("global", "debug_mode")) - $response->end(zm_internal_errcode("E00023") . "Internal server exception: " . $e->getMessage()); - else - $response->end(zm_internal_errcode("E00023") . "Internal server error."); + if (ZMConfig::get('global', 'debug_mode')) { + $response->end(zm_internal_errcode('E00023') . 'Internal server exception: ' . $e->getMessage()); + } else { + $response->end(zm_internal_errcode('E00023') . 'Internal server error.'); + } } - Console::error(zm_internal_errcode("E00023") . "Internal server exception (500), caused by " . get_class($e) . ": " . $e->getMessage()); - Console::log($e->getTraceAsString(), "gray"); + Console::error(zm_internal_errcode('E00023') . 'Internal server exception (500), caused by ' . get_class($e) . ': ' . $e->getMessage()); + Console::log($e->getTraceAsString(), 'gray'); } catch (Error $e) { $response->status(500); - Console::info($request->server["remote_addr"] . ":" . $request->server["remote_port"] . - " [" . $response->getStatusCode() . "] " . $request->server["request_uri"] + Console::info( + $request->server['remote_addr'] . ':' . $request->server['remote_port'] . + ' [' . $response->getStatusCode() . '] ' . $request->server['request_uri'] ); if (!$response->isEnd()) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - if (ZMConfig::get("global", "debug_mode")) - $response->end(zm_internal_errcode("E00023") . "Internal server error: " . $error_msg); - else - $response->end(zm_internal_errcode("E00023") . "Internal server error."); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + if (ZMConfig::get('global', 'debug_mode')) { + $response->end(zm_internal_errcode('E00023') . 'Internal server error: ' . $error_msg); + } else { + $response->end(zm_internal_errcode('E00023') . 'Internal server error.'); + } } - Console::error(zm_internal_errcode("E00023") . "Internal server error (500), caused by " . get_class($e) . ": " . $e->getMessage()); - Console::log($e->getTraceAsString(), "gray"); + Console::error(zm_internal_errcode('E00023') . 'Internal server error (500), caused by ' . get_class($e) . ': ' . $e->getMessage()); + Console::log($e->getTraceAsString(), 'gray'); } } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnShutdown.php b/src/ZM/Event/SwooleEvent/OnShutdown.php index 367390a2..d2f108c6 100644 --- a/src/ZM/Event/SwooleEvent/OnShutdown.php +++ b/src/ZM/Event/SwooleEvent/OnShutdown.php @@ -1,9 +1,11 @@ -master_pid, [ - 'stdout' => ZMConfig::get("global")["swoole"]["log_file"], - 'daemon' => (bool)Framework::$argv["daemon"] + 'stdout' => ZMConfig::get('global')['swoole']['log_file'], + 'daemon' => (bool) Framework::$argv['daemon'], ]); } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnTask.php b/src/ZM/Event/SwooleEvent/OnTask.php index 1c19e9e1..4e32d373 100644 --- a/src/ZM/Event/SwooleEvent/OnTask.php +++ b/src/ZM/Event/SwooleEvent/OnTask.php @@ -1,9 +1,9 @@ data["task"])) { + public function onCall(?Server $server, Task $task) + { + if (isset($task->data['task'])) { $dispatcher = new EventDispatcher(\ZM\Annotation\Swoole\OnTask::class); $dispatcher->setRuleFunction(function ($v) use ($task) { - /** @var \ZM\Annotation\Swoole\OnTask $v */ - return $v->task_name == $task->data["task"]; + /* @var \ZM\Annotation\Swoole\OnTask $v */ + return $v->task_name == $task->data['task']; }); $dispatcher->setReturnFunction(function ($return) { EventDispatcher::interrupt($return); }); - $params = $task->data["params"]; + $params = $task->data['params']; try { $dispatcher->dispatchEvents(...$params); } catch (Throwable $e) { - $finish["throw"] = $e; + $finish['throw'] = $e; } if ($dispatcher->status === EventDispatcher::STATUS_EXCEPTION) { - $finish["result"] = null; - $finish["retcode"] = -1; + $finish['result'] = null; + $finish['retcode'] = -1; } else { - $finish["result"] = $dispatcher->store; - $finish["retcode"] = 0; + $finish['result'] = $dispatcher->store; + $finish['retcode'] = 0; } - if (zm_atomic("server_is_stopped")->get() === 1) { + if (zm_atomic('server_is_stopped')->get() === 1) { return; } $task->finish($finish); @@ -59,19 +56,19 @@ class OnTask implements SwooleEvent try { $dispatcher = new EventDispatcher(OnTaskEvent::class); $dispatcher->setRuleFunction(function ($v) { - /** @var OnTaskEvent $v */ - return eval("return " . $v->getRule() . ";"); + /* @var OnTaskEvent $v */ + return eval('return ' . $v->getRule() . ';'); }); $dispatcher->dispatchEvents(); } catch (Exception $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00026") . "Uncaught exception " . get_class($e) . " when calling \"task\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00026') . 'Uncaught exception ' . get_class($e) . ' when calling "task": ' . $error_msg); Console::trace(); } catch (Error $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00026") . "Uncaught " . get_class($e) . " when calling \"task\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00026') . 'Uncaught ' . get_class($e) . ' when calling "task": ' . $error_msg); Console::trace(); } } } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnWorkerExit.php b/src/ZM/Event/SwooleEvent/OnWorkerExit.php index a4c9c6df..8da90aaf 100644 --- a/src/ZM/Event/SwooleEvent/OnWorkerExit.php +++ b/src/ZM/Event/SwooleEvent/OnWorkerExit.php @@ -1,9 +1,11 @@ -taskworker === false) { Framework::saveProcessState(ZM_PROCESS_WORKER, $server->worker_pid, ['worker_id' => $worker_id]); - zm_atomic("_#worker_" . $worker_id)->set($server->worker_pid); - if (LightCacheInside::get("wait_api", "wait_api") !== null) { - LightCacheInside::unset("wait_api", "wait_api"); + zm_atomic('_#worker_' . $worker_id)->set($server->worker_pid); + if (LightCacheInside::get('wait_api', 'wait_api') !== null) { + LightCacheInside::unset('wait_api', 'wait_api'); } try { register_shutdown_function(function () use ($server) { $error = error_get_last(); - if (($error["type"] ?? 0) != 0) { - Console::error(zm_internal_errcode("E00027") . "Internal fatal error: " . $error["message"] . " at " . $error["file"] . "({$error["line"]})"); + if (($error['type'] ?? 0) != 0) { + Console::error(zm_internal_errcode('E00027') . 'Internal fatal error: ' . $error['message'] . ' at ' . $error['file'] . "({$error['line']})"); zm_dump($error); - } elseif (!isset($error["type"])) { + } elseif (!isset($error['type'])) { return; } //DataProvider::saveBuffer(); - /** @var Server $server */ - if (server() === null) $server->shutdown(); - else server()->shutdown(); + /* @var Server $server */ + if (server() === null) { + $server->shutdown(); + } else { + server()->shutdown(); + } }); Console::verbose("Worker #{$server->worker_id} starting"); @@ -80,34 +84,40 @@ class OnWorkerStart implements SwooleEvent $this->initMySQLPool(); // 开箱即用的Redis - $redis = ZMConfig::get("global", "redis_config"); - if ($redis !== null && $redis["host"] != "") { - if (!extension_loaded("redis")) Console::error(zm_internal_errcode("E00029") . "Can not find redis extension.\n"); - else ZMRedisPool::init($redis); + $redis = ZMConfig::get('global', 'redis_config'); + if ($redis !== null && $redis['host'] != '') { + if (!extension_loaded('redis')) { + Console::error(zm_internal_errcode('E00029') . "Can not find redis extension.\n"); + } else { + ZMRedisPool::init($redis); + } } $this->loadAnnotations(); //加载composer资源、phar外置包、注解解析注册等 EventManager::registerTimerTick(); //启动计时器 - set_coroutine_params(["server" => $server, "worker_id" => $worker_id]); + set_coroutine_params(['server' => $server, 'worker_id' => $worker_id]); $dispatcher = new EventDispatcher(OnStart::class); $dispatcher->setRuleFunction(function ($v) { return server()->worker_id === $v->worker_id || $v->worker_id === -1; }); $dispatcher->dispatchEvents($server, $worker_id); - if ($dispatcher->status === EventDispatcher::STATUS_NORMAL) Console::debug("@OnStart 执行完毕"); - else Console::warning("@OnStart 执行异常!"); - Console::success("Worker #" . $worker_id . " started"); + if ($dispatcher->status === EventDispatcher::STATUS_NORMAL) { + Console::debug('@OnStart 执行完毕'); + } else { + Console::warning('@OnStart 执行异常!'); + } + Console::success('Worker #' . $worker_id . ' started'); } catch (Exception $e) { - Console::error("Worker加载出错!停止服务!"); - Console::error(zm_internal_errcode("E00030") . $e->getMessage() . "\n" . $e->getTraceAsString()); + Console::error('Worker加载出错!停止服务!'); + Console::error(zm_internal_errcode('E00030') . $e->getMessage() . "\n" . $e->getTraceAsString()); Process::kill($server->master_pid, SIGTERM); return; } catch (Error $e) { - Console::error(zm_internal_errcode("E00030") . "PHP Error: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine()); - Console::error("Maybe it caused by your own code if in your own Module directory."); + Console::error(zm_internal_errcode('E00030') . 'PHP Error: ' . $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine()); + Console::error('Maybe it caused by your own code if in your own Module directory.'); Console::log($e->getTraceAsString(), 'gray'); - if (!Framework::$argv["watch"]) { // 在热更新模式下不能退出 + if (!Framework::$argv['watch']) { // 在热更新模式下不能退出 Process::kill($server->master_pid, SIGTERM); } } @@ -117,15 +127,15 @@ class OnWorkerStart implements SwooleEvent try { Framework::$server = $server; $this->loadAnnotations(); - Console::success("TaskWorker #" . $server->worker_id . " started"); + Console::success('TaskWorker #' . $server->worker_id . ' started'); } catch (Exception $e) { - Console::error("Worker加载出错!停止服务!"); - Console::error(zm_internal_errcode("E00030") . $e->getMessage() . "\n" . $e->getTraceAsString()); + Console::error('Worker加载出错!停止服务!'); + Console::error(zm_internal_errcode('E00030') . $e->getMessage() . "\n" . $e->getTraceAsString()); Process::kill($server->master_pid, SIGTERM); return; } catch (Error $e) { - Console::error(zm_internal_errcode("E00030") . "PHP Error: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine()); - Console::error("Maybe it caused by your own code if in your own Module directory."); + Console::error(zm_internal_errcode('E00030') . 'PHP Error: ' . $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine()); + Console::error('Maybe it caused by your own code if in your own Module directory.'); Console::log($e->getTraceAsString(), 'gray'); Process::kill($server->master_pid, SIGTERM); } @@ -138,31 +148,41 @@ class OnWorkerStart implements SwooleEvent */ private function loadAnnotations() { - if (Framework::$instant_mode) goto skip; + if (Framework::$instant_mode) { + goto skip; + } //加载各个模块的注解类,以及反射 - Console::debug("Mapping annotations"); + Console::debug('Mapping annotations'); $parser = new AnnotationParser(); - $composer = json_decode(file_get_contents(DataProvider::getSourceRootDir() . "/composer.json"), true); - $merge = array_merge($composer["autoload"]["psr-4"] ?? [], $composer["autoload-dev"]["psr-4"] ?? []); + $composer = json_decode(file_get_contents(DataProvider::getSourceRootDir() . '/composer.json'), true); + $merge = array_merge($composer['autoload']['psr-4'] ?? [], $composer['autoload-dev']['psr-4'] ?? []); foreach ($merge as $k => $v) { - if (is_dir(DataProvider::getSourceRootDir() . "/" . $v)) { - if (in_array(trim($k, "\\") . "\\", $composer["extra"]["exclude_annotate"] ?? [])) continue; - if (trim($k, "\\") == "ZM") continue; - if (\server()->worker_id == 0) Console::verbose("Add " . $v . ":$k to register path"); - $parser->addRegisterPath(DataProvider::getSourceRootDir() . "/" . $v . "/", trim($k, "\\")); + if (is_dir(DataProvider::getSourceRootDir() . '/' . $v)) { + if (in_array(trim($k, '\\') . '\\', $composer['extra']['exclude_annotate'] ?? [])) { + continue; + } + if (trim($k, '\\') == 'ZM') { + continue; + } + if (\server()->worker_id == 0) { + Console::verbose('Add ' . $v . ":{$k} to register path"); + } + $parser->addRegisterPath(DataProvider::getSourceRootDir() . '/' . $v . '/', trim($k, '\\')); } } // 检查是否允许热加载phar模块,允许的话将遍历phar内的文件 - $plugin_enable_hotload = ZMConfig::get("global", "module_loader")["enable_hotload"] ?? false; + $plugin_enable_hotload = ZMConfig::get('global', 'module_loader')['enable_hotload'] ?? false; if ($plugin_enable_hotload) { $list = ModuleManager::getPackedModules(); foreach ($list as $k => $v) { - if (\server()->worker_id === 0) Console::info("Loading packed module: " . $k); - require_once $v["phar-path"]; - $func = "loader" . $v["generated-id"]; + if (\server()->worker_id === 0) { + Console::info('Loading packed module: ' . $k); + } + require_once $v['phar-path']; + $func = 'loader' . $v['generated-id']; $func(); - $parser->addRegisterPath("phar://" . $v["phar-path"] . "/" . $v["module-root-path"], $v["namespace"]); + $parser->addRegisterPath('phar://' . $v['phar-path'] . '/' . $v['module-root-path'], $v['namespace']); } } @@ -171,27 +191,27 @@ class OnWorkerStart implements SwooleEvent skip: //加载自定义的全局函数 - Console::debug("Loading context class..."); - $context_class = ZMConfig::get("global", "context_class"); + Console::debug('Loading context class...'); + $context_class = ZMConfig::get('global', 'context_class'); if (!is_a($context_class, ContextInterface::class, true)) { - throw new ZMKnownException("E00032", "Context class must implemented from ContextInterface!"); + throw new ZMKnownException('E00032', 'Context class must implemented from ContextInterface!'); } //加载插件 - $obb_onebot = ZMConfig::get("global", "onebot") ?? - ZMConfig::get("global", "modules")["onebot"] ?? - ["status" => true, "single_bot_mode" => false, "message_level" => 99999]; - if ($obb_onebot["status"]) { - Console::debug("OneBot support enabled, listening OneBot event(3)."); + $obb_onebot = ZMConfig::get('global', 'onebot') ?? + ZMConfig::get('global', 'modules')['onebot'] ?? + ['status' => true, 'single_bot_mode' => false, 'message_level' => 99999]; + if ($obb_onebot['status']) { + Console::debug('OneBot support enabled, listening OneBot event(3).'); $obj = new OnMessageEvent(); $obj->class = QQBot::class; $obj->method = 'handleByEvent'; - $obj->level = $obb_onebot["message_level"] ?? 99; + $obj->level = $obb_onebot['message_level'] ?? 99; $obj->rule = 'connectIsQQ()'; EventManager::addEvent(OnMessageEvent::class, $obj); - if ($obb_onebot["single_bot_mode"]) { - LightCacheInside::set("connect", "conn_fd", -1); + if ($obb_onebot['single_bot_mode']) { + LightCacheInside::set('connect', 'conn_fd', -1); } else { - LightCacheInside::set("connect", "conn_fd", -2); + LightCacheInside::set('connect', 'conn_fd', -2); } } } @@ -203,56 +223,61 @@ class OnWorkerStart implements SwooleEvent SqlPoolStorage::$sql_pool = null; } $real_conf = []; - if (isset(ZMConfig::get("global", "sql_config")["sql_host"])) { - if (ZMConfig::get("global", "sql_config")["sql_host"] != "") { + if (isset(ZMConfig::get('global', 'sql_config')['sql_host'])) { + if (ZMConfig::get('global', 'sql_config')['sql_host'] != '') { if (\server()->worker_id === 0) { Console::warning("使用 'sql_config' 配置项和 DB 数据库查询构造器进行查询数据库可能会在下一个大版本中废弃,请使用 'mysql_config' 搭配 doctrine dbal 使用!"); - Console::warning("详见: `https://framework.zhamao.xin/`"); + Console::warning('详见: `https://framework.zhamao.xin/`'); } - $origin_conf = ZMConfig::get("global", "sql_config"); + $origin_conf = ZMConfig::get('global', 'sql_config'); $real_conf = [ - "host" => $origin_conf["sql_host"], - "port" => $origin_conf["sql_port"], - "username" => $origin_conf["sql_username"], - "password" => $origin_conf["sql_password"], - "dbname" => $origin_conf["sql_database"], - "options" => $origin_conf["sql_options"], + 'host' => $origin_conf['sql_host'], + 'port' => $origin_conf['sql_port'], + 'username' => $origin_conf['sql_username'], + 'password' => $origin_conf['sql_password'], + 'dbname' => $origin_conf['sql_database'], + 'options' => $origin_conf['sql_options'], 'unix_socket' => null, 'charset' => 'utf8mb4', - 'pool_size' => 64 + 'pool_size' => 64, ]; } } - if (isset(ZMConfig::get("global", "mysql_config")["host"])) { - if (ZMConfig::get("global", "mysql_config")["host"] != "") { - $real_conf = ZMConfig::get("global", "mysql_config"); + if (isset(ZMConfig::get('global', 'mysql_config')['host'])) { + if (ZMConfig::get('global', 'mysql_config')['host'] != '') { + $real_conf = ZMConfig::get('global', 'mysql_config'); } } if (!empty($real_conf)) { - Console::info("Connecting to MySQL pool"); + Console::info('Connecting to MySQL pool'); ob_start(); phpinfo(); //这个phpinfo是有用的,不能删除 $str = ob_get_clean(); $str = explode("\n", $str); foreach ($str as $v) { $v = trim($v); - if ($v == "") continue; - if (mb_strpos($v, "API Extensions") === false) continue; - if (mb_strpos($v, "pdo_mysql") === false) { - throw new DbException(zm_internal_errcode("E00028") . "未安装 mysqlnd php-mysql扩展。"); + if ($v == '') { + continue; + } + if (mb_strpos($v, 'API Extensions') === false) { + continue; + } + if (mb_strpos($v, 'pdo_mysql') === false) { + throw new DbException(zm_internal_errcode('E00028') . '未安装 mysqlnd php-mysql扩展。'); } } - SqlPoolStorage::$sql_pool = new MySQLPool((new PDOConfig()) - ->withHost($real_conf["host"]) - ->withPort($real_conf["port"]) + SqlPoolStorage::$sql_pool = new MySQLPool( + (new PDOConfig()) + ->withHost($real_conf['host']) + ->withPort($real_conf['port']) // ->withUnixSocket('/tmp/mysql.sock') - ->withDbName($real_conf["dbname"]) - ->withCharset($real_conf["charset"]) - ->withUsername($real_conf["username"]) - ->withPassword($real_conf["password"]) - ->withOptions($real_conf["options"] ?? [PDO::ATTR_STRINGIFY_FETCHES => false]) + ->withDbName($real_conf['dbname']) + ->withCharset($real_conf['charset']) + ->withUsername($real_conf['username']) + ->withPassword($real_conf['password']) + ->withOptions($real_conf['options'] ?? [PDO::ATTR_STRINGIFY_FETCHES => false]) ); - DB::initTableList($real_conf["dbname"]); + DB::initTableList($real_conf['dbname']); } } -} \ No newline at end of file +} diff --git a/src/ZM/Event/SwooleEvent/OnWorkerStop.php b/src/ZM/Event/SwooleEvent/OnWorkerStop.php index dba5c1bf..17c89976 100644 --- a/src/ZM/Event/SwooleEvent/OnWorkerStop.php +++ b/src/ZM/Event/SwooleEvent/OnWorkerStop.php @@ -1,9 +1,9 @@ taskworker ? "Task" : "") . "Worker #$worker_id 已停止 (Worker 状态码: ".$server->getWorkerStatus($worker_id).")"); + Console::verbose(($server->taskworker ? 'Task' : '') . "Worker #{$worker_id} 已停止 (Worker 状态码: " . $server->getWorkerStatus($worker_id) . ')'); Framework::removeProcessState($server->taskworker ? ZM_PROCESS_TASKWORKER : ZM_PROCESS_WORKER, $worker_id); } -} \ No newline at end of file +} diff --git a/src/ZM/Exception/AnnotationException.php b/src/ZM/Exception/AnnotationException.php index 4c1d2b55..5f52df74 100644 --- a/src/ZM/Exception/AnnotationException.php +++ b/src/ZM/Exception/AnnotationException.php @@ -1,10 +1,9 @@ return_var = $return_var; } diff --git a/src/ZM/Exception/InvalidArgumentException.php b/src/ZM/Exception/InvalidArgumentException.php index 0052a29e..cb2f8190 100644 --- a/src/ZM/Exception/InvalidArgumentException.php +++ b/src/ZM/Exception/InvalidArgumentException.php @@ -1,10 +1,9 @@ module = $module; } diff --git a/src/ZM/Exception/ZMException.php b/src/ZM/Exception/ZMException.php index a2a41396..a79a797d 100644 --- a/src/ZM/Exception/ZMException.php +++ b/src/ZM/Exception/ZMException.php @@ -1,12 +1,11 @@ getTtyWidth(); self::$instant_mode = $instant_mode; self::$argv = $args; ZMConfig::setDirectory(DataProvider::getSourceRootDir() . '/config'); - ZMConfig::setEnv($args["env"] ?? ""); - if (ZMConfig::get("global") === false) { - die (zm_internal_errcode("E00007") . "Global config load failed: " . ZMConfig::$last_error . "\nError path: " . DataProvider::getSourceRootDir() . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"); + ZMConfig::setEnv($args['env'] ?? ''); + if (ZMConfig::get('global') === false) { + echo zm_internal_errcode('E00007') . 'Global config load failed: ' . ZMConfig::$last_error . "\nError path: " . DataProvider::getSourceRootDir() . "\nPlease init first!\nSee: https://github.com/zhamao-robot/zhamao-framework/issues/37\n"; + exit(1); } //定义常量 - include_once "global_defines.php"; + include_once 'global_defines.php'; try { - $sw = ZMConfig::get("global"); - if (!is_dir($sw["zm_data"])) mkdir($sw["zm_data"]); - if (!is_dir($sw["config_dir"])) mkdir($sw["config_dir"]); - if (!is_dir($sw["crash_dir"])) mkdir($sw["crash_dir"]); - ManagerGM::init(ZMConfig::get("global", "swoole")["max_connection"] ?? 2048, 0.5, [ + $sw = ZMConfig::get('global'); + if (!is_dir($sw['zm_data'])) { + mkdir($sw['zm_data']); + } + if (!is_dir($sw['config_dir'])) { + mkdir($sw['config_dir']); + } + if (!is_dir($sw['crash_dir'])) { + mkdir($sw['crash_dir']); + } + ManagerGM::init(ZMConfig::get('global', 'swoole')['max_connection'] ?? 2048, 0.5, [ [ - "key" => "connect_id", - "type" => "string", - "size" => 30 + 'key' => 'connect_id', + 'type' => 'string', + 'size' => 30, ], [ - "key" => "type", - "type" => "int" - ] + 'key' => 'type', + 'type' => 'int', + ], ]); } catch (ConnectionManager\TableException $e) { - die(zm_internal_errcode("E00008") . $e->getMessage()); + echo zm_internal_errcode('E00008') . $e->getMessage() . PHP_EOL; + exit(1); } try { - Console::init( - ZMConfig::get("global", "info_level") ?? 2, + ZMConfig::get('global', 'info_level') ?? 2, self::$server, - $args["log-theme"] ?? "default", - ($o = ZMConfig::get("console_color")) === false ? [] : $o + $args['log-theme'] ?? 'default', + ($o = ZMConfig::get('console_color')) === false ? [] : $o ); - if ((ZMConfig::get("global", "runtime")["save_console_log_file"] ?? false) !== false) { - Console::setOutputFile(ZMConfig::get("global", "runtime")["save_console_log_file"]); + if ((ZMConfig::get('global', 'runtime')['save_console_log_file'] ?? false) !== false) { + Console::setOutputFile(ZMConfig::get('global', 'runtime')['save_console_log_file']); } - $timezone = ZMConfig::get("global", "timezone") ?? "Asia/Shanghai"; + $timezone = ZMConfig::get('global', 'timezone') ?? 'Asia/Shanghai'; date_default_timezone_set($timezone); - $this->server_set = ZMConfig::get("global", "swoole"); - $this->server_set["log_level"] = SWOOLE_LOG_DEBUG; - $add_port = ZMConfig::get("global", "remote_terminal")["status"] ?? false; + $this->server_set = ZMConfig::get('global', 'swoole'); + $this->server_set['log_level'] = SWOOLE_LOG_DEBUG; + $add_port = ZMConfig::get('global', 'remote_terminal')['status'] ?? false; //if ($instant_mode) { $this->loadServerEvents(); @@ -137,89 +150,90 @@ class Framework $this->parseCliArgs(self::$argv, $add_port); - if (!isset($this->server_set["max_wait_time"])) { - $this->server_set["max_wait_time"] = 5; + if (!isset($this->server_set['max_wait_time'])) { + $this->server_set['max_wait_time'] = 5; } - $worker = $this->server_set["worker_num"] ?? swoole_cpu_num(); - define("ZM_WORKER_NUM", $worker); + $worker = $this->server_set['worker_num'] ?? swoole_cpu_num(); + define('ZM_WORKER_NUM', $worker); ZMAtomic::init(); - $out["working_dir"] = DataProvider::getWorkingDir(); + $out['working_dir'] = DataProvider::getWorkingDir(); // 打印初始信息 - $out["listen"] = ZMConfig::get("global", "host") . ":" . ZMConfig::get("global", "port"); - if (!isset($this->server_set["worker_num"])) { - if ((ZMConfig::get("global", "runtime")["swoole_server_mode"] ?? SWOOLE_PROCESS) == SWOOLE_PROCESS) { - $out["worker"] = swoole_cpu_num() . " (auto)"; + $out['listen'] = ZMConfig::get('global', 'host') . ':' . ZMConfig::get('global', 'port'); + if (!isset($this->server_set['worker_num'])) { + if ((ZMConfig::get('global', 'runtime')['swoole_server_mode'] ?? SWOOLE_PROCESS) == SWOOLE_PROCESS) { + $out['worker'] = swoole_cpu_num() . ' (auto)'; } else { - $out["single_proc_mode"] = "true"; + $out['single_proc_mode'] = 'true'; } } else { - $out["worker"] = $this->server_set["worker_num"]; + $out['worker'] = $this->server_set['worker_num']; } - $out["environment"] = ($args["env"] ?? null) === null ? "default" : $args["env"]; - $out["log_level"] = Console::getLevel(); - $out["version"] = ZM_VERSION . (LOAD_MODE == 0 ? (" (build " . ZM_VERSION_ID . ")") : ""); - $out["master_pid"] = posix_getpid(); - if (APP_VERSION !== "unknown") $out["app_version"] = APP_VERSION; - if (isset($this->server_set["task_worker_num"])) { - $out["task_worker"] = $this->server_set["task_worker_num"]; + $out['environment'] = ($args['env'] ?? null) === null ? 'default' : $args['env']; + $out['log_level'] = Console::getLevel(); + $out['version'] = ZM_VERSION . (LOAD_MODE == 0 ? (' (build ' . ZM_VERSION_ID . ')') : ''); + $out['master_pid'] = posix_getpid(); + if (APP_VERSION !== 'unknown') { + $out['app_version'] = APP_VERSION; } - if ((ZMConfig::get("global", "sql_config")["sql_host"] ?? "") !== "") { - $conf = ZMConfig::get("global", "sql_config"); - $out["mysql_pool"] = $conf["sql_database"] . "@" . $conf["sql_host"] . ":" . $conf["sql_port"]; + if (isset($this->server_set['task_worker_num'])) { + $out['task_worker'] = $this->server_set['task_worker_num']; } - if ((ZMConfig::get("global", "mysql_config")["host"] ?? "") !== "") { - $conf = ZMConfig::get("global", "mysql_config"); - $out["mysql"] = $conf["dbname"] . "@" . $conf["host"] . ":" . $conf["port"]; + if ((ZMConfig::get('global', 'sql_config')['sql_host'] ?? '') !== '') { + $conf = ZMConfig::get('global', 'sql_config'); + $out['mysql_pool'] = $conf['sql_database'] . '@' . $conf['sql_host'] . ':' . $conf['sql_port']; } - if (ZMConfig::get("global", "redis_config")["host"] !== "") { - $conf = ZMConfig::get("global", "redis_config"); - $out["redis_pool"] = $conf["host"] . ":" . $conf["port"]; + if ((ZMConfig::get('global', 'mysql_config')['host'] ?? '') !== '') { + $conf = ZMConfig::get('global', 'mysql_config'); + $out['mysql'] = $conf['dbname'] . '@' . $conf['host'] . ':' . $conf['port']; } - if (ZMConfig::get("global", "static_file_server")["status"] !== false) { - $out["static_file_server"] = "enabled"; + if (ZMConfig::get('global', 'redis_config')['host'] !== '') { + $conf = ZMConfig::get('global', 'redis_config'); + $out['redis_pool'] = $conf['host'] . ':' . $conf['port']; } - if (self::$argv["show-php-ver"] !== false) { - $out["php_version"] = PHP_VERSION; - $out["swoole_version"] = SWOOLE_VERSION; + if (ZMConfig::get('global', 'static_file_server')['status'] !== false) { + $out['static_file_server'] = 'enabled'; + } + if (self::$argv['show-php-ver'] !== false) { + $out['php_version'] = PHP_VERSION; + $out['swoole_version'] = SWOOLE_VERSION; } if ($add_port) { - $conf = ZMConfig::get("global", "remote_terminal"); - $out["terminal"] = $conf["host"] . ":" . $conf["port"]; + $conf = ZMConfig::get('global', 'remote_terminal'); + $out['terminal'] = $conf['host'] . ':' . $conf['port']; } - self::printProps($out, $tty_width, $args["log-theme"] === null); - if ($args["preview"] ?? false) { + self::printProps($out, $tty_width, $args['log-theme'] === null); + if ($args['preview'] ?? false) { exit(); } - self::$server = new Server( - ZMConfig::get("global", "host"), - ZMConfig::get("global", "port"), - ZMConfig::get("global", "runtime")["swoole_server_mode"] ?? SWOOLE_PROCESS + ZMConfig::get('global', 'host'), + ZMConfig::get('global', 'port'), + ZMConfig::get('global', 'runtime')['swoole_server_mode'] ?? SWOOLE_PROCESS ); if ($add_port) { - $conf = ZMConfig::get("global", "remote_terminal") ?? [ - 'status' => true, - 'host' => '127.0.0.1', - 'port' => 20002, - 'token' => '' - ]; - $welcome_msg = Console::setColor("Welcome! You can use `help` for usage.", "green"); + $conf = ZMConfig::get('global', 'remote_terminal') ?? [ + 'status' => true, + 'host' => '127.0.0.1', + 'port' => 20002, + 'token' => '', + ]; + $welcome_msg = Console::setColor('Welcome! You can use `help` for usage.', 'green'); /** @var Port $port */ - $port = self::$server->listen($conf["host"], $conf["port"], SWOOLE_SOCK_TCP); + $port = self::$server->listen($conf['host'], $conf['port'], SWOOLE_SOCK_TCP); $port->set([ - 'open_http_protocol' => false + 'open_http_protocol' => false, ]); - $port->on('connect', function (?\Swoole\Server $serv, $fd) use ($port, $welcome_msg, $conf) { - ManagerGM::pushConnect($fd, "terminal"); - $serv->send($fd, file_get_contents(working_dir() . "/config/motd.txt")); - if (!empty($conf["token"])) { - $serv->send($fd, "Please input token: "); + $port->on('connect', function (?\Swoole\Server $serv, $fd) use ($welcome_msg, $conf) { + ManagerGM::pushConnect($fd, 'terminal'); + $serv->send($fd, file_get_contents(working_dir() . '/config/motd.txt')); + if (!empty($conf['token'])) { + $serv->send($fd, 'Please input token: '); } else { $serv->send($fd, $welcome_msg . "\n>>> "); } @@ -228,44 +242,48 @@ class Framework $port->on('receive', function ($serv, $fd, $reactor_id, $data) use ($welcome_msg, $conf) { ob_start(); try { - $arr = LightCacheInside::get("light_array", "input_token") ?? []; + $arr = LightCacheInside::get('light_array', 'input_token') ?? []; if (empty($arr[$fd] ?? '')) { - if ($conf["token"] != '') { + if ($conf['token'] != '') { $token = trim($data); - if ($token === $conf["token"]) { - SpinLock::transaction("input_token", function () use ($fd, $token) { - $arr = LightCacheInside::get("light_array", "input_token"); + if ($token === $conf['token']) { + SpinLock::transaction('input_token', function () use ($fd, $token) { + $arr = LightCacheInside::get('light_array', 'input_token'); $arr[$fd] = $token; - LightCacheInside::set("light_array", "input_token", $arr); + LightCacheInside::set('light_array', 'input_token', $arr); }); - $serv->send($fd, Console::setColor("Auth success!!\n", "green")); + $serv->send($fd, Console::setColor("Auth success!!\n", 'green')); $serv->send($fd, $welcome_msg . "\n>>> "); } else { - $serv->send($fd, Console::setColor("Auth failed!!\n", "red")); + $serv->send($fd, Console::setColor("Auth failed!!\n", 'red')); $serv->close($fd); } return; } } - if (trim($data) == "exit" || trim($data) == "q") { - $serv->send($fd, Console::setColor("Bye!\n", "blue")); + if (trim($data) == 'exit' || trim($data) == 'q') { + $serv->send($fd, Console::setColor("Bye!\n", 'blue')); $serv->close($fd); return; } Terminal::executeCommand(trim($data)); } catch (Exception $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00009") . "Uncaught exception " . get_class($e) . " when calling \"open\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00009') . 'Uncaught exception ' . get_class($e) . ' when calling "open": ' . $error_msg); Console::trace(); } catch (Error $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00009") . "Uncaught " . get_class($e) . " when calling \"open\": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00009') . 'Uncaught ' . get_class($e) . ' when calling "open": ' . $error_msg); Console::trace(); } $r = ob_get_clean(); - if (!empty($r)) $serv->send($fd, $r); - if (!in_array(trim($data), ['r', 'reload'])) $serv->send($fd, ">>> "); + if (!empty($r)) { + $serv->send($fd, $r); + } + if (!in_array(trim($data), ['r', 'reload'])) { + $serv->send($fd, '>>> '); + } }); $port->on('close', function ($serv, $fd) { @@ -282,16 +300,16 @@ class Framework $asd = get_included_files(); // 注册 Swoole Server 的事件 $this->registerServerEvents(); - $r = ZMConfig::get("global", "light_cache") ?? [ - 'size' => 512, //最多允许储存的条数(需要2的倍数) - 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) - 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) - 'persistence_path' => DataProvider::getDataFolder() . '_cache.json', - 'auto_save_interval' => 900 - ]; + $r = ZMConfig::get('global', 'light_cache') ?? [ + 'size' => 512, //最多允许储存的条数(需要2的倍数) + 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) + 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) + 'persistence_path' => DataProvider::getDataFolder() . '_cache.json', + 'auto_save_interval' => 900, + ]; LightCache::init($r); LightCacheInside::init(); - SpinLock::init($r["size"]); + SpinLock::init($r['size']); set_error_handler(function ($error_no, $error_msg, $error_file, $error_line) { switch ($error_no) { case E_WARNING: @@ -327,31 +345,16 @@ class Framework return true; }, E_ALL | E_STRICT); } catch (Exception $e) { - Console::error("Framework初始化出现错误,请检查!"); - Console::error(zm_internal_errcode("E00010") . $e->getMessage()); + Console::error('Framework初始化出现错误,请检查!'); + Console::error(zm_internal_errcode('E00010') . $e->getMessage()); Console::debug($e); - die; + exit; } } - private static function printMotd($tty_width) - { - if (file_exists(DataProvider::getSourceRootDir() . "/config/motd.txt")) { - $motd = file_get_contents(DataProvider::getSourceRootDir() . "/config/motd.txt"); - } else { - $motd = file_get_contents(__DIR__ . "/../../config/motd.txt"); - } - $motd = explode("\n", $motd); - foreach ($motd as $k => $v) $motd[$k] = substr($v, 0, $tty_width); - $motd = implode("\n", $motd); - echo $motd; - } - /** * 将各进程的pid写入文件,以备后续崩溃及僵尸进程处理使用 - * @param int $type * @param int|string $pid - * @param array $data * @internal */ public static function saveProcessState(int $type, $pid, array $data = []) @@ -362,7 +365,7 @@ class Framework $json = [ 'pid' => intval($pid), 'stdout' => $data['stdout'], - 'daemon' => $data['daemon'] + 'daemon' => $data['daemon'], ]; file_put_contents($file, json_encode($json, JSON_UNESCAPED_UNICODE)); return; @@ -387,10 +390,9 @@ class Framework /** * 用于框架内部获取多进程运行状态的函数 - * @param int $type - * @param null $id_or_name - * @return false|int|mixed + * @param mixed $id_or_name * @throws ZMKnownException + * @return false|int|mixed * @internal */ public static function getProcessState(int $type, $id_or_name = null) @@ -398,24 +400,42 @@ class Framework $file = _zm_pid_dir(); switch ($type) { case ZM_PROCESS_MASTER: - if (!file_exists($file . '/master.json')) return false; + if (!file_exists($file . '/master.json')) { + return false; + } $json = json_decode(file_get_contents($file . '/master.json'), true); - if ($json !== null) return $json; - else return false; + if ($json !== null) { + return $json; + } + return false; case ZM_PROCESS_MANAGER: - if (!file_exists($file . '/manager.pid')) return false; + if (!file_exists($file . '/manager.pid')) { + return false; + } return intval(file_get_contents($file . '/manager.pid')); case ZM_PROCESS_WORKER: - if (!is_int($id_or_name)) throw new ZMKnownException('E99999', 'worker_id必须为整数'); - if (!file_exists($file . '/worker.' . $id_or_name . '.pid')) return false; + if (!is_int($id_or_name)) { + throw new ZMKnownException('E99999', 'worker_id必须为整数'); + } + if (!file_exists($file . '/worker.' . $id_or_name . '.pid')) { + return false; + } return intval(file_get_contents($file . '/worker.' . $id_or_name . '.pid')); case ZM_PROCESS_USER: - if (!is_string($id_or_name)) throw new ZMKnownException('E99999', 'process_name必须为字符串'); - if (!file_exists($file . '/user.' . $id_or_name . '.pid')) return false; + if (!is_string($id_or_name)) { + throw new ZMKnownException('E99999', 'process_name必须为字符串'); + } + if (!file_exists($file . '/user.' . $id_or_name . '.pid')) { + return false; + } return intval(file_get_contents($file . '/user.' . $id_or_name . '.pid')); case ZM_PROCESS_TASKWORKER: - if (!is_int($id_or_name)) throw new ZMKnownException('E99999', 'worker_id必须为整数'); - if (!file_exists($file . '/taskworker.' . $id_or_name . '.pid')) return false; + if (!is_int($id_or_name)) { + throw new ZMKnownException('E99999', 'worker_id必须为整数'); + } + if (!file_exists($file . '/taskworker.' . $id_or_name . '.pid')) { + return false; + } return intval(file_get_contents($file . '/taskworker.' . $id_or_name . '.pid')); default: return false; @@ -423,8 +443,7 @@ class Framework } /** - * @param int $type - * @param null $id_or_name + * @param null $id_or_name * @throws ZMKnownException * @internal */ @@ -433,26 +452,42 @@ class Framework switch ($type) { case ZM_PROCESS_MASTER: $file = _zm_pid_dir() . '/master.json'; - if (file_exists($file)) unlink($file); + if (file_exists($file)) { + unlink($file); + } return; case ZM_PROCESS_MANAGER: $file = _zm_pid_dir() . '/manager.pid'; - if (file_exists($file)) unlink($file); + if (file_exists($file)) { + unlink($file); + } return; case ZM_PROCESS_WORKER: - if (!is_int($id_or_name)) throw new ZMKnownException('E99999', 'worker_id必须为整数'); + if (!is_int($id_or_name)) { + throw new ZMKnownException('E99999', 'worker_id必须为整数'); + } $file = _zm_pid_dir() . '/worker.' . $id_or_name . '.pid'; - if (file_exists($file)) unlink($file); + if (file_exists($file)) { + unlink($file); + } return; case ZM_PROCESS_USER: - if (!is_string($id_or_name)) throw new ZMKnownException('E99999', 'process_name必须为字符串'); + if (!is_string($id_or_name)) { + throw new ZMKnownException('E99999', 'process_name必须为字符串'); + } $file = _zm_pid_dir() . '/user.' . $id_or_name . '.pid'; - if (file_exists($file)) unlink($file); + if (file_exists($file)) { + unlink($file); + } return; case ZM_PROCESS_TASKWORKER: - if (!is_int($id_or_name)) throw new ZMKnownException('E99999', 'worker_id必须为整数'); + if (!is_int($id_or_name)) { + throw new ZMKnownException('E99999', 'worker_id必须为整数'); + } $file = _zm_pid_dir() . '/taskworker.' . $id_or_name . '.pid'; - if (file_exists($file)) unlink($file); + if (file_exists($file)) { + unlink($file); + } return; } } @@ -462,33 +497,122 @@ class Framework try { self::$loaded_files = get_included_files(); self::$server->start(); - zm_atomic("server_is_stopped")->set(1); - Console::log("zhamao-framework is stopped."); + zm_atomic('server_is_stopped')->set(1); + Console::log('zhamao-framework is stopped.'); } catch (Throwable $e) { - die(zm_internal_errcode("E00011") . "Framework has an uncaught " . get_class($e) . ": " . $e->getMessage() . PHP_EOL); + exit(zm_internal_errcode('E00011') . 'Framework has an uncaught ' . get_class($e) . ': ' . $e->getMessage() . PHP_EOL); } } + public static function printProps($out, $tty_width, $colorful = true) + { + $max_border = $tty_width < 65 ? $tty_width : 65; + if (LOAD_MODE == 0) { + echo Console::setColor("* Framework started with source mode.\n", $colorful ? 'yellow' : ''); + } + echo str_pad('', $max_border, '=') . PHP_EOL; + + $current_line = 0; + $line_width = []; + $line_data = []; + foreach ($out as $k => $v) { + start: + if (!isset($line_width[$current_line])) { + $line_width[$current_line] = $max_border - 2; + } + //Console::info("行宽[$current_line]:".$line_width[$current_line]); + if ($max_border >= 57) { // 很宽的时候,一行能放两个短行 + if ($line_width[$current_line] == ($max_border - 2)) { //空行 + self::writeNoDouble($k, $v, $line_data, $line_width, $current_line, $colorful, $max_border); + } else { // 不是空行,已经有东西了 + $tmp_line = $k . ': ' . $v; + //Console::info("[$current_line]即将插入后面的东西[".$tmp_line."]"); + if (strlen($tmp_line) > $line_width[$current_line]) { // 地方不够,另起一行 + $line_data[$current_line] = str_replace('| ', '', $line_data[$current_line]); + ++$current_line; + goto start; + } // 地方够,直接写到后面并另起一行 + $line_data[$current_line] .= $k . ': '; + if ($colorful) { + $line_data[$current_line] .= TermColor::color8(32); + } + $line_data[$current_line] .= $v; + if ($colorful) { + $line_data[$current_line] .= TermColor::RESET; + } + ++$current_line; + } + } else { // 不够宽,直接写单行 + self::writeNoDouble($k, $v, $line_data, $line_width, $current_line, $colorful, $max_border); + } + } + foreach ($line_data as $v) { + echo $v . PHP_EOL; + } + echo str_pad('', $max_border, '=') . PHP_EOL; + } + + public static function getTtyWidth(): int + { + $size = exec('stty size'); + if (empty($size)) { + return 65; + } + return (int) explode(' ', trim($size))[1]; + } + + public static function loadFrameworkState() + { + if (!file_exists(DataProvider::getDataFolder() . '.state.json')) { + return []; + } + $r = json_decode(file_get_contents(DataProvider::getDataFolder() . '.state.json'), true); + if ($r === null) { + $r = []; + } + return $r; + } + + public static function saveFrameworkState($data) + { + return file_put_contents(DataProvider::getDataFolder() . '.state.json', json_encode($data, 64 | 128 | 256)); + } + + private static function printMotd($tty_width) + { + if (file_exists(DataProvider::getSourceRootDir() . '/config/motd.txt')) { + $motd = file_get_contents(DataProvider::getSourceRootDir() . '/config/motd.txt'); + } else { + $motd = file_get_contents(__DIR__ . '/../../config/motd.txt'); + } + $motd = explode("\n", $motd); + foreach ($motd as $k => $v) { + $motd[$k] = substr($v, 0, $tty_width); + } + $motd = implode("\n", $motd); + echo $motd; + } + /** * @noinspection PhpIncludeInspection */ private function loadServerEvents() { - if (Phar::running() !== "") { + if (Phar::running() !== '') { ob_start(); - include_once DataProvider::getFrameworkRootDir() . "/src/ZM/script_setup_loader.php"; + include_once DataProvider::getFrameworkRootDir() . '/src/ZM/script_setup_loader.php'; $r = ob_get_clean(); $result_code = 0; } else { - $r = exec(PHP_BINARY . " " . DataProvider::getFrameworkRootDir() . "/src/ZM/script_setup_loader.php", $output, $result_code); + $r = exec(PHP_BINARY . ' ' . DataProvider::getFrameworkRootDir() . '/src/ZM/script_setup_loader.php', $output, $result_code); } if ($result_code !== 0) { - Console::error("Parsing code error!"); + Console::error('Parsing code error!'); exit(1); } $json = json_decode($r, true); if (!is_array($json)) { - Console::warning(zm_internal_errcode("E00012") . "Parsing @SwooleHandler and @OnSetup error!"); + Console::warning(zm_internal_errcode('E00012') . 'Parsing @SwooleHandler and @OnSetup error!'); } $this->setup_events = $json; } @@ -501,30 +625,30 @@ class Framework private function registerServerEvents() { $reader = new AnnotationReader(); - $all = ZMUtil::getClassesPsr4(FRAMEWORK_ROOT_DIR . "/src/ZM/Event/SwooleEvent/", "ZM\\Event\\SwooleEvent"); + $all = ZMUtil::getClassesPsr4(FRAMEWORK_ROOT_DIR . '/src/ZM/Event/SwooleEvent/', 'ZM\\Event\\SwooleEvent'); foreach ($all as $v) { $class = new $v(); $reflection_class = new ReflectionClass($class); $anno_class = $reader->getClassAnnotation($reflection_class, SwooleHandler::class); if ($anno_class !== null) { // 类名形式的注解 - $this->setup_events["event"][] = [ - "class" => $v, - "method" => "onCall", - "event" => $anno_class->event + $this->setup_events['event'][] = [ + 'class' => $v, + 'method' => 'onCall', + 'event' => $anno_class->event, ]; } } - foreach (($this->setup_events["setup"] ?? []) as $v) { - Console::debug('Calling @OnSetup: ' . $v["class"]); - $c = ZMUtil::getModInstance($v["class"]); - $method = $v["method"]; - $c->$method(); + foreach (($this->setup_events['setup'] ?? []) as $v) { + Console::debug('Calling @OnSetup: ' . $v['class']); + $c = ZMUtil::getModInstance($v['class']); + $method = $v['method']; + $c->{$method}(); } - foreach ($this->setup_events["event"] as $v) { - self::$server->on($v["event"], function (...$param) use ($v) { - ZMUtil::getModInstance($v["class"])->{$v["method"]}(...$param); + foreach ($this->setup_events['event'] as $v) { + self::$server->on($v['event'], function (...$param) use ($v) { + ZMUtil::getModInstance($v['class'])->{$v['method']}(...$param); }); } } @@ -544,33 +668,33 @@ class Framework switch ($x) { case 'worker-num': if (intval($y) >= 1 && intval($y) <= 1024) { - $this->server_set["worker_num"] = intval($y); + $this->server_set['worker_num'] = intval($y); } else { - Console::warning(zm_internal_errcode("E00013") . "Invalid worker num! Turn to default value (" . ($this->server_set["worker_num"] ?? swoole_cpu_num()) . ")"); + Console::warning(zm_internal_errcode('E00013') . 'Invalid worker num! Turn to default value (' . ($this->server_set['worker_num'] ?? swoole_cpu_num()) . ')'); } break; case 'task-worker-num': if (intval($y) >= 1 && intval($y) <= 1024) { - $this->server_set["task_worker_num"] = intval($y); - $this->server_set["task_enable_coroutine"] = true; + $this->server_set['task_worker_num'] = intval($y); + $this->server_set['task_enable_coroutine'] = true; } else { - Console::warning(zm_internal_errcode("E00013") . "Invalid worker num! Turn to default value (0)"); + Console::warning(zm_internal_errcode('E00013') . 'Invalid worker num! Turn to default value (0)'); } break; case 'disable-coroutine': $coroutine_mode = false; break; case 'debug-mode': - self::$argv["disable-safe-exit"] = true; + self::$argv['disable-safe-exit'] = true; $coroutine_mode = false; $terminal_id = null; - self::$argv["watch"] = true; - echo("* You are in debug mode, do not use in production!\n"); + self::$argv['watch'] = true; + echo "* You are in debug mode, do not use in production!\n"; break; case 'daemon': - $this->server_set["daemonize"] = 1; - Console::$theme = "no-color"; - Console::log("已启用守护进程,输出重定向到 " . $this->server_set["log_file"]); + $this->server_set['daemonize'] = 1; + Console::$theme = 'no-color'; + Console::log('已启用守护进程,输出重定向到 ' . $this->server_set['log_file']); $terminal_id = null; break; case 'disable-console-input': @@ -607,38 +731,53 @@ class Framework } } } - $global_hook = ZMConfig::get("global", 'runtime')['swoole_coroutine_hook_flags'] ?? (SWOOLE_HOOK_ALL & (~SWOOLE_HOOK_CURL)); - if ($coroutine_mode) Runtime::enableCoroutine(true, $global_hook); - else Runtime::enableCoroutine(false, SWOOLE_HOOK_ALL); + $global_hook = ZMConfig::get('global', 'runtime')['swoole_coroutine_hook_flags'] ?? (SWOOLE_HOOK_ALL & (~SWOOLE_HOOK_CURL)); + if ($coroutine_mode) { + Runtime::enableCoroutine(true, $global_hook); + } else { + Runtime::enableCoroutine(false, SWOOLE_HOOK_ALL); + } } private static function writeNoDouble($k, $v, &$line_data, &$line_width, &$current_line, $colorful, $max_border) { - $tmp_line = $k . ": " . $v; + $tmp_line = $k . ': ' . $v; //Console::info("写入[".$tmp_line."]"); if (strlen($tmp_line) > $line_width[$current_line]) { //输出的内容太多了,以至于一行都放不下一个,要折行 - $title_strlen = strlen($k . ": "); + $title_strlen = strlen($k . ': '); $content_len = $line_width[$current_line] - $title_strlen; - $line_data[$current_line] = " " . $k . ": "; - if ($colorful) $line_data[$current_line] .= TermColor::color8(32); + $line_data[$current_line] = ' ' . $k . ': '; + if ($colorful) { + $line_data[$current_line] .= TermColor::color8(32); + } $line_data[$current_line] .= substr($v, 0, $content_len); - if ($colorful) $line_data[$current_line] .= TermColor::RESET; + if ($colorful) { + $line_data[$current_line] .= TermColor::RESET; + } $rest = substr($v, $content_len); ++$current_line; // 带标题的第一行满了,折到第二行 do { - if ($colorful) $line_data[$current_line] = TermColor::color8(32); - $line_data[$current_line] .= " " . substr($rest, 0, $max_border - 2); - if ($colorful) $line_data[$current_line] .= TermColor::RESET; + if ($colorful) { + $line_data[$current_line] = TermColor::color8(32); + } + $line_data[$current_line] .= ' ' . substr($rest, 0, $max_border - 2); + if ($colorful) { + $line_data[$current_line] .= TermColor::RESET; + } $rest = substr($rest, $max_border - 2); ++$current_line; } while ($rest > $max_border - 2); // 循环,直到放完 } else { // 不需要折行 //Console::info("不需要折行"); - $line_data[$current_line] = " " . $k . ": "; - if ($colorful) $line_data[$current_line] .= TermColor::color8(32); + $line_data[$current_line] = ' ' . $k . ': '; + if ($colorful) { + $line_data[$current_line] .= TermColor::color8(32); + } $line_data[$current_line] .= $v; - if ($colorful) $line_data[$current_line] .= TermColor::RESET; + if ($colorful) { + $line_data[$current_line] .= TermColor::RESET; + } if ($max_border >= 57) { if (strlen($tmp_line) >= intval(($max_border - 2) / 2)) { // 不需要折行,直接输出一个转下一行 @@ -647,8 +786,8 @@ class Framework } else { // 输出很小,写到前面并分片 //Console::info("输出很小,写到前面并分片"); $space = intval($max_border / 2) - 2 - strlen($tmp_line); - $line_data[$current_line] .= str_pad("", $space); - $line_data[$current_line] .= "| "; // 添加分片 + $line_data[$current_line] .= str_pad('', $space); + $line_data[$current_line] .= '| '; // 添加分片 $line_width[$current_line] -= (strlen($tmp_line) + 3 + $space); } } else { @@ -656,67 +795,4 @@ class Framework } } } - - public static function printProps($out, $tty_width, $colorful = true) - { - $max_border = $tty_width < 65 ? $tty_width : 65; - if (LOAD_MODE == 0) echo Console::setColor("* Framework started with source mode.\n", $colorful ? "yellow" : ""); - echo str_pad("", $max_border, "=") . PHP_EOL; - - $current_line = 0; - $line_width = []; - $line_data = []; - foreach ($out as $k => $v) { - start: - if (!isset($line_width[$current_line])) { - $line_width[$current_line] = $max_border - 2; - } - //Console::info("行宽[$current_line]:".$line_width[$current_line]); - if ($max_border >= 57) { // 很宽的时候,一行能放两个短行 - if ($line_width[$current_line] == ($max_border - 2)) { //空行 - self::writeNoDouble($k, $v, $line_data, $line_width, $current_line, $colorful, $max_border); - } else { // 不是空行,已经有东西了 - $tmp_line = $k . ": " . $v; - //Console::info("[$current_line]即将插入后面的东西[".$tmp_line."]"); - if (strlen($tmp_line) > $line_width[$current_line]) { // 地方不够,另起一行 - $line_data[$current_line] = str_replace("| ", "", $line_data[$current_line]); - ++$current_line; - goto start; - } else { // 地方够,直接写到后面并另起一行 - $line_data[$current_line] .= $k . ": "; - if ($colorful) $line_data[$current_line] .= TermColor::color8(32); - $line_data[$current_line] .= $v; - if ($colorful) $line_data[$current_line] .= TermColor::RESET; - ++$current_line; - } - } - } else { // 不够宽,直接写单行 - self::writeNoDouble($k, $v, $line_data, $line_width, $current_line, $colorful, $max_border); - } - } - foreach ($line_data as $v) { - echo $v . PHP_EOL; - } - echo str_pad("", $max_border, "=") . PHP_EOL; - } - - public static function getTtyWidth(): string - { - $size = exec("stty size"); - if (empty($size)) return 65; - return explode(" ", trim($size))[1]; - } - - public static function loadFrameworkState() - { - if (!file_exists(DataProvider::getDataFolder() . ".state.json")) return []; - $r = json_decode(file_get_contents(DataProvider::getDataFolder() . ".state.json"), true); - if ($r === null) $r = []; - return $r; - } - - public static function saveFrameworkState($data) - { - return file_put_contents(DataProvider::getDataFolder() . ".state.json", json_encode($data, 64 | 128 | 256)); - } } diff --git a/src/ZM/Http/MiddlewareInterface.php b/src/ZM/Http/MiddlewareInterface.php index a0ed6969..65d01ab0 100644 --- a/src/ZM/Http/MiddlewareInterface.php +++ b/src/ZM/Http/MiddlewareInterface.php @@ -1,10 +1,9 @@ response = $response; $this->fd = $response->fd; $this->socket = $response->socket; $this->header = $response->header; $this->cookie = $response->cookie; - if (isset($response->trailer)) + if (isset($response->trailer)) { $this->trailer = $response->trailer; + } + } + + public function __destruct() + { } /** * @return mixed */ - public function initHeader() { + public function initHeader() + { return $this->response->initHeader(); } @@ -53,7 +65,8 @@ class Response * @param $samesite * @return mixed */ - public function cookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null) { + public function cookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null) + { return $this->response->rawcookie($name, $value, $expires, $path, $domain, $secure, $httponly, $samesite); } @@ -68,7 +81,8 @@ class Response * @param $samesite * @return mixed */ - public function setCookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null) { + public function setCookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null) + { return $this->response->setCookie($name, $value, $expires, $path, $domain, $secure, $httponly, $samesite); } @@ -83,7 +97,8 @@ class Response * @param $samesite * @return mixed */ - public function rawcookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null) { + public function rawcookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null) + { return $this->response->rawcookie($name, $value, $expires, $path, $domain, $secure, $httponly, $samesite); } @@ -92,13 +107,17 @@ class Response * @param $reason * @return mixed */ - public function status($http_code, $reason = null) { + public function status($http_code, $reason = null) + { $this->status_code = $http_code; - if (!$this->is_end) return $this->response->status($http_code, $reason); - else return false; + if (!$this->is_end) { + return $this->response->status($http_code, $reason); + } + return false; } - public function getStatusCode() { + public function getStatusCode() + { return $this->status_code ?? 200; } @@ -107,9 +126,12 @@ class Response * @param $reason * @return mixed */ - public function setStatusCode($http_code, $reason = null) { - if (!$this->is_end) return $this->response->setStatusCode($http_code, $reason); - else return false; + public function setStatusCode($http_code, $reason = null) + { + if (!$this->is_end) { + return $this->response->setStatusCode($http_code, $reason); + } + return false; } /** @@ -118,9 +140,12 @@ class Response * @param $ucwords * @return mixed */ - public function header($key, $value, $ucwords = null) { - if (!$this->is_end) return $ucwords === null ? $this->response->header($key, $value) : $this->response->header($key, $value, $ucwords); - else return false; + public function header($key, $value, $ucwords = null) + { + if (!$this->is_end) { + return $ucwords === null ? $this->response->header($key, $value) : $this->response->header($key, $value, $ucwords); + } + return false; } /** @@ -129,9 +154,12 @@ class Response * @param $ucwords * @return mixed */ - public function setHeader($key, $value, $ucwords = null) { - if (!$this->is_end) return $ucwords === null ? $this->response->setHeader($key, $value) : $this->response->setHeader($key, $value, $ucwords); - else return false; + public function setHeader($key, $value, $ucwords = null) + { + if (!$this->is_end) { + return $ucwords === null ? $this->response->setHeader($key, $value) : $this->response->setHeader($key, $value, $ucwords); + } + return false; } /** @@ -139,14 +167,16 @@ class Response * @param $value * @return mixed */ - public function trailer($key, $value) { + public function trailer($key, $value) + { return $this->response->trailer($key, $value); } /** * @return mixed */ - public function ping() { + public function ping() + { return $this->response->ping(); } @@ -154,7 +184,8 @@ class Response * @param $content * @return mixed */ - public function write($content) { + public function write($content) + { return $this->response->write($content); } @@ -162,18 +193,22 @@ class Response * @param $content * @return mixed */ - public function end($content = null) { + public function end($content = null) + { if (!$this->is_end) { $this->is_end = true; return $this->response->end($content); - } else { - return false; } + return false; } - public function isEnd() { return $this->is_end; } + public function isEnd() + { + return $this->is_end; + } - public function endWithStatus($status_code = 200, $content = null) { + public function endWithStatus($status_code = 200, $content = null) + { $this->status($status_code); $this->end($content); } @@ -184,7 +219,8 @@ class Response * @param $length * @return mixed */ - public function sendfile($filename, $offset = null, $length = null) { + public function sendfile($filename, $offset = null, $length = null) + { return $this->response->sendfile($filename, $offset, $length); } @@ -193,7 +229,8 @@ class Response * @param $http_code * @return mixed */ - public function redirect($location, $http_code = null) { + public function redirect($location, $http_code = null) + { $this->is_end = true; return $this->response->redirect($location, $http_code); } @@ -201,7 +238,8 @@ class Response /** * @return mixed */ - public function detach() { + public function detach() + { return $this->response->detach(); } @@ -209,43 +247,43 @@ class Response * @param $fd * @return mixed */ - public static function create($fd) { + public static function create($fd) + { return \Swoole\Http\Response::create($fd); } /** * @return mixed */ - public function upgrade() { + public function upgrade() + { return $this->response->upgrade(); } /** * @param $data - * @param null $opcode - * @param null $flags + * @param null $opcode + * @param null $flags * @return mixed */ - public function push($data, $opcode = null, $flags = null) { + public function push($data, $opcode = null, $flags = null) + { return $this->response->push($data, $opcode, $flags); } /** * @return mixed */ - public function recv() { + public function recv() + { return $this->response->recv(); } /** * @return mixed */ - public function close() { + public function close() + { return $this->response->close(); } - - public function __destruct() { - } - - } diff --git a/src/ZM/Http/RouteManager.php b/src/ZM/Http/RouteManager.php index bd729069..549aef46 100644 --- a/src/ZM/Http/RouteManager.php +++ b/src/ZM/Http/RouteManager.php @@ -1,14 +1,14 @@ getResponse(); - Console::debug("Full path: " . $full_path); + Console::debug('Full path: ' . $full_path); if ($full_path !== false) { if (strpos($full_path, $path) !== 0) { $response->status(403); - $response->end("403 Forbidden"); + $response->end('403 Forbidden'); + return true; + } + if (is_file($full_path)) { + $exp = strtolower(pathinfo($full_path)['extension'] ?? 'unknown'); + $response->setHeader('Content-Type', ZMConfig::get('file_header')[$exp] ?? 'application/octet-stream'); + $response->end(file_get_contents($full_path)); return true; - } else { - if (is_file($full_path)) { - $exp = strtolower(pathinfo($full_path)['extension'] ?? "unknown"); - $response->setHeader("Content-Type", ZMConfig::get("file_header")[$exp] ?? "application/octet-stream"); - $response->end(file_get_contents($full_path)); - return true; - } } } $response->status(404); diff --git a/src/ZM/Module/InstantModule.php b/src/ZM/Module/InstantModule.php index fddca2e0..4f4ec5f6 100644 --- a/src/ZM/Module/InstantModule.php +++ b/src/ZM/Module/InstantModule.php @@ -1,5 +1,7 @@ $v) { - if (is_string($k)) $class->$k = $v; + if (is_string($k)) { + $class->{$k} = $v; + } } $class->method = $callable; $this->events[] = $class; } -} \ No newline at end of file +} diff --git a/src/ZM/Module/ModuleBase.php b/src/ZM/Module/ModuleBase.php index cc9d24e5..4bad0c26 100644 --- a/src/ZM/Module/ModuleBase.php +++ b/src/ZM/Module/ModuleBase.php @@ -1,5 +1,7 @@ module_name = $module_name; } /** * @return mixed */ - public function getModuleName() { + public function getModuleName() + { return $this->module_name; } - /** - * @return array - */ - public function getEvents(): array { + public function getEvents(): array + { return $this->events; } -} \ No newline at end of file +} diff --git a/src/ZM/Module/ModulePacker.php b/src/ZM/Module/ModulePacker.php index b703f67f..a874fd44 100644 --- a/src/ZM/Module/ModulePacker.php +++ b/src/ZM/Module/ModulePacker.php @@ -1,5 +1,6 @@ output_path = $path; - if (!is_dir($path)) mkdir($path, 0755, true); + if (!is_dir($path)) { + mkdir($path, 0755, true); + } } /** * 设置是否覆盖 - * @param bool $override */ - public function setOverride(bool $override = true) { + public function setOverride(bool $override = true) + { $this->override = $override; } @@ -69,15 +79,16 @@ class ModulePacker * 获取模块名字 * @return mixed */ - public function getName() { + public function getName() + { return $this->module['name']; } /** * 获取打包的文件名绝对路径 - * @return string */ - public function getFileName(): string { + public function getFileName(): string + { return $this->filename; } @@ -85,7 +96,8 @@ class ModulePacker * 打包模块 * @throws ZMException */ - public function pack() { + public function pack() + { $this->filename = $this->output_path . '/' . $this->module['name']; if (isset($this->module['version'])) { $this->filename .= '_' . $this->module['version']; @@ -111,28 +123,32 @@ class ModulePacker $this->phar->stopBuffering(); } - private function addFiles() { + private function addFiles() + { $file_list = DataProvider::scanDirFiles($this->module['module-path'], true, false); foreach ($file_list as $v) { $this->phar->addFile($v, $this->getRelativePath($v)); } } - private function getRelativePath($path) { + private function getRelativePath($path) + { return str_replace(realpath(DataProvider::getSourceRootDir()) . '/', '', realpath($path)); } - private function generatePharAutoload(): array { - $pos = strpos($this->module['module-path'], DataProvider::getSourceRootDir().'/'); + private function generatePharAutoload(): array + { + $pos = strpos($this->module['module-path'], DataProvider::getSourceRootDir() . '/'); if ($pos === 0) { - $path_value = substr($this->module['module-path'], strlen(DataProvider::getSourceRootDir().'/')); + $path_value = substr($this->module['module-path'], strlen(DataProvider::getSourceRootDir() . '/')); } else { - throw new ModulePackException(zm_internal_errcode("E99999")); //未定义的错误 + throw new ModulePackException(zm_internal_errcode('E99999')); //未定义的错误 } return ZMUtil::getClassesPsr4($this->module['module-path'], $this->module['namespace'], null, $path_value); } - private function getComposerAutoloadItems(): array { + private function getComposerAutoloadItems(): array + { $composer = json_decode(file_get_contents(DataProvider::getSourceRootDir() . '/composer.json'), true); $path = self::getRelativePath($this->module['module-path']); $item = []; @@ -153,21 +169,22 @@ class ModulePacker * @throws ZMException * @throws Exception */ - private function addLightCacheStore() { + private function addLightCacheStore() + { if (isset($this->module['light-cache-store'])) { $store = []; $r = ZMConfig::get('global', 'light_cache') ?? [ - 'size' => 512, //最多允许储存的条数(需要2的倍数) - 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) - 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) - 'persistence_path' => DataProvider::getDataFolder() . '_cache.json', - 'auto_save_interval' => 900 - ]; + 'size' => 512, //最多允许储存的条数(需要2的倍数) + 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) + 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) + 'persistence_path' => DataProvider::getDataFolder() . '_cache.json', + 'auto_save_interval' => 900, + ]; LightCache::init($r); foreach ($this->module['light-cache-store'] as $v) { $r = LightCache::get($v); if ($r === null) { - Console::warning(zm_internal_errcode("E00045") . 'LightCache 项:' . $v . ' 不存在或值为null,无法为其保存。'); + Console::warning(zm_internal_errcode('E00045') . 'LightCache 项:' . $v . ' 不存在或值为null,无法为其保存。'); } else { $store[$v] = $r; Console::info('打包LightCache持久化项:' . $v); @@ -177,7 +194,8 @@ class ModulePacker } } - private function addModuleConfig() { + private function addModuleConfig() + { $stub_values = [ 'zm-module' => true, 'generated-id' => sha1(strval(microtime(true))), @@ -187,18 +205,19 @@ class ModulePacker 'autoload-psr-4' => $this->generatePharAutoload(), 'unpack' => [ 'composer-autoload-items' => $this->getComposerAutoloadItems(), - 'global-config-override' => $this->module['global-config-override'] ?? false + 'global-config-override' => $this->module['global-config-override'] ?? false, ], - 'allow-hotload' => $this->module["allow-hotload"] ?? false, - 'pack-time' => time() + 'allow-hotload' => $this->module['allow-hotload'] ?? false, + 'pack-time' => time(), ]; $this->phar->addFromString('zmplugin.json', json_encode($stub_values, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); $this->module_config = $stub_values; } - private function addEntry() { + private function addEntry() + { $stub_replace = [ - 'generated_id' => $this->module_config['generated-id'] + 'generated_id' => $this->module_config['generated-id'], ]; $stub_template = str_replace( @@ -216,24 +235,25 @@ class ModulePacker /** * @throws ModulePackException */ - private function addZMDataFiles() { + private function addZMDataFiles() + { $base_dir = realpath(DataProvider::getDataFolder()); - if (is_array($this->module["zm-data-store"] ?? null)) { - foreach ($this->module["zm-data-store"] as $v) { + if (is_array($this->module['zm-data-store'] ?? null)) { + foreach ($this->module['zm-data-store'] as $v) { if (is_dir($base_dir . '/' . $v)) { $v = rtrim($v, '/'); - Console::info("Adding external zm_data dir: " . $v); + Console::info('Adding external zm_data dir: ' . $v); $files = DataProvider::scanDirFiles($base_dir . '/' . $v, true, true); foreach ($files as $single) { $this->phar->addFile($base_dir . '/' . $v . '/' . $single, 'zm_data/' . $v . '/' . $single); } } elseif (is_file($base_dir . '/' . $v)) { - Console::info("Add external zm_data file: " . $v); + Console::info('Add external zm_data file: ' . $v); $this->phar->addFile($base_dir . '/' . $v, 'zm_data/' . $v); } else { - throw new ModulePackException(zm_internal_errcode("E00066")."`zmdata-store` 指定的文件或目录不存在"); + throw new ModulePackException(zm_internal_errcode('E00066') . '`zmdata-store` 指定的文件或目录不存在'); } } } } -} \ No newline at end of file +} diff --git a/src/ZM/Module/ModuleUnpacker.php b/src/ZM/Module/ModuleUnpacker.php index e583ff15..e904e58f 100644 --- a/src/ZM/Module/ModuleUnpacker.php +++ b/src/ZM/Module/ModuleUnpacker.php @@ -1,9 +1,9 @@ module = $module; } /** * 解包模块 - * @param bool $override_light_cache - * @param bool $override_data_files - * @param bool $override_source - * @param bool $ignore_depends - * @return array + * @param bool $ignore_depends * @throws ModulePackException * @throws ZMException */ - public function unpack(bool $override_light_cache = false, bool $override_data_files = false, bool $override_source = false, $ignore_depends = false): array { + public function unpack(bool $override_light_cache = false, bool $override_data_files = false, bool $override_source = false, $ignore_depends = false): array + { $this->checkConfig(); $this->checkDepends($ignore_depends); $this->checkLightCacheStore(); @@ -54,29 +52,30 @@ class ModuleUnpacker /** * 检查模块配置文件是否正确地放在phar包的位置中 - * @return void */ - private function checkConfig() { - $config = "phar://" . $this->module["phar-path"] . "/" . $this->module["module-root-path"] . "/zm.json"; + private function checkConfig() + { + $config = 'phar://' . $this->module['phar-path'] . '/' . $this->module['module-root-path'] . '/zm.json'; $this->module_config = json_decode(file_get_contents($config), true); } /** * 检查模块依赖关系 - * @param bool $ignore_depends + * @param bool $ignore_depends * @throws ModulePackException * @throws ZMException */ - private function checkDepends($ignore_depends = false) { + private function checkDepends($ignore_depends = false) + { $configured = ModuleManager::getConfiguredModules(); - $depends = $this->module_config["depends"] ?? []; + $depends = $this->module_config['depends'] ?? []; foreach ($depends as $k => $v) { if (!isset($configured[$k]) && !$ignore_depends) { - throw new ModulePackException(zm_internal_errcode("E00064") . "模块 " . $this->module_config["name"] . " 依赖的模块 $k 不存在"); + throw new ModulePackException(zm_internal_errcode('E00064') . '模块 ' . $this->module_config['name'] . " 依赖的模块 {$k} 不存在"); } - $current_ver = $configured[$k]["version"] ?? "1.0"; + $current_ver = $configured[$k]['version'] ?? '1.0'; if (!VersionComparator::compareVersionRange($current_ver, $v) && !$ignore_depends) { - throw new ModulePackException(zm_internal_errcode("E00063") . "模块 " . $this->module_config["name"] . " 依赖的模块 $k 版本依赖不符合条件(现有版本: " . $current_ver . ", 需求版本: " . $v . ")"); + throw new ModulePackException(zm_internal_errcode('E00063') . '模块 ' . $this->module_config['name'] . " 依赖的模块 {$k} 版本依赖不符合条件(现有版本: " . $current_ver . ', 需求版本: ' . $v . ')'); } } } @@ -85,10 +84,13 @@ class ModuleUnpacker * 检查 light-cache-store 项是否合规 * @throws ModulePackException */ - private function checkLightCacheStore() { - if (isset($this->module_config["light-cache-store"])) { - $file = json_decode(file_get_contents("phar://" . $this->module["phar-path"] . "/light_cache_store.json"), true); - if ($file === null) throw new ModulePackException(zm_internal_errcode("E00065") . "模块系统检测到打包的模块文件中未含有 `light_cache_store.json` 文件"); + private function checkLightCacheStore() + { + if (isset($this->module_config['light-cache-store'])) { + $file = json_decode(file_get_contents('phar://' . $this->module['phar-path'] . '/light_cache_store.json'), true); + if ($file === null) { + throw new ModulePackException(zm_internal_errcode('E00065') . '模块系统检测到打包的模块文件中未含有 `light_cache_store.json` 文件'); + } $this->light_cache = $file; } } @@ -96,17 +98,18 @@ class ModuleUnpacker /** * @throws ModulePackException */ - private function checkZMDataStore() { - if (is_array($this->module_config["zm-data-store"] ?? null)) { - foreach ($this->module_config["zm-data-store"] as $v) { - if (!file_exists("phar://" . $this->module["phar-path"] . "/zm_data/" . $v)) { - throw new ModulePackException(zm_internal_errcode("E00067") . "压缩包损坏,内部找不到待解压的 zm_data 原始数据"); + private function checkZMDataStore() + { + if (is_array($this->module_config['zm-data-store'] ?? null)) { + foreach ($this->module_config['zm-data-store'] as $v) { + if (!file_exists('phar://' . $this->module['phar-path'] . '/zm_data/' . $v)) { + throw new ModulePackException(zm_internal_errcode('E00067') . '压缩包损坏,内部找不到待解压的 zm_data 原始数据'); } - $file = "phar://" . $this->module["phar-path"] . "/zm_data/" . $v; + $file = 'phar://' . $this->module['phar-path'] . '/zm_data/' . $v; if (is_dir($file)) { $all = DataProvider::scanDirFiles($file, true, true); foreach ($all as $single) { - $this->unpack_data_files[$file . "/" . $single] = DataProvider::getDataFolder() . $v . "/" . $single; + $this->unpack_data_files[$file . '/' . $single] = DataProvider::getDataFolder() . $v . '/' . $single; } } else { $this->unpack_data_files[$file] = DataProvider::getDataFolder() . $v; @@ -115,105 +118,119 @@ class ModuleUnpacker } } - private function mergeComposer() { - $composer_file = DataProvider::getWorkingDir() . "/composer.json"; - if (!file_exists($composer_file)) throw new ModulePackException(zm_internal_errcode("E00068")); + private function mergeComposer() + { + $composer_file = DataProvider::getWorkingDir() . '/composer.json'; + if (!file_exists($composer_file)) { + throw new ModulePackException(zm_internal_errcode('E00068')); + } $composer = json_decode(file_get_contents($composer_file), true); - if (isset($this->module_config["composer-extend-autoload"])) { - $autoload = $this->module_config["composer-extend-autoload"]; - if (isset($autoload["psr-4"])) { - Console::info("Adding extended autoload psr-4 for composer"); - $composer["autoload"]["psr-4"] = isset($composer["autoload"]["psr-4"]) ? array_merge($composer["autoload"]["psr-4"], $autoload["psr-4"]) : $autoload["psr-4"]; + if (isset($this->module_config['composer-extend-autoload'])) { + $autoload = $this->module_config['composer-extend-autoload']; + if (isset($autoload['psr-4'])) { + Console::info('Adding extended autoload psr-4 for composer'); + $composer['autoload']['psr-4'] = isset($composer['autoload']['psr-4']) ? array_merge($composer['autoload']['psr-4'], $autoload['psr-4']) : $autoload['psr-4']; } - if (isset($autoload["files"])) { - Console::info("Adding extended autoload file for composer"); - $composer["autoload"]["files"] = isset($composer["autoload"]["files"]) ? array_merge($composer["autoload"]["files"], $autoload["files"]) : $autoload["files"]; + if (isset($autoload['files'])) { + Console::info('Adding extended autoload file for composer'); + $composer['autoload']['files'] = isset($composer['autoload']['files']) ? array_merge($composer['autoload']['files'], $autoload['files']) : $autoload['files']; } } - if (isset($this->module_config["composer-extend-require"])) { - foreach ($this->module_config["composer-extend-require"] as $k => $v) { - Console::info("Adding extended required composer library: " . $k); - if (!isset($composer[$k])) $composer[$k] = $v; + if (isset($this->module_config['composer-extend-require'])) { + foreach ($this->module_config['composer-extend-require'] as $k => $v) { + Console::info('Adding extended required composer library: ' . $k); + if (!isset($composer[$k])) { + $composer[$k] = $v; + } } } file_put_contents($composer_file, json_encode($composer, 64 | 128 | 256)); } /** + * @param mixed $override_data * @throws ModulePackException */ - private function copyZMDataStore($override_data) { + private function copyZMDataStore($override_data) + { foreach ($this->unpack_data_files as $k => $v) { $pathinfo = pathinfo($v); - if (!is_dir($pathinfo["dirname"])) @mkdir($pathinfo["dirname"], 0755, true); + if (!is_dir($pathinfo['dirname'])) { + @mkdir($pathinfo['dirname'], 0755, true); + } if (is_file($v) && $override_data !== true) { - Console::info("Skipping zm_data file (not overwriting): " . $v); + Console::info('Skipping zm_data file (not overwriting): ' . $v); continue; } - Console::info("Copying zm_data file: " . $v); + Console::info('Copying zm_data file: ' . $v); if (copy($k, $v) !== true) { - throw new ModulePackException(zm_internal_errcode("E00068") . "Cannot copy file: " . $v); + throw new ModulePackException(zm_internal_errcode('E00068') . 'Cannot copy file: ' . $v); } } } - private function copyLightCacheStore($override) { + private function copyLightCacheStore($override) + { $r = ZMConfig::get('global', 'light_cache') ?? [ - 'size' => 512, //最多允许储存的条数(需要2的倍数) - 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) - 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) - 'persistence_path' => DataProvider::getDataFolder() . '_cache.json', - 'auto_save_interval' => 900 - ]; + 'size' => 512, //最多允许储存的条数(需要2的倍数) + 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) + 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) + 'persistence_path' => DataProvider::getDataFolder() . '_cache.json', + 'auto_save_interval' => 900, + ]; LightCache::init($r); foreach (($this->light_cache ?? []) as $k => $v) { - if (LightCache::isset($k) && $override !== true) continue; + if (LightCache::isset($k) && $override !== true) { + continue; + } LightCache::addPersistence($k); LightCache::set($k, $v); } } - private function mergeGlobalConfig() { - if ($this->module["unpack"]["global-config-override"] !== false) { - $prompt = !is_string($this->module["unpack"]["global-config-override"]) ? "请根据模块提供者提供的要求进行修改 global.php 中对应的配置项" : $this->module["unpack"]["global-config-override"]; - Console::warning("模块作者要求用户手动修改 global.php 配置文件中的项目:"); - Console::warning("*" . $prompt); - echo Console::setColor("请输入修改模式,y(使用vim修改)/e(自行使用其他编辑器修改后确认)/N(默认暂不修改):[y/e/N] ", "gold"); + private function mergeGlobalConfig() + { + if ($this->module['unpack']['global-config-override'] !== false) { + $prompt = !is_string($this->module['unpack']['global-config-override']) ? '请根据模块提供者提供的要求进行修改 global.php 中对应的配置项' : $this->module['unpack']['global-config-override']; + Console::warning('模块作者要求用户手动修改 global.php 配置文件中的项目:'); + Console::warning('*' . $prompt); + echo Console::setColor('请输入修改模式,y(使用vim修改)/e(自行使用其他编辑器修改后确认)/N(默认暂不修改):[y/e/N] ', 'gold'); $r = strtolower(trim(fgets(STDIN))); switch ($r) { - case "y": - system("vim " . escapeshellarg(DataProvider::getWorkingDir() . "/config/global.php") . " > `tty`"); - Console::info("已使用 vim 修改!"); + case 'y': + system('vim ' . escapeshellarg(DataProvider::getWorkingDir() . '/config/global.php') . ' > `tty`'); + Console::info('已使用 vim 修改!'); break; - case "e": - echo Console::setColor("请修改后文件点击回车即可继续 [Enter] ", "gold"); + case 'e': + echo Console::setColor('请修改后文件点击回车即可继续 [Enter] ', 'gold'); fgets(STDIN); break; - case "n": - Console::info("暂不修改 global.php"); + case 'n': + Console::info('暂不修改 global.php'); break; } } } - private function copySource(bool $override_source) { - $origin_base = "phar://" . $this->module["phar-path"] . "/" . $this->module["module-root-path"]; + private function copySource(bool $override_source) + { + $origin_base = 'phar://' . $this->module['phar-path'] . '/' . $this->module['module-root-path']; $dir = DataProvider::scanDirFiles($origin_base, true, true); - $base = DataProvider::getSourceRootDir() . "/" . $this->module["module-root-path"]; + $base = DataProvider::getSourceRootDir() . '/' . $this->module['module-root-path']; foreach ($dir as $v) { - $info = pathinfo($base . "/" . $v); - if (!is_dir($info["dirname"])) { - @mkdir($info["dirname"], 0755, true); + $info = pathinfo($base . '/' . $v); + if (!is_dir($info['dirname'])) { + @mkdir($info['dirname'], 0755, true); } - if (is_file($base . "/" . $v) && $override_source !== true) { - Console::info("Skipping source file (not overwriting): " . $v); + if (is_file($base . '/' . $v) && $override_source !== true) { + Console::info('Skipping source file (not overwriting): ' . $v); continue; } - Console::info("Releasing source file: " . $this->module["module-root-path"] . "/" . $v); + Console::info('Releasing source file: ' . $this->module['module-root-path'] . '/' . $v); - if (copy($origin_base . "/" . $v, $base . "/" . $v) !== true) { - throw new ModulePackException(zm_internal_errcode("E00068") . "Cannot copy file: " . $v); + if (copy($origin_base . '/' . $v, $base . '/' . $v) !== true) { + throw new ModulePackException(zm_internal_errcode('E00068') . 'Cannot copy file: ' . $v); } } } -} \ No newline at end of file +} diff --git a/src/ZM/Module/QQBot.php b/src/ZM/Module/QQBot.php index 4719b35d..0b190c3f 100644 --- a/src/ZM/Module/QQBot.php +++ b/src/ZM/Module/QQBot.php @@ -1,5 +1,6 @@ getFrame()->data, true); $this->handle($data); } /** * @param $data - * @param int $level + * @param int $level * @throws InterruptException */ - public function handle($data, $level = 0) { + public function handle($data, $level = 0) + { try { - if ($level > 10) return; - set_coroutine_params(["data" => $data]); - if (isset($data["post_type"])) { + if ($level > 10) { + return; + } + set_coroutine_params(['data' => $data]); + if (isset($data['post_type'])) { //echo TermColor::ITALIC.json_encode($data, 128|256).TermColor::RESET.PHP_EOL; - ctx()->setCache("level", $level); + ctx()->setCache('level', $level); //Console::debug("Calling CQ Event from fd=" . ctx()->getConnection()->getFd()); - if ($data["post_type"] != "meta_event") { - $r = $this->dispatchBeforeEvents($data, "pre"); // before在这里执行,元事件不执行before为减少不必要的调试日志 - if ($r->store === "block") EventDispatcher::interrupt(); + if ($data['post_type'] != 'meta_event') { + $r = $this->dispatchBeforeEvents($data, 'pre'); // before在这里执行,元事件不执行before为减少不必要的调试日志 + if ($r->store === 'block') { + EventDispatcher::interrupt(); + } } //Console::warning("最上数据包:".json_encode($data)); } - if (isset($data["echo"]) || isset($data["post_type"])) { - if (CoMessage::resumeByWS()) EventDispatcher::interrupt(); + if (isset($data['echo']) || isset($data['post_type'])) { + if (CoMessage::resumeByWS()) { + EventDispatcher::interrupt(); + } } - if (($data["post_type"] ?? "meta_event") != "meta_event") { - $r = $this->dispatchBeforeEvents($data, "post"); // before在这里执行,元事件不执行before为减少不必要的调试日志 - if ($r->store === "block") EventDispatcher::interrupt(); + if (($data['post_type'] ?? 'meta_event') != 'meta_event') { + $r = $this->dispatchBeforeEvents($data, 'post'); // before在这里执行,元事件不执行before为减少不必要的调试日志 + if ($r->store === 'block') { + EventDispatcher::interrupt(); + } + } + if (isset($data['post_type'])) { + $this->dispatchEvents($data); + } else { + $this->dispatchAPIResponse($data); } - if (isset($data["post_type"])) $this->dispatchEvents($data); - else $this->dispatchAPIResponse($data); - if (($data["post_type"] ?? "meta_event") != "meta_event") { + if (($data['post_type'] ?? 'meta_event') != 'meta_event') { $r = $this->dispatchAfterEvents($data); // before在这里执行,元事件不执行before为减少不必要的调试日志 - if ($r->store === "block") EventDispatcher::interrupt(); + if ($r->store === 'block') { + EventDispatcher::interrupt(); + } } - } /** @noinspection PhpRedundantCatchClauseInspection */ catch (WaitTimeoutException $e) { - if (($data["post_type"] ?? "meta_event") != "meta_event") { + } /* @noinspection PhpRedundantCatchClauseInspection */ catch (WaitTimeoutException $e) { + if (($data['post_type'] ?? 'meta_event') != 'meta_event') { $r = $this->dispatchAfterEvents($data); // before在这里执行,元事件不执行before为减少不必要的调试日志 - if ($r->store === "block") EventDispatcher::interrupt(); + if ($r->store === 'block') { + EventDispatcher::interrupt(); + } } $e->module->finalReply($e->getMessage()); } catch (InterruptException $e) { - if (($data["post_type"] ?? "meta_event") != "meta_event") { + if (($data['post_type'] ?? 'meta_event') != 'meta_event') { $r = $this->dispatchAfterEvents($data); // before在这里执行,元事件不执行before为减少不必要的调试日志 - if ($r->store === "block") EventDispatcher::interrupt(); + if ($r->store === 'block') { + EventDispatcher::interrupt(); + } } throw $e; } @@ -85,22 +104,24 @@ class QQBot /** * @param $data * @param $time - * @return EventDispatcher * @throws Exception */ - public function dispatchBeforeEvents($data, $time): EventDispatcher { + public function dispatchBeforeEvents($data, $time): EventDispatcher + { $before = new EventDispatcher(CQBefore::class); - if ($time === "pre") { + if ($time === 'pre') { $before->setRuleFunction(function ($v) use ($data) { - return $v->level >= 200 && $v->cq_event == $data["post_type"]; + return $v->level >= 200 && $v->cq_event == $data['post_type']; }); } else { $before->setRuleFunction(function ($v) use ($data) { - return $v->level < 200 && $v->cq_event == $data["post_type"]; + return $v->level < 200 && $v->cq_event == $data['post_type']; }); } $before->setReturnFunction(function ($result) { - if (!$result) EventDispatcher::interrupt("block"); + if (!$result) { + EventDispatcher::interrupt('block'); + } }); $before->dispatchEvents($data); return $before; @@ -111,23 +132,32 @@ class QQBot * @throws InterruptException * @throws Exception */ - private function dispatchEvents($data) { + private function dispatchEvents($data) + { //Console::warning("最xia数据包:".json_encode($data)); - switch ($data["post_type"]) { - case "message": + switch ($data['post_type']) { + case 'message': //分发CQCommand事件 $dispatcher = new EventDispatcher(CQCommand::class); $dispatcher->setReturnFunction(function ($result) { - if (is_string($result)) ctx()->reply($result); - if (ctx()->getCache("has_reply") === true) EventDispatcher::interrupt(); + if (is_string($result)) { + ctx()->reply($result); + } + if (ctx()->getCache('has_reply') === true) { + EventDispatcher::interrupt(); + } }); $s = MessageUtil::matchCommand(ctx()->getStringMessage(), ctx()->getData()); if ($s->status !== false) { - if (!empty($s->match)) ctx()->setCache("match", $s->match); + if (!empty($s->match)) { + ctx()->setCache('match', $s->match); + } $dispatcher->dispatchEvent($s->object, null); - if (is_string($dispatcher->store)) ctx()->reply($dispatcher->store); - if (ctx()->getCache("has_reply") === true) { - $policy = ZMConfig::get("global", "onebot")['message_command_policy'] ?? 'interrupt'; + if (is_string($dispatcher->store)) { + ctx()->reply($dispatcher->store); + } + if (ctx()->getCache('has_reply') === true) { + $policy = ZMConfig::get('global', 'onebot')['message_command_policy'] ?? 'interrupt'; switch ($policy) { case 'interrupt': EventDispatcher::interrupt(); @@ -135,7 +165,7 @@ class QQBot case 'continue': break; default: - throw new Exception("未知的消息命令策略:" . $policy); + throw new Exception('未知的消息命令策略:' . $policy); } } } @@ -143,54 +173,57 @@ class QQBot //分发CQMessage事件 $msg_dispatcher = new EventDispatcher(CQMessage::class); $msg_dispatcher->setRuleFunction(function ($v) { - return ($v->message == '' || ($v->message == ctx()->getStringMessage())) && - ($v->user_id == 0 || ($v->user_id == ctx()->getUserId())) && - ($v->group_id == 0 || ($v->group_id == (ctx()->getGroupId() ?? 0))) && - ($v->message_type == '' || ($v->message_type == ctx()->getMessageType())) && - ($v->raw_message == '' || ($v->raw_message == context()->getData()["raw_message"])); + return ($v->message == '' || ($v->message == ctx()->getStringMessage())) + && ($v->user_id == 0 || ($v->user_id == ctx()->getUserId())) + && ($v->group_id == 0 || ($v->group_id == (ctx()->getGroupId() ?? 0))) + && ($v->message_type == '' || ($v->message_type == ctx()->getMessageType())) + && ($v->raw_message == '' || ($v->raw_message == context()->getData()['raw_message'])); }); $msg_dispatcher->setReturnFunction(function ($result) { - if (is_string($result)) ctx()->reply($result); + if (is_string($result)) { + ctx()->reply($result); + } }); $msg_dispatcher->dispatchEvents(ctx()->getMessage()); return; - case "meta_event": + case 'meta_event': //Console::success("当前数据包:".json_encode(ctx()->getData())); $dispatcher = new EventDispatcher(CQMetaEvent::class); $dispatcher->setRuleFunction(function (CQMetaEvent $v) { - return ($v->meta_event_type == '' || ($v->meta_event_type != '' && $v->meta_event_type == ctx()->getData()["meta_event_type"])); + return $v->meta_event_type == '' || ($v->meta_event_type != '' && $v->meta_event_type == ctx()->getData()['meta_event_type']); }); //eval(BP); $dispatcher->dispatchEvents(ctx()->getData()); return; - case "notice": + case 'notice': $dispatcher = new EventDispatcher(CQNotice::class); $dispatcher->setRuleFunction(function (CQNotice $v) { return - ($v->notice_type == '' || ($v->notice_type != '' && $v->notice_type == ctx()->getData()["notice_type"])) && - ($v->sub_type == '' || ($v->sub_type != '' && $v->sub_type == ctx()->getData()["sub_type"])) && - ($v->group_id == '' || ($v->group_id != '' && $v->group_id == ctx()->getData()["group_id"])) && - ($v->operator_id == '' || ($v->operator_id != '' && $v->operator_id == ctx()->getData()["operator_id"])); + ($v->notice_type == '' || ($v->notice_type != '' && $v->notice_type == ctx()->getData()['notice_type'])) + && ($v->sub_type == '' || ($v->sub_type != '' && $v->sub_type == ctx()->getData()['sub_type'])) + && ($v->group_id == '' || ($v->group_id != '' && $v->group_id == ctx()->getData()['group_id'])) + && ($v->operator_id == '' || ($v->operator_id != '' && $v->operator_id == ctx()->getData()['operator_id'])); }); $dispatcher->dispatchEvents(ctx()->getData()); return; - case "request": + case 'request': $dispatcher = new EventDispatcher(CQRequest::class); $dispatcher->setRuleFunction(function (CQRequest $v) { - return ($v->request_type == '' || ($v->request_type != '' && $v->request_type == ctx()->getData()['request_type'])) && - ($v->sub_type == '' || ($v->sub_type != '' && $v->sub_type == ctx()->getData()['sub_type'])) && - ($v->user_id == 0 || ($v->user_id != 0 && $v->user_id == ctx()->getData()["user_id"])) && - ($v->comment == '' || ($v->comment != '' && $v->comment == ctx()->getData()['comment'])); + return ($v->request_type == '' || ($v->request_type != '' && $v->request_type == ctx()->getData()['request_type'])) + && ($v->sub_type == '' || ($v->sub_type != '' && $v->sub_type == ctx()->getData()['sub_type'])) + && ($v->user_id == 0 || ($v->user_id != 0 && $v->user_id == ctx()->getData()['user_id'])) + && ($v->comment == '' || ($v->comment != '' && $v->comment == ctx()->getData()['comment'])); }); $dispatcher->dispatchEvents(ctx()->getData()); return; } } - private function dispatchAfterEvents($data): EventDispatcher { + private function dispatchAfterEvents($data): EventDispatcher + { $after = new EventDispatcher(CQAfter::class); $after->setRuleFunction(function ($v) use ($data) { - return $v->cq_event == $data["post_type"]; + return $v->cq_event == $data['post_type']; }); $after->dispatchEvents($data); return $after; @@ -200,11 +233,12 @@ class QQBot * @param $req * @throws Exception */ - private function dispatchAPIResponse($req) { - set_coroutine_params(["cq_response" => $req]); + private function dispatchAPIResponse($req) + { + set_coroutine_params(['cq_response' => $req]); $dispatcher = new EventDispatcher(CQAPIResponse::class); $dispatcher->setRuleFunction(function (CQAPIResponse $response) { - return $response->retcode == ctx()->getCQResponse()["retcode"]; + return $response->retcode == ctx()->getCQResponse()['retcode']; }); $dispatcher->dispatchEvents($req); } diff --git a/src/ZM/MySQL/MySQLConnection.php b/src/ZM/MySQL/MySQLConnection.php index 1915b10e..bb40044e 100644 --- a/src/ZM/MySQL/MySQLConnection.php +++ b/src/ZM/MySQL/MySQLConnection.php @@ -1,9 +1,11 @@ -conn = SqlPoolStorage::$sql_pool->getConnection(); } - public function prepare($sql, $options = []) { + public function __destruct() + { + Console::debug('Destructing!!!'); + SqlPoolStorage::$sql_pool->putConnection($this->conn); + } + + public function prepare($sql, $options = []) + { try { - Console::debug("Running SQL prepare: ".$sql); + Console::debug('Running SQL prepare: ' . $sql); $statement = $this->conn->prepare($sql, $options); assert(($statement instanceof PDOStatementProxy) || ($statement instanceof PDOStatement)); } catch (PDOException $exception) { @@ -36,7 +46,8 @@ class MySQLConnection implements Connection return new MySQLStatement($statement); } - public function query(...$args) { + public function query(...$args) + { try { $statement = $this->conn->query(...$args); assert(($statement instanceof PDOStatementProxy) || ($statement instanceof PDOStatement)); @@ -46,13 +57,15 @@ class MySQLConnection implements Connection return new MySQLStatement($statement); } - public function quote($value, $type = ParameterType::STRING) { + public function quote($value, $type = ParameterType::STRING) + { return $this->conn->quote($value, $type); } - public function exec($sql) { + public function exec($sql) + { try { - Console::debug("Running SQL exec: ".$sql); + Console::debug('Running SQL exec: ' . $sql); $statement = $this->conn->exec($sql); assert($statement !== false); return $statement; @@ -61,7 +74,8 @@ class MySQLConnection implements Connection } } - public function lastInsertId($name = null) { + public function lastInsertId($name = null) + { try { return $name === null ? $this->conn->lastInsertId() : $this->conn->lastInsertId($name); } catch (PDOException $exception) { @@ -69,28 +83,28 @@ class MySQLConnection implements Connection } } - public function beginTransaction() { + public function beginTransaction() + { return $this->conn->beginTransaction(); } - public function commit() { + public function commit() + { return $this->conn->commit(); } - public function rollBack() { + public function rollBack() + { return $this->conn->rollBack(); } - public function errorCode() { + public function errorCode() + { return $this->conn->errorCode(); } - public function errorInfo() { + public function errorInfo() + { return $this->conn->errorInfo(); } - - public function __destruct() { - Console::debug("Destructing!!!"); - SqlPoolStorage::$sql_pool->putConnection($this->conn); - } -} \ No newline at end of file +} diff --git a/src/ZM/MySQL/MySQLDriver.php b/src/ZM/MySQL/MySQLDriver.php index ec9e4634..70c837e1 100644 --- a/src/ZM/MySQL/MySQLDriver.php +++ b/src/ZM/MySQL/MySQLDriver.php @@ -1,9 +1,9 @@ count++; + public function getConnection() + { + ++$this->count; return parent::get(); } /** * @param PDO|PDOProxy $connection */ - public function putConnection($connection) { - $this->count--; + public function putConnection($connection) + { + --$this->count; parent::put($connection); } - public function getCount() { + public function getCount() + { return $this->count; } -} \ No newline at end of file +} diff --git a/src/ZM/MySQL/MySQLQueryBuilder.php b/src/ZM/MySQL/MySQLQueryBuilder.php index 01ab31a4..189efe8b 100644 --- a/src/ZM/MySQL/MySQLQueryBuilder.php +++ b/src/ZM/MySQL/MySQLQueryBuilder.php @@ -1,9 +1,9 @@ getConnection()); $this->wrapper = $wrapper; } /** - * @return int|MySQLStatementWrapper * @throws DbException + * @return int|MySQLStatementWrapper */ - public function execute() { + public function execute() + { if ($this->getType() === self::SELECT) { return $this->wrapper->executeQuery($this->getSQL(), $this->getParameters(), $this->getParameterTypes()); } return $this->wrapper->executeStatement($this->getSQL(), $this->getParameters(), $this->getParameterTypes()); } -} \ No newline at end of file +} diff --git a/src/ZM/MySQL/MySQLStatement.php b/src/ZM/MySQL/MySQLStatement.php index 3c22375b..248b995b 100644 --- a/src/ZM/MySQL/MySQLStatement.php +++ b/src/ZM/MySQL/MySQLStatement.php @@ -1,9 +1,13 @@ -statement->setFetchMode($fetchMode, $arg2, $arg3); - elseif ($arg2 !== null && $arg3 === []) + } + if ($arg2 !== null && $arg3 === []) { return $this->statement->setFetchMode($fetchMode, $arg2); - elseif ($arg2 === null && $arg3 !== []) + } + if ($arg2 === null && $arg3 !== []) { return $this->statement->setFetchMode($fetchMode, $arg2, $arg3); - else - return $this->statement->setFetchMode($fetchMode); + } + + return $this->statement->setFetchMode($fetchMode); } public function fetch($fetchMode = PDO::FETCH_ASSOC, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) @@ -51,12 +58,14 @@ class MySQLStatement implements IteratorAggregate, Statement public function fetchAll($fetchMode = PDO::FETCH_ASSOC, $fetchArgument = null, $ctorArgs = null) { - if ($fetchArgument === null && $ctorArgs === null) + if ($fetchArgument === null && $ctorArgs === null) { return $this->statement->fetchAll($fetchMode); - elseif ($fetchArgument !== null && $ctorArgs === null) + } + if ($fetchArgument !== null && $ctorArgs === null) { return $this->statement->fetchAll($fetchMode, $fetchArgument); - else - return $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs); + } + + return $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs); } public function fetchColumn($columnIndex = 0) @@ -103,4 +112,4 @@ class MySQLStatement implements IteratorAggregate, Statement { return $this->statement->current(); } -} \ No newline at end of file +} diff --git a/src/ZM/MySQL/MySQLStatementWrapper.php b/src/ZM/MySQL/MySQLStatementWrapper.php index c1b2e265..6256887f 100644 --- a/src/ZM/MySQL/MySQLStatementWrapper.php +++ b/src/ZM/MySQL/MySQLStatementWrapper.php @@ -5,6 +5,8 @@ * @noinspection PhpUnused */ +declare(strict_types=1); + namespace ZM\MySQL; use Doctrine\DBAL\Driver\ResultStatement; @@ -17,7 +19,8 @@ class MySQLStatementWrapper { public $stmt; - public function __construct(?Result $stmt) { + public function __construct(?Result $stmt) + { $this->stmt = $stmt; } @@ -26,7 +29,8 @@ class MySQLStatementWrapper * wrapper method * @return ResultStatement */ - public function getIterator() { + public function getIterator() + { return $this->stmt->getIterator(); } @@ -35,16 +39,18 @@ class MySQLStatementWrapper * wrapper method * @return int */ - public function columnCount() { + public function columnCount() + { return $this->stmt->columnCount(); } /** * wrapper method - * @return array|false|mixed * @throws DbException + * @return array|false|mixed */ - public function fetchNumeric() { + public function fetchNumeric() + { try { return $this->stmt->fetchNumeric(); } catch (Throwable $e) { @@ -54,10 +60,11 @@ class MySQLStatementWrapper /** * wrapper method - * @return array|false|mixed * @throws DbException + * @return array|false|mixed */ - public function fetchAssociative() { + public function fetchAssociative() + { try { return $this->stmt->fetchAssociative(); } catch (Throwable $e) { @@ -67,10 +74,11 @@ class MySQLStatementWrapper /** * wrapper method - * @return false|mixed * @throws DbException + * @return false|mixed */ - public function fetchOne() { + public function fetchOne() + { try { return $this->stmt->fetchOne(); } catch (Throwable $e) { @@ -80,10 +88,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return array * @throws DbException */ - public function fetchAllNumeric(): array { + public function fetchAllNumeric(): array + { try { return $this->stmt->fetchAllNumeric(); } catch (Throwable $e) { @@ -93,10 +101,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return array * @throws DbException */ - public function fetchAllAssociative(): array { + public function fetchAllAssociative(): array + { try { return $this->stmt->fetchAllAssociative(); } catch (Throwable $e) { @@ -106,10 +114,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return array * @throws DbException */ - public function fetchAllKeyValue(): array { + public function fetchAllKeyValue(): array + { try { return $this->stmt->fetchAllKeyValue(); } catch (Throwable $e) { @@ -119,10 +127,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return array * @throws DbException */ - public function fetchAllAssociativeIndexed(): array { + public function fetchAllAssociativeIndexed(): array + { try { return $this->stmt->fetchAllAssociativeIndexed(); } catch (Throwable $e) { @@ -132,10 +140,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return array * @throws DbException */ - public function fetchFirstColumn(): array { + public function fetchFirstColumn(): array + { try { return $this->stmt->fetchFirstColumn(); } catch (Throwable $e) { @@ -145,10 +153,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return Traversable * @throws DbException */ - public function iterateNumeric(): Traversable { + public function iterateNumeric(): Traversable + { try { return $this->stmt->iterateNumeric(); } catch (Throwable $e) { @@ -158,10 +166,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return Traversable * @throws DbException */ - public function iterateAssociative(): Traversable { + public function iterateAssociative(): Traversable + { try { return $this->stmt->iterateAssociative(); } catch (Throwable $e) { @@ -171,10 +179,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return Traversable * @throws DbException */ - public function iterateKeyValue(): Traversable { + public function iterateKeyValue(): Traversable + { try { return $this->stmt->iterateKeyValue(); } catch (Throwable $e) { @@ -184,10 +192,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return Traversable * @throws DbException */ - public function iterateAssociativeIndexed(): Traversable { + public function iterateAssociativeIndexed(): Traversable + { try { return $this->stmt->iterateAssociativeIndexed(); } catch (Throwable $e) { @@ -197,10 +205,10 @@ class MySQLStatementWrapper /** * wrapper method - * @return Traversable * @throws DbException */ - public function iterateColumn(): Traversable { + public function iterateColumn(): Traversable + { try { return $this->stmt->iterateColumn(); } catch (Throwable $e) { @@ -210,10 +218,11 @@ class MySQLStatementWrapper /** * wrapper method - * @return int * @throws DbException + * @return int */ - public function rowCount() { + public function rowCount() + { try { return $this->stmt->rowCount(); } catch (Throwable $e) { @@ -224,9 +233,8 @@ class MySQLStatementWrapper /** * wrapper method */ - public function free(): void { + public function free(): void + { $this->stmt->free(); } - - -} \ No newline at end of file +} diff --git a/src/ZM/MySQL/MySQLWrapper.php b/src/ZM/MySQL/MySQLWrapper.php index a5fd1d7c..7e213a39 100644 --- a/src/ZM/MySQL/MySQLWrapper.php +++ b/src/ZM/MySQL/MySQLWrapper.php @@ -1,5 +1,7 @@ connection = DriverManager::getConnection(["driverClass" => MySQLDriver::class]); + $this->connection = DriverManager::getConnection(['driverClass' => MySQLDriver::class]); } catch (Throwable $e) { throw new DbException($e->getMessage(), $e->getCode(), $e); } } + public function __destruct() + { + $this->connection->close(); + } + /** * wrapper method - * @return string */ - public function getDatabase(): string { + public function getDatabase(): string + { return $this->connection->getDatabase(); } /** * wrapper method - * @return bool */ - public function isAutoCommit(): bool { + public function isAutoCommit(): bool + { return $this->connection->isAutoCommit(); } @@ -51,19 +59,18 @@ class MySQLWrapper * wrapper method * @param $autoCommit */ - public function setAutoCommit($autoCommit) { + public function setAutoCommit($autoCommit) + { $this->connection->setAutoCommit($autoCommit); } /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return array|false * @throws DbException + * @return array|false */ - public function fetchAssociative(string $query, array $params = [], array $types = []) { + public function fetchAssociative(string $query, array $params = [], array $types = []) + { try { return $this->connection->fetchAssociative($query, $params, $types); } catch (Throwable $e) { @@ -73,13 +80,11 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return array|false * @throws DbException + * @return array|false */ - public function fetchNumeric(string $query, array $params = [], array $types = []) { + public function fetchNumeric(string $query, array $params = [], array $types = []) + { try { return $this->connection->fetchNumeric($query, $params, $types); } catch (Throwable $e) { @@ -88,13 +93,11 @@ class MySQLWrapper } /** - * @param string $query - * @param array $params - * @param array $types - * @return false|mixed * @throws DbException + * @return false|mixed */ - public function fetchOne(string $query, array $params = [], array $types = []) { + public function fetchOne(string $query, array $params = [], array $types = []) + { try { return $this->connection->fetchOne($query, $params, $types); } catch (Throwable $e) { @@ -104,20 +107,18 @@ class MySQLWrapper /** * wrapper method - * @return bool */ - public function isTransactionActive(): bool { + public function isTransactionActive(): bool + { return $this->connection->isTransactionActive(); } /** * @param $table - * @param array $criteria - * @param array $types - * @return int * @throws DbException */ - public function delete($table, array $criteria, array $types = []): int { + public function delete($table, array $criteria, array $types = []): int + { try { return $this->connection->delete($table, $criteria, $types); } catch (Throwable $e) { @@ -128,30 +129,27 @@ class MySQLWrapper /** * wrapper method * @param $level - * @return int */ - public function setTransactionIsolation($level): int { + public function setTransactionIsolation($level): int + { return $this->connection->setTransactionIsolation($level); } /** * wrapper method - * @return int|null */ - public function getTransactionIsolation(): ?int { + public function getTransactionIsolation(): ?int + { return $this->connection->getTransactionIsolation(); } /** * wrapper method * @param $table - * @param array $data - * @param array $criteria - * @param array $types - * @return int * @throws DbException */ - public function update($table, array $data, array $criteria, array $types = []): int { + public function update($table, array $data, array $criteria, array $types = []): int + { try { return $this->connection->update($table, $data, $criteria, $types); } catch (Throwable $e) { @@ -162,12 +160,10 @@ class MySQLWrapper /** * wrapper method * @param $table - * @param array $data - * @param array $types - * @return int * @throws DbException */ - public function insert($table, array $data, array $types = []): int { + public function insert($table, array $data, array $types = []): int + { try { return $this->connection->insert($table, $data, $types); } catch (Throwable $e) { @@ -178,31 +174,29 @@ class MySQLWrapper /** * wrapper method * @param $str - * @return string */ - public function quoteIdentifier($str): string { + public function quoteIdentifier($str): string + { return $this->connection->quoteIdentifier($str); } /** * wrapper method * @param $value - * @param int $type + * @param int $type * @return mixed */ - public function quote($value, $type = ParameterType::STRING) { + public function quote($value, $type = ParameterType::STRING) + { return $this->connection->quote($value, $type); } /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return array * @throws DbException */ - public function fetchAllNumeric(string $query, array $params = [], array $types = []): array { + public function fetchAllNumeric(string $query, array $params = [], array $types = []): array + { try { return $this->connection->fetchAllNumeric($query, $params, $types); } catch (Throwable $e) { @@ -212,13 +206,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return array * @throws DbException */ - public function fetchAllAssociative(string $query, array $params = [], array $types = []): array { + public function fetchAllAssociative(string $query, array $params = [], array $types = []): array + { try { return $this->connection->fetchAllAssociative($query, $params, $types); } catch (Throwable $e) { @@ -228,13 +219,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return array * @throws DbException */ - public function fetchAllKeyValue(string $query, array $params = [], array $types = []): array { + public function fetchAllKeyValue(string $query, array $params = [], array $types = []): array + { try { return $this->connection->fetchAllKeyValue($query, $params, $types); } catch (Throwable $e) { @@ -244,13 +232,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return array * @throws DbException */ - public function fetchAllAssociativeIndexed(string $query, array $params = [], array $types = []): array { + public function fetchAllAssociativeIndexed(string $query, array $params = [], array $types = []): array + { try { return $this->connection->fetchAllAssociativeIndexed($query, $params, $types); } catch (Throwable $e) { @@ -260,13 +245,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return array * @throws DbException */ - public function fetchFirstColumn(string $query, array $params = [], array $types = []): array { + public function fetchFirstColumn(string $query, array $params = [], array $types = []): array + { try { return $this->connection->fetchFirstColumn($query, $params, $types); } catch (Throwable $e) { @@ -276,13 +258,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return Traversable * @throws DbException */ - public function iterateNumeric(string $query, array $params = [], array $types = []): Traversable { + public function iterateNumeric(string $query, array $params = [], array $types = []): Traversable + { try { return $this->connection->iterateNumeric($query, $params, $types); } catch (Throwable $e) { @@ -292,13 +271,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return Traversable * @throws DbException */ - public function iterateAssociative(string $query, array $params = [], array $types = []): Traversable { + public function iterateAssociative(string $query, array $params = [], array $types = []): Traversable + { try { return $this->connection->iterateAssociative($query, $params, $types); } catch (Throwable $e) { @@ -308,13 +284,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return Traversable * @throws DbException */ - public function iterateKeyValue(string $query, array $params = [], array $types = []): Traversable { + public function iterateKeyValue(string $query, array $params = [], array $types = []): Traversable + { try { return $this->connection->iterateKeyValue($query, $params, $types); } catch (Throwable $e) { @@ -324,13 +297,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return Traversable * @throws DbException */ - public function iterateAssociativeIndexed(string $query, array $params = [], array $types = []): Traversable { + public function iterateAssociativeIndexed(string $query, array $params = [], array $types = []): Traversable + { try { return $this->connection->iterateAssociativeIndexed($query, $params, $types); } catch (Throwable $e) { @@ -340,13 +310,10 @@ class MySQLWrapper /** * wrapper method - * @param string $query - * @param array $params - * @param array $types - * @return Traversable * @throws DbException */ - public function iterateColumn(string $query, array $params = [], array $types = []): Traversable { + public function iterateColumn(string $query, array $params = [], array $types = []): Traversable + { try { return $this->connection->iterateColumn($query, $params, $types); } catch (Throwable $e) { @@ -357,13 +324,11 @@ class MySQLWrapper /** * wrapper method * @param $sql - * @param array $params - * @param array $types - * @param QueryCacheProfile|null $qcp - * @return MySQLStatementWrapper + * @param array $types * @throws DbException */ - public function executeQuery($sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null): MySQLStatementWrapper { + public function executeQuery($sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null): MySQLStatementWrapper + { try { $query = $this->connection->executeQuery($sql, $params, $types, $qcp); return new MySQLStatementWrapper($query); @@ -377,11 +342,10 @@ class MySQLWrapper * @param $sql * @param $params * @param $types - * @param QueryCacheProfile $qcp - * @return MySQLStatementWrapper * @throws DbException */ - public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp): MySQLStatementWrapper { + public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp): MySQLStatementWrapper + { try { $query = $this->connection->executeCacheQuery($sql, $params, $types, $qcp); return new MySQLStatementWrapper($query); @@ -393,12 +357,10 @@ class MySQLWrapper /** * wrapper method * @param $sql - * @param array $params - * @param array $types - * @return int * @throws DbException */ - public function executeStatement($sql, array $params = [], array $types = []): int { + public function executeStatement($sql, array $params = [], array $types = []): int + { try { return $this->connection->executeStatement($sql, $params, $types); } catch (Throwable $e) { @@ -408,28 +370,28 @@ class MySQLWrapper /** * wrapper method - * @return int */ - public function getTransactionNestingLevel(): int { + public function getTransactionNestingLevel(): int + { return $this->connection->getTransactionNestingLevel(); } /** * wrapper method * @param null $name - * @return string */ - public function lastInsertId($name = null): string { + public function lastInsertId($name = null): string + { return $this->connection->lastInsertId($name); } /** * overwrite method to $this->connection->transactional() - * @param Closure $func - * @return mixed * @throws DbException + * @return mixed */ - public function transactional(Closure $func) { + public function transactional(Closure $func) + { $this->beginTransaction(); try { $res = $func($this); @@ -446,7 +408,8 @@ class MySQLWrapper * @param $nestTransactionsWithSavepoints * @throws DbException */ - public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints) { + public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints) + { try { $this->connection->setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints); } catch (Throwable $e) { @@ -456,26 +419,26 @@ class MySQLWrapper /** * wrapper method - * @return bool */ - public function getNestTransactionsWithSavepoints(): bool { + public function getNestTransactionsWithSavepoints(): bool + { return $this->connection->getNestTransactionsWithSavepoints(); } /** * wrapper method - * @return bool */ - public function beginTransaction(): bool { + public function beginTransaction(): bool + { return $this->connection->beginTransaction(); } /** * wrapper method - * @return bool * @throws DbException */ - public function commit(): bool { + public function commit(): bool + { try { return $this->connection->commit(); } catch (Throwable $e) { @@ -485,10 +448,10 @@ class MySQLWrapper /** * wrapper method - * @return bool * @throws DbException */ - public function rollBack(): bool { + public function rollBack(): bool + { try { return $this->connection->rollBack(); } catch (Throwable $e) { @@ -501,7 +464,8 @@ class MySQLWrapper * @param $savepoint * @throws DbException */ - public function createSavepoint($savepoint) { + public function createSavepoint($savepoint) + { try { $this->connection->createSavepoint($savepoint); } catch (Throwable $e) { @@ -514,7 +478,8 @@ class MySQLWrapper * @param $savepoint * @throws DbException */ - public function releaseSavepoint($savepoint) { + public function releaseSavepoint($savepoint) + { try { $this->connection->releaseSavepoint($savepoint); } catch (Throwable $e) { @@ -527,7 +492,8 @@ class MySQLWrapper * @param $savepoint * @throws DbException */ - public function rollbackSavepoint($savepoint) { + public function rollbackSavepoint($savepoint) + { try { $this->connection->rollbackSavepoint($savepoint); } catch (Throwable $e) { @@ -539,7 +505,8 @@ class MySQLWrapper * wrapper method * @throws DbException */ - public function setRollbackOnly() { + public function setRollbackOnly() + { try { $this->connection->setRollbackOnly(); } catch (Throwable $e) { @@ -549,10 +516,10 @@ class MySQLWrapper /** * wrapper method - * @return bool * @throws DbException */ - public function isRollbackOnly(): bool { + public function isRollbackOnly(): bool + { try { return $this->connection->isRollbackOnly(); } catch (Throwable $e) { @@ -562,17 +529,14 @@ class MySQLWrapper /** * overwrite method to $this->connection->createQueryBuilder - * @return MySQLQueryBuilder */ - public function createQueryBuilder(): MySQLQueryBuilder { + public function createQueryBuilder(): MySQLQueryBuilder + { return new MySQLQueryBuilder($this); } - public function getConnection(): Connection { + public function getConnection(): Connection + { return $this->connection; } - - public function __destruct() { - $this->connection->close(); - } -} \ No newline at end of file +} diff --git a/src/ZM/Store/LightCache.php b/src/ZM/Store/LightCache.php index 6d82e158..db5546e8 100644 --- a/src/ZM/Store/LightCache.php +++ b/src/ZM/Store/LightCache.php @@ -1,9 +1,9 @@ column("value", Table::TYPE_STRING, $config["max_strlen"]); - self::$kv_table->column("expire", Table::TYPE_INT); - self::$kv_table->column("data_type", Table::TYPE_STRING, 8); + self::$kv_table = new Table($config['size'], $config['hash_conflict_proportion']); + self::$kv_table->column('value', Table::TYPE_STRING, $config['max_strlen']); + self::$kv_table->column('expire', Table::TYPE_INT); + self::$kv_table->column('data_type', Table::TYPE_STRING, 8); $result = self::$kv_table->create(); // 加载内容 - if ($result === true && isset($config["persistence_path"])) { - if (file_exists($config["persistence_path"])) { - $r = json_decode(file_get_contents($config["persistence_path"]), true); - if ($r === null) $r = []; + if ($result === true && isset($config['persistence_path'])) { + if (file_exists($config['persistence_path'])) { + $r = json_decode(file_get_contents($config['persistence_path']), true); + if ($r === null) { + $r = []; + } foreach ($r as $k => $v) { $write = self::set($k, $v); - Console::verbose("Writing LightCache: " . $k); + Console::verbose('Writing LightCache: ' . $k); if ($write === false) { - self::$last_error = zm_internal_errcode("E00051") . '可能是由于 Hash 冲突过多导致动态空间无法分配内存'; + self::$last_error = zm_internal_errcode('E00051') . '可能是由于 Hash 冲突过多导致动态空间无法分配内存'; return false; } } } } if ($result === false) { - self::$last_error = zm_internal_errcode("E00050") . '系统内存不足,申请失败'; + self::$last_error = zm_internal_errcode('E00050') . '系统内存不足,申请失败'; } else { $obj = Framework::loadFrameworkState(); - foreach (($obj["expiring_light_cache"] ?? []) as $k => $v) { - $value = $v["value"]; + foreach (($obj['expiring_light_cache'] ?? []) as $k => $v) { + $value = $v['value']; if (is_array($value)) { $value = json_encode($value, JSON_UNESCAPED_UNICODE); - if (strlen($value) >= self::$config["max_strlen"]) return false; - $data_type = "json"; + if (strlen($value) >= self::$config['max_strlen']) { + return false; + } + $data_type = 'json'; } elseif (is_string($value)) { - $data_type = ""; + $data_type = ''; } elseif (is_int($value)) { - $data_type = "int"; + $data_type = 'int'; } elseif (is_bool($value)) { - $data_type = "bool"; + $data_type = 'bool'; $value = json_encode($value); } else { return false; } $result = self::$kv_table->set($k, [ - "value" => $value, - "expire" => $v["expire"], - "data_type" => $data_type + 'value' => $value, + 'expire' => $v['expire'], + 'data_type' => $data_type, ]); - if ($result === false) return false; + if ($result === false) { + return false; + } } } return $result; } /** - * @param string $key - * @return null|mixed * @throws ZMException + * @return null|mixed */ - public static function get(string $key) { - if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache"); + public static function get(string $key) + { + if (self::$kv_table === null) { + throw new LightCacheException('E00048', 'not initialized LightCache'); + } self::checkExpire($key); $r = self::$kv_table->get($key); return $r === false ? null : self::parseGet($r); } /** - * @param string $key - * @return mixed|null * @throws ZMException + * @return null|mixed */ - public static function getExpire(string $key) { - if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache"); + public static function getExpire(string $key) + { + if (self::$kv_table === null) { + throw new LightCacheException('E00048', 'not initialized LightCache'); + } self::checkExpire($key); - $r = self::$kv_table->get($key, "expire"); + $r = self::$kv_table->get($key, 'expire'); return $r === false ? null : $r - time(); } /** - * @param string $key - * @return mixed|null * @throws ZMException + * @return null|mixed * @since 2.4.3 */ - public static function getExpireTS(string $key) { - if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache"); + public static function getExpireTS(string $key) + { + if (self::$kv_table === null) { + throw new LightCacheException('E00048', 'not initialized LightCache'); + } self::checkExpire($key); - $r = self::$kv_table->get($key, "expire"); + $r = self::$kv_table->get($key, 'expire'); return $r === false ? null : $r; } /** - * @param string $key - * @param string|array|int $value - * @param int $expire - * @return mixed + * @param array|int|string $value * @throws ZMException + * @return bool */ - public static function set(string $key, $value, int $expire = -1) { - if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache"); + public static function set(string $key, $value, int $expire = -1) + { + if (self::$kv_table === null) { + throw new LightCacheException('E00048', 'not initialized LightCache'); + } if (is_array($value)) { $value = json_encode($value, JSON_UNESCAPED_UNICODE); - if (strlen($value) >= self::$config["max_strlen"]) return false; - $data_type = "json"; + if (strlen($value) >= self::$config['max_strlen']) { + return false; + } + $data_type = 'json'; } elseif (is_string($value)) { - $data_type = ""; + $data_type = ''; } elseif (is_int($value)) { - $data_type = "int"; + $data_type = 'int'; } elseif (is_bool($value)) { - $data_type = "bool"; + $data_type = 'bool'; $value = json_encode($value); } else { - throw new LightCacheException("E00049", "Only can set string, array and int"); + throw new LightCacheException('E00049', 'Only can set string, array and int'); } try { return self::$kv_table->set($key, [ - "value" => $value, - "expire" => $expire >= 0 ? $expire + time() : $expire, - "data_type" => $data_type + 'value' => $value, + 'expire' => $expire >= 0 ? $expire + time() : $expire, + 'data_type' => $data_type, ]); } catch (Exception $e) { return false; @@ -153,57 +169,65 @@ class LightCache } /** - * @param string $key * @param $value - * @return bool|mixed * @throws ZMException + * @return bool */ - public static function update(string $key, $value) { - if (self::$kv_table === null) throw new LightCacheException("E00048", "not initialized LightCache."); + public static function update(string $key, $value) + { + if (self::$kv_table === null) { + throw new LightCacheException('E00048', 'not initialized LightCache.'); + } if (is_array($value)) { $value = json_encode($value, JSON_UNESCAPED_UNICODE); - if (strlen($value) >= self::$config["max_strlen"]) return false; - $data_type = "json"; + if (strlen($value) >= self::$config['max_strlen']) { + return false; + } + $data_type = 'json'; } elseif (is_string($value)) { - $data_type = ""; + $data_type = ''; } elseif (is_int($value)) { - $data_type = "int"; + $data_type = 'int'; } else { - throw new LightCacheException("E00048", "Only can set string, array and int"); + throw new LightCacheException('E00048', 'Only can set string, array and int'); } try { - if (self::$kv_table->get($key) === false) return false; + if (self::$kv_table->get($key) === false) { + return false; + } return self::$kv_table->set($key, [ - "value" => $value, - "data_type" => $data_type + 'value' => $value, + 'data_type' => $data_type, ]); } catch (Exception $e) { return false; } } - public static function getMemoryUsage() { + public static function getMemoryUsage() + { return self::$kv_table->getMemorySize(); } /** - * @param string $key - * @return bool * @throws Exception */ - public static function isset(string $key): bool { + public static function isset(string $key): bool + { return self::get($key) !== null; } - public static function unset(string $key) { + public static function unset(string $key) + { return self::$kv_table->del($key); } - public static function getAll(): array { + public static function getAll(): array + { $r = []; $del = []; foreach (self::$kv_table as $k => $v) { - if ($v["expire"] <= time() && $v["expire"] >= 0) { + if ($v['expire'] <= time() && $v['expire'] >= 0) { $del[] = $k; continue; } @@ -215,69 +239,81 @@ class LightCache return $r; } - public static function addPersistence($key) { - if (file_exists(self::$config["persistence_path"])) { - $r = json_decode(file_get_contents(self::$config["persistence_path"]), true); - if ($r === null) $r = []; - if (!isset($r[$key])) $r[$key] = null; - file_put_contents(self::$config["persistence_path"], json_encode($r, 64 | 128 | 256)); + public static function addPersistence($key) + { + if (file_exists(self::$config['persistence_path'])) { + $r = json_decode(file_get_contents(self::$config['persistence_path']), true); + if ($r === null) { + $r = []; + } + if (!isset($r[$key])) { + $r[$key] = null; + } + file_put_contents(self::$config['persistence_path'], json_encode($r, 64 | 128 | 256)); return true; - } else { - return false; } + return false; } - public static function removePersistence($key) { - if (file_exists(self::$config["persistence_path"])) { - $r = json_decode(file_get_contents(self::$config["persistence_path"]), true); - if ($r === null) $r = []; - if (isset($r[$key])) unset($r[$key]); - file_put_contents(self::$config["persistence_path"], json_encode($r, 64 | 128 | 256)); + public static function removePersistence($key) + { + if (file_exists(self::$config['persistence_path'])) { + $r = json_decode(file_get_contents(self::$config['persistence_path']), true); + if ($r === null) { + $r = []; + } + if (isset($r[$key])) { + unset($r[$key]); + } + file_put_contents(self::$config['persistence_path'], json_encode($r, 64 | 128 | 256)); return true; - } else { - return false; } + return false; } /** * 这个只能在唯一一个工作进程中执行 * @throws Exception */ - public static function savePersistence() { + public static function savePersistence() + { if (server()->worker_id !== MAIN_WORKER) { - ProcessManager::sendActionToWorker(MAIN_WORKER, "save_persistence", []); + WorkerManager::sendActionToWorker(MAIN_WORKER, 'save_persistence', []); return; } $dispatcher = new EventDispatcher(OnSave::class); $dispatcher->dispatchEvents(); - if (self::$kv_table === null) return; + if (self::$kv_table === null) { + return; + } - if (!empty(self::$config["persistence_path"])) { - if (file_exists(self::$config["persistence_path"])) { - $r = json_decode(file_get_contents(self::$config["persistence_path"]), true); + if (!empty(self::$config['persistence_path'])) { + if (file_exists(self::$config['persistence_path'])) { + $r = json_decode(file_get_contents(self::$config['persistence_path']), true); } else { $r = []; } - if ($r === null) $r = []; + if ($r === null) { + $r = []; + } foreach ($r as $k => $v) { - Console::verbose("Saving " . $k); + Console::verbose('Saving ' . $k); $r[$k] = self::get($k); } - file_put_contents(self::$config["persistence_path"], json_encode($r, 64 | 128 | 256)); + file_put_contents(self::$config['persistence_path'], json_encode($r, 64 | 128 | 256)); } $obj = Framework::loadFrameworkState(); - $obj["expiring_light_cache"] = []; + $obj['expiring_light_cache'] = []; $del = []; foreach (self::$kv_table as $k => $v) { - if ($v["expire"] <= time() && $v["expire"] >= 0) { + if ($v['expire'] <= time() && $v['expire'] >= 0) { $del[] = $k; - continue; - } elseif ($v["expire"] > time()) { - $obj["expiring_light_cache"][$k] = [ - "expire" => $v["expire"], - "value" => self::parseGet($v) + } elseif ($v['expire'] > time()) { + $obj['expiring_light_cache'][$k] = [ + 'expire' => $v['expire'], + 'value' => self::parseGet($v), ]; } } @@ -285,26 +321,28 @@ class LightCache self::unset($v); } Framework::saveFrameworkState($obj); - Console::verbose("Saved."); + Console::verbose('Saved.'); } - private static function checkExpire($key) { - if (($expire = self::$kv_table->get($key, "expire")) >= 0) { + private static function checkExpire($key) + { + if (($expire = self::$kv_table->get($key, 'expire')) >= 0) { if ($expire <= time()) { self::$kv_table->del($key); } } } - private static function parseGet($r) { - switch ($r["data_type"]) { - case "json": - case "int": - case "bool": - return json_decode($r["value"], true); - case "": + private static function parseGet($r) + { + switch ($r['data_type']) { + case 'json': + case 'int': + case 'bool': + return json_decode($r['value'], true); + case '': default: - return $r["value"]; + return $r['value']; } } } diff --git a/src/ZM/Store/LightCacheInside.php b/src/ZM/Store/LightCacheInside.php index dd63be64..c902119e 100644 --- a/src/ZM/Store/LightCacheInside.php +++ b/src/ZM/Store/LightCacheInside.php @@ -1,9 +1,9 @@ get($key); - return $r === false ? null : json_decode($r["value"], true); + return $r === false ? null : json_decode($r['value'], true); } /** - * @param string $table - * @param string $key - * @param string|array|int $value + * @param array|int|string $value * @return mixed */ - public static function set(string $table, string $key, $value): bool { + public static function set(string $table, string $key, $value): bool + { try { return self::$kv_table[$table]->set($key, [ - "value" => json_encode($value, 256) + 'value' => json_encode($value, 256), ]); } catch (Exception $e) { return false; } } - public static function unset(string $table, string $key) { + public static function unset(string $table, string $key) + { return self::$kv_table[$table]->del($key); } @@ -61,13 +61,16 @@ class LightCacheInside * @param $name * @param $size * @param $str_size - * @param int $conflict_proportion + * @param int $conflict_proportion * @throws ZMException */ - private static function createTable($name, $size, $str_size, $conflict_proportion = 0) { + private static function createTable($name, $size, $str_size, $conflict_proportion = 0) + { self::$kv_table[$name] = new Table($size, $conflict_proportion); - self::$kv_table[$name]->column("value", Table::TYPE_STRING, $str_size); + self::$kv_table[$name]->column('value', Table::TYPE_STRING, $str_size); $r = self::$kv_table[$name]->create(); - if ($r === false) throw new LightCacheException("E00050", "内存不足,创建静态表失败!"); + if ($r === false) { + throw new LightCacheException('E00050', '内存不足,创建静态表失败!'); + } } } diff --git a/src/ZM/Store/Lock/SpinLock.php b/src/ZM/Store/Lock/SpinLock.php index 4f302823..42e56df0 100644 --- a/src/ZM/Store/Lock/SpinLock.php +++ b/src/ZM/Store/Lock/SpinLock.php @@ -1,47 +1,56 @@ -column('lock_num', Table::TYPE_INT, 8); return self::$kv_lock->create(); } - public static function lock(string $key) { + public static function lock(string $key) + { while (($r = self::$kv_lock->incr($key, 'lock_num')) > 1) { //此资源已经被锁上了 - if (Coroutine::getCid() != -1) System::sleep(self::$delay / 1000); - else usleep(self::$delay * 1000); + if (Coroutine::getCid() != -1) { + System::sleep(self::$delay / 1000); + } else { + usleep(self::$delay * 1000); + } } } - public static function tryLock(string $key): bool { + public static function tryLock(string $key): bool + { if (($r = self::$kv_lock->incr($key, 'lock_num')) > 1) { return false; } return true; } - public static function unlock(string $key) { + public static function unlock(string $key) + { return self::$kv_lock->set($key, ['lock_num' => 0]); } - public static function transaction(string $key, callable $function) { + public static function transaction(string $key, callable $function) + { SpinLock::lock($key); $function(); SpinLock::unlock($key); diff --git a/src/ZM/Store/MySQL/SqlPoolStorage.php b/src/ZM/Store/MySQL/SqlPoolStorage.php index 33cc9441..584ede36 100644 --- a/src/ZM/Store/MySQL/SqlPoolStorage.php +++ b/src/ZM/Store/MySQL/SqlPoolStorage.php @@ -1,13 +1,13 @@ get(); - $result = $callable($r); - if (isset($r->wasted)) ZMRedisPool::$pool->put(null); - else ZMRedisPool::$pool->put($r); - return $result; - } - /** * ZMRedis constructor. * @throws NotInitializedException */ - public function __construct() { - if (ZMRedisPool::$pool === null) throw new NotInitializedException("Redis pool is not initialized."); + public function __construct() + { + if (ZMRedisPool::$pool === null) { + throw new NotInitializedException('Redis pool is not initialized.'); + } $this->conn = ZMRedisPool::$pool->get(); } - /** - * @return Redis - */ - public function get(): Redis { - return $this->conn; + public function __destruct() + { + if (isset($this->conn->wasted)) { + ZMRedisPool::$pool->put(null); + } else { + ZMRedisPool::$pool->put($this->conn); + } } - public function __destruct() { - if (isset($this->conn->wasted)) ZMRedisPool::$pool->put(null); - else ZMRedisPool::$pool->put($this->conn); + /** + * @throws NotInitializedException + * @return mixed + */ + public static function call(callable $callable) + { + if (ZMRedisPool::$pool === null) { + throw new NotInitializedException('Redis pool is not initialized.'); + } + $r = ZMRedisPool::$pool->get(); + $result = $callable($r); + if (isset($r->wasted)) { + ZMRedisPool::$pool->put(null); + } else { + ZMRedisPool::$pool->put($r); + } + return $result; + } + + public function get(): Redis + { + return $this->conn; } } diff --git a/src/ZM/Store/Redis/ZMRedisPool.php b/src/ZM/Store/Redis/ZMRedisPool.php index 7179d2b0..faee8beb 100644 --- a/src/ZM/Store/Redis/ZMRedisPool.php +++ b/src/ZM/Store/Redis/ZMRedisPool.php @@ -1,9 +1,11 @@ -withHost($config['host']) - ->withPort($config['port']) - ->withAuth($config['auth']) - ->withDbIndex($config['db_index']) - ->withTimeout($config['timeout'] ?? 1) + public static function init($config) + { + self::$pool = new RedisPool( + (new RedisConfig()) + ->withHost($config['host']) + ->withPort($config['port']) + ->withAuth($config['auth']) + ->withDbIndex($config['db_index']) + ->withTimeout($config['timeout'] ?? 1) ); try { $r = self::$pool->get()->ping('123'); - if (strpos(strtolower($r), "123") !== false) { - Console::debug("成功连接redis连接池!"); + if (strpos(strtolower($r), '123') !== false) { + Console::debug('成功连接redis连接池!'); } else { var_dump($r); } } catch (RedisException $e) { - Console::error(zm_internal_errcode("E00047") . "Redis init failed! " . $e->getMessage()); + Console::error(zm_internal_errcode('E00047') . 'Redis init failed! ' . $e->getMessage()); self::$pool = null; } } diff --git a/src/ZM/Store/WorkerCache.php b/src/ZM/Store/WorkerCache.php index ce38d2c5..b4d7e130 100644 --- a/src/ZM/Store/WorkerCache.php +++ b/src/ZM/Store/WorkerCache.php @@ -1,96 +1,107 @@ - 0]; - if ($config["worker"] === server()->worker_id) { + public static function get($key) + { + $config = self::$config ?? ZMConfig::get('global', 'worker_cache') ?? ['worker' => 0]; + if ($config['worker'] === server()->worker_id) { return self::$store[$key] ?? null; - } else { - $action = ["action" => "getWorkerCache", "key" => $key, "cid" => zm_cid()]; - server()->sendMessage(json_encode($action, JSON_UNESCAPED_UNICODE), $config["worker"]); - zm_yield(); - $p = self::$transfer[zm_cid()] ?? null; - unset(self::$transfer[zm_cid()]); - return $p; } - } - - public static function set($key, $value, $async = false) { - $config = self::$config ?? ZMConfig::get("global", "worker_cache") ?? ["worker" => 0]; - if ($config["worker"] === server()->worker_id) { - self::$store[$key] = $value; - return true; - } else { - $action = ["action" => $async ? "asyncSetWorkerCache" : "setWorkerCache", "key" => $key, "value" => $value, "cid" => zm_cid()]; - return self::processRemote($action, $async, $config); - } - } - - public static function hasKey($key, $subkey) { - $config = self::$config ?? ZMConfig::get("global", "worker_cache") ?? ["worker" => 0]; - if ($config["worker"] === server()->worker_id) { - return isset(self::$store[$key][$subkey]); - } else { - $action = ["hasKeyWorkerCache", "key" => $key, "subkey" => $subkey, "cid" => zm_cid()]; - return self::processRemote($action, false, $config); - } - } - - private static function processRemote($action, $async, $config) { - $ss = server()->sendMessage(json_encode($action, JSON_UNESCAPED_UNICODE), $config["worker"]); - if (!$ss) return false; - if ($async) return true; + $action = ['action' => 'getWorkerCache', 'key' => $key, 'cid' => zm_cid()]; + server()->sendMessage(json_encode($action, JSON_UNESCAPED_UNICODE), $config['worker']); zm_yield(); $p = self::$transfer[zm_cid()] ?? null; unset(self::$transfer[zm_cid()]); return $p; } - public static function unset($key, $async = false) { - $config = self::$config ?? ZMConfig::get("global", "worker_cache") ?? ["worker" => 0]; - if ($config["worker"] === server()->worker_id) { + public static function set($key, $value, $async = false) + { + $config = self::$config ?? ZMConfig::get('global', 'worker_cache') ?? ['worker' => 0]; + if ($config['worker'] === server()->worker_id) { + self::$store[$key] = $value; + return true; + } + $action = ['action' => $async ? 'asyncSetWorkerCache' : 'setWorkerCache', 'key' => $key, 'value' => $value, 'cid' => zm_cid()]; + return self::processRemote($action, $async, $config); + } + + public static function hasKey($key, $subkey) + { + $config = self::$config ?? ZMConfig::get('global', 'worker_cache') ?? ['worker' => 0]; + if ($config['worker'] === server()->worker_id) { + return isset(self::$store[$key][$subkey]); + } + $action = ['hasKeyWorkerCache', 'key' => $key, 'subkey' => $subkey, 'cid' => zm_cid()]; + return self::processRemote($action, false, $config); + } + + public static function unset($key, $async = false) + { + $config = self::$config ?? ZMConfig::get('global', 'worker_cache') ?? ['worker' => 0]; + if ($config['worker'] === server()->worker_id) { unset(self::$store[$key]); return true; - } else { - $action = ["action" => $async ? "asyncUnsetWorkerCache" : "unsetWorkerCache", "key" => $key, "cid" => zm_cid()]; - return self::processRemote($action, $async, $config); } + $action = ['action' => $async ? 'asyncUnsetWorkerCache' : 'unsetWorkerCache', 'key' => $key, 'cid' => zm_cid()]; + return self::processRemote($action, $async, $config); } - public static function add($key, int $value, $async = false) { - $config = self::$config ?? ZMConfig::get("global", "worker_cache") ?? ["worker" => 0]; - if ($config["worker"] === server()->worker_id) { - if (!isset(self::$store[$key])) self::$store[$key] = 0; + public static function add($key, int $value, $async = false) + { + $config = self::$config ?? ZMConfig::get('global', 'worker_cache') ?? ['worker' => 0]; + if ($config['worker'] === server()->worker_id) { + if (!isset(self::$store[$key])) { + self::$store[$key] = 0; + } self::$store[$key] += $value; return true; - } else { - $action = ["action" => $async ? "asyncAddWorkerCache" : "addWorkerCache", "key" => $key, "value" => $value, "cid" => zm_cid()]; - return self::processRemote($action, $async, $config); } + $action = ['action' => $async ? 'asyncAddWorkerCache' : 'addWorkerCache', 'key' => $key, 'value' => $value, 'cid' => zm_cid()]; + return self::processRemote($action, $async, $config); } - public static function sub($key, int $value, $async = false) { - $config = self::$config ?? ZMConfig::get("global", "worker_cache") ?? ["worker" => 0]; - if ($config["worker"] === server()->worker_id) { - if (!isset(self::$store[$key])) self::$store[$key] = 0; + public static function sub($key, int $value, $async = false) + { + $config = self::$config ?? ZMConfig::get('global', 'worker_cache') ?? ['worker' => 0]; + if ($config['worker'] === server()->worker_id) { + if (!isset(self::$store[$key])) { + self::$store[$key] = 0; + } self::$store[$key] -= $value; return true; - } else { - $action = ["action" => $async ? "asyncSubWorkerCache" : "subWorkerCache", "key" => $key, "value" => $value, "cid" => zm_cid()]; - return self::processRemote($action, $async, $config); } + $action = ['action' => $async ? 'asyncSubWorkerCache' : 'subWorkerCache', 'key' => $key, 'value' => $value, 'cid' => zm_cid()]; + return self::processRemote($action, $async, $config); } -} \ No newline at end of file + + private static function processRemote($action, $async, $config) + { + $ss = server()->sendMessage(json_encode($action, JSON_UNESCAPED_UNICODE), $config['worker']); + if (!$ss) { + return false; + } + if ($async) { + return true; + } + zm_yield(); + $p = self::$transfer[zm_cid()] ?? null; + unset(self::$transfer[zm_cid()]); + return $p; + } +} diff --git a/src/ZM/Store/ZMAtomic.php b/src/ZM/Store/ZMAtomic.php index 12a133a4..e8b38579 100644 --- a/src/ZM/Store/ZMAtomic.php +++ b/src/ZM/Store/ZMAtomic.php @@ -1,9 +1,9 @@ $v) { + public static function init() + { + foreach ((ZMConfig::get('global', 'init_atomics') ?? []) as $k => $v) { self::$atomics[$k] = new Atomic($v); } - self::$atomics["stop_signal"] = new Atomic(0); - self::$atomics["_int_is_reload"] = new Atomic(0); - self::$atomics["wait_msg_id"] = new Atomic(0); - self::$atomics["_event_id"] = new Atomic(0); - self::$atomics["server_is_stopped"] = new Atomic(0); - if (!defined("ZM_WORKER_NUM")) define("ZM_WORKER_NUM", 1); - for($i = 0; $i < ZM_WORKER_NUM; ++$i) { - self::$atomics["_#worker_".$i] = new Atomic(0); + self::$atomics['stop_signal'] = new Atomic(0); + self::$atomics['_int_is_reload'] = new Atomic(0); + self::$atomics['wait_msg_id'] = new Atomic(0); + self::$atomics['_event_id'] = new Atomic(0); + self::$atomics['server_is_stopped'] = new Atomic(0); + if (!defined('ZM_WORKER_NUM')) { + define('ZM_WORKER_NUM', 1); + } + for ($i = 0; $i < ZM_WORKER_NUM; ++$i) { + self::$atomics['_#worker_' . $i] = new Atomic(0); } for ($i = 0; $i < 10; ++$i) { - self::$atomics["_tmp_" . $i] = new Atomic(0); + self::$atomics['_tmp_' . $i] = new Atomic(0); } - self::$atomics["ss"] = new Atomic(1); + self::$atomics['ss'] = new Atomic(1); } - - } diff --git a/src/ZM/Store/ZMBuf.php b/src/ZM/Store/ZMBuf.php index 32c0621a..0f2f7e59 100644 --- a/src/ZM/Store/ZMBuf.php +++ b/src/ZM/Store/ZMBuf.php @@ -1,4 +1,6 @@ add(1); - $hang["compare"] = $compare; - $hang["coroutine"] = $cid; - $hang["worker_id"] = server()->worker_id; - $hang["result"] = null; - SpinLock::lock("wait_api"); - $wait = LightCacheInside::get("wait_api", "wait_api"); + $api_id = ZMAtomic::get('wait_msg_id')->add(1); + $hang['compare'] = $compare; + $hang['coroutine'] = $cid; + $hang['worker_id'] = server()->worker_id; + $hang['result'] = null; + SpinLock::lock('wait_api'); + $wait = LightCacheInside::get('wait_api', 'wait_api'); $wait[$api_id] = $hang; - LightCacheInside::set("wait_api", "wait_api", $wait); - SpinLock::unlock("wait_api"); + LightCacheInside::set('wait_api', 'wait_api', $wait); + SpinLock::unlock('wait_api'); $id = swoole_timer_after($timeout * 1000, function () use ($api_id) { - $r = LightCacheInside::get("wait_api", "wait_api")[$api_id] ?? null; + $r = LightCacheInside::get('wait_api', 'wait_api')[$api_id] ?? null; if (is_array($r)) { - Coroutine::resume($r["coroutine"]); + Coroutine::resume($r['coroutine']); } }); Coroutine::suspend(); - SpinLock::lock("wait_api"); - $sess = LightCacheInside::get("wait_api", "wait_api"); - $result = $sess[$api_id]["result"] ?? null; + SpinLock::lock('wait_api'); + $sess = LightCacheInside::get('wait_api', 'wait_api'); + $result = $sess[$api_id]['result'] ?? null; unset($sess[$api_id]); - LightCacheInside::set("wait_api", "wait_api", $sess); - SpinLock::unlock("wait_api"); - if (isset($id)) swoole_timer_clear($id); - if ($result === null) return false; + LightCacheInside::set('wait_api', 'wait_api', $sess); + SpinLock::unlock('wait_api'); + if (isset($id)) { + swoole_timer_clear($id); + } + if ($result === null) { + return false; + } return $result; } - public static function resumeByWS(): bool { + /** + * @throws Exception + */ + public static function resumeByWS(): bool + { $dat = ctx()->getData(); $last = null; - SpinLock::lock("wait_api"); - $all = LightCacheInside::get("wait_api", "wait_api") ?? []; + SpinLock::lock('wait_api'); + $all = LightCacheInside::get('wait_api', 'wait_api') ?? []; foreach ($all as $k => $v) { - if (!isset($v["compare"])) continue; - foreach ($v["compare"] as $vs) { - if (!isset($v[$vs], $dat[$vs])) continue 2; + if (!isset($v['compare'])) { + continue; + } + foreach ($v['compare'] as $vs) { + if (!isset($v[$vs], $dat[$vs])) { + continue 2; + } if ($v[$vs] != $dat[$vs]) { continue 2; } @@ -64,18 +76,17 @@ class CoMessage $last = $k; } if ($last !== null) { - $all[$last]["result"] = $dat; - LightCacheInside::set("wait_api", "wait_api", $all); - SpinLock::unlock("wait_api"); - if ($all[$last]["worker_id"] != server()->worker_id) { - ProcessManager::sendActionToWorker($all[$last]["worker_id"], "resume_ws_message", $all[$last]); + $all[$last]['result'] = $dat; + LightCacheInside::set('wait_api', 'wait_api', $all); + SpinLock::unlock('wait_api'); + if ($all[$last]['worker_id'] != server()->worker_id) { + WorkerManager::sendActionToWorker($all[$last]['worker_id'], 'resume_ws_message', $all[$last]); } else { - Coroutine::resume($all[$last]["coroutine"]); + Coroutine::resume($all[$last]['coroutine']); } return true; - } else { - SpinLock::unlock("wait_api"); - return false; } + SpinLock::unlock('wait_api'); + return false; } } diff --git a/src/ZM/Utils/CoroutinePool.php b/src/ZM/Utils/CoroutinePool.php index 1abe6835..e918f1ab 100644 --- a/src/ZM/Utils/CoroutinePool.php +++ b/src/ZM/Utils/CoroutinePool.php @@ -1,9 +1,9 @@ = (self::$sizes[$name] ?? self::$default_size)) { self::$yields[] = Coroutine::getCid(); Coroutine::suspend(); @@ -30,19 +33,23 @@ class CoroutinePool }); } - public static function defaultSize(int $size) { + public static function defaultSize(int $size) + { self::$default_size = $size; } - public static function setSize($name, int $size) { + public static function setSize($name, int $size) + { self::$sizes[$name] = $size; } - public static function getRunningCoroutineCount($name = "default") { + public static function getRunningCoroutineCount($name = 'default') + { return count(self::$cids[$name]); } - private static function checkCids($name) { + private static function checkCids($name) + { if (in_array(Coroutine::getCid(), self::$cids[$name])) { $a = array_search(Coroutine::getCid(), self::$cids[$name]); array_splice(self::$cids[$name], $a, 1); diff --git a/src/ZM/Utils/DataProvider.php b/src/ZM/Utils/DataProvider.php index 729e467f..8f010a85 100644 --- a/src/ZM/Utils/DataProvider.php +++ b/src/ZM/Utils/DataProvider.php @@ -1,9 +1,10 @@ - 0 && $path[0] === '/'; } } diff --git a/src/ZM/Utils/HttpUtil.php b/src/ZM/Utils/HttpUtil.php index 14e77520..14999049 100644 --- a/src/ZM/Utils/HttpUtil.php +++ b/src/ZM/Utils/HttpUtil.php @@ -1,9 +1,9 @@ -setMethod($request->server['request_method']); @@ -26,8 +27,8 @@ class HttpUtil $matcher = new UrlMatcher(RouteManager::$routes ?? new RouteCollection(), $context); $matched = $matcher->match($uri); } catch (ResourceNotFoundException $e) { - if (ZMConfig::get("global", "static_file_server")["status"]) { - HttpUtil::handleStaticPage($request->server["request_uri"], $response); + if (ZMConfig::get('global', 'static_file_server')['status']) { + HttpUtil::handleStaticPage($request->server['request_uri'], $response); return null; } $matched = null; @@ -36,72 +37,76 @@ class HttpUtil } if ($matched !== null) { $node = [ - "route" => RouteManager::$routes->get($matched["_route"])->getPath(), - "class" => $matched["_class"], - "method" => $matched["_method"], - "request_method" => $request->server['request_method'] + 'route' => RouteManager::$routes->get($matched['_route'])->getPath(), + 'class' => $matched['_class'], + 'method' => $matched['_method'], + 'request_method' => $request->server['request_method'], ]; - unset($matched["_class"], $matched["_method"]); + unset($matched['_class'], $matched['_method']); $params = $matched; return true; - } else { - return false; } + return false; } - public static function getHttpCodePage(int $http_code) { - if (isset(ZMConfig::get("global", "http_default_code_page")[$http_code])) { - return Coroutine::readFile(DataProvider::getResourceFolder() . "html/" . ZMConfig::get("global", "http_default_code_page")[$http_code]); - } else return null; + public static function getHttpCodePage(int $http_code) + { + if (isset(ZMConfig::get('global', 'http_default_code_page')[$http_code])) { + return Coroutine::readFile(DataProvider::getResourceFolder() . 'html/' . ZMConfig::get('global', 'http_default_code_page')[$http_code]); + } + return null; } /** * @param $uri - * @param Response|\Swoole\Http\Response $response - * @param array $settings + * @param Response|\Swoole\Http\Response $response * @return bool */ - public static function handleStaticPage($uri, $response, $settings = []) { - $base_dir = $settings["document_root"] ?? ZMConfig::get("global", "static_file_server")["document_root"]; - $base_index = $settings["document_index"] ?? ZMConfig::get("global", "static_file_server")["document_index"]; + public static function handleStaticPage($uri, $response, array $settings = []) + { + $base_dir = $settings['document_root'] ?? ZMConfig::get('global', 'static_file_server')['document_root']; + $base_index = $settings['document_index'] ?? ZMConfig::get('global', 'static_file_server')['document_index']; $path = realpath($base_dir . urldecode($uri)); if ($path !== false) { - if (is_dir($path)) $path = $path . '/'; + if (is_dir($path)) { + $path = $path . '/'; + } $work = realpath($base_dir) . '/'; if (strpos($path, $work) !== 0) { - Console::info("[403] " . $uri); + Console::info('[403] ' . $uri); self::responseCodePage($response, 403); return true; } if (is_dir($path)) { - if (mb_substr($uri, -1, 1) != "/") { - Console::info("[302] " . $uri); - $response->redirect($uri . "/", 302); + if (mb_substr($uri, -1, 1) != '/') { + Console::info('[302] ' . $uri); + $response->redirect($uri . '/', 302); return true; } foreach ($base_index as $vp) { - if (is_file($path . "/" . $vp)) { - Console::info("[200] " . $uri); - $exp = strtolower(pathinfo($path . $vp)['extension'] ?? "unknown"); - $response->setHeader("Content-Type", ZMConfig::get("file_header")[$exp] ?? "application/octet-stream"); + if (is_file($path . '/' . $vp)) { + Console::info('[200] ' . $uri); + $exp = strtolower(pathinfo($path . $vp)['extension'] ?? 'unknown'); + $response->setHeader('Content-Type', ZMConfig::get('file_header')[$exp] ?? 'application/octet-stream'); $response->end(file_get_contents($path . $vp)); return true; } } } elseif (is_file($path)) { - Console::info("[200] " . $uri); - $exp = strtolower(pathinfo($path)['extension'] ?? "unknown"); - $response->setHeader("Content-Type", ZMConfig::get("file_header")[$exp] ?? "application/octet-stream"); + Console::info('[200] ' . $uri); + $exp = strtolower(pathinfo($path)['extension'] ?? 'unknown'); + $response->setHeader('Content-Type', ZMConfig::get('file_header')[$exp] ?? 'application/octet-stream'); $response->end(file_get_contents($path)); return true; } } - Console::info("[404] " . $uri); + Console::info('[404] ' . $uri); self::responseCodePage($response, 404); return true; } - public static function responseCodePage($response, $code) { + public static function responseCodePage($response, $code) + { $response->status($code); $response->end(self::getHttpCodePage($code)); } diff --git a/src/ZM/Utils/Manager/ModuleManager.php b/src/ZM/Utils/Manager/ModuleManager.php index e9d6bf8d..3c2705a5 100644 --- a/src/ZM/Utils/Manager/ModuleManager.php +++ b/src/ZM/Utils/Manager/ModuleManager.php @@ -1,9 +1,9 @@ setOutputPath($path); $packer->setOverride(); $packer->pack(); @@ -106,16 +123,16 @@ class ModuleManager /** * 解包模块 * @param $module - * @param array $options * @return array|false */ - public static function unpackModule($module, array $options = []) { + public static function unpackModule($module, array $options = []) + { try { $packer = new ModuleUnpacker($module); - return $packer->unpack((bool)$options["overwrite-light-cache"], (bool)$options["overwrite-zm-data"], (bool)$options["overwrite-source"], (bool)$options["ignore-depends"]); + return $packer->unpack((bool) $options['overwrite-light-cache'], (bool) $options['overwrite-zm-data'], (bool) $options['overwrite-source'], (bool) $options['ignore-depends']); } catch (ZMException $e) { Console::error($e->getMessage()); return false; } } -} \ No newline at end of file +} diff --git a/src/ZM/Utils/Manager/ProcessManager.php b/src/ZM/Utils/Manager/ProcessManager.php index f64dcf7c..143e5109 100644 --- a/src/ZM/Utils/Manager/ProcessManager.php +++ b/src/ZM/Utils/Manager/ProcessManager.php @@ -1,9 +1,11 @@ -route, "/"); - $route_name = $prefix . ($tail === "" ? "" : "/") . $tail; - Console::debug("添加路由:" . $route_name); + $tail = trim($vss->route, '/'); + $route_name = $prefix . ($tail === '' ? '' : '/') . $tail; + Console::debug('添加路由:' . $route_name); $route = new Route($route_name, ['_class' => $class, '_method' => $method]); $route->setMethods($vss->request_method); self::$routes->add(md5($route_name), $route); } - public static function addStaticFileRoute($route, $path) { - $tail = trim($route, "/"); - $route_name = ($tail === "" ? "" : "/") . $tail . "/{filename}"; - Console::debug("添加静态文件路由:" . $route_name); - $route = new Route($route_name, ['_class' => RouteManager::class, '_method' => "onStaticRoute"]); + public static function addStaticFileRoute($route, $path) + { + $tail = trim($route, '/'); + $route_name = ($tail === '' ? '' : '/') . $tail . '/{filename}'; + Console::debug('添加静态文件路由:' . $route_name); + $route = new Route($route_name, ['_class' => RouteManager::class, '_method' => 'onStaticRoute']); //echo $path.PHP_EOL; - LightCacheInside::set("static_route", $route->getPath(), $path); + LightCacheInside::set('static_route', $route->getPath(), $path); self::$routes->add(md5($route_name), $route); } - public function onStaticRoute($params) { - $route_path = self::$routes->get($params["_route"])->getPath(); - if(($path = LightCacheInside::get("static_route", $route_path)) === null) { + public function onStaticRoute($params) + { + $route_path = self::$routes->get($params['_route'])->getPath(); + if (($path = LightCacheInside::get('static_route', $route_path)) === null) { ctx()->getResponse()->endWithStatus(404); return false; } - unset($params["_route"]); + unset($params['_route']); $obj = array_shift($params); return new StaticFileHandler($obj, $path); } -} \ No newline at end of file +} diff --git a/src/ZM/Utils/Manager/TaskManager.php b/src/ZM/Utils/Manager/TaskManager.php index 802aa7ce..2e4d0100 100644 --- a/src/ZM/Utils/Manager/TaskManager.php +++ b/src/ZM/Utils/Manager/TaskManager.php @@ -1,25 +1,27 @@ -setting["task_worker_num"])) { - Console::warning(zm_internal_errcode("E00056") . "未开启 TaskWorker 进程,请先修改 global 配置文件启用!"); + public static function runTask($task_name, int $timeout = -1, ...$params) + { + if (!isset(server()->setting['task_worker_num'])) { + Console::warning(zm_internal_errcode('E00056') . '未开启 TaskWorker 进程,请先修改 global 配置文件启用!'); return false; } - $r = server()->taskwait(["task" => $task_name, "params" => $params], $timeout); - return $r === false ? false : $r["result"]; + $r = server()->taskwait(['task' => $task_name, 'params' => $params], $timeout); + return $r === false ? false : $r['result']; } -} \ No newline at end of file +} diff --git a/src/ZM/Utils/Manager/WorkerManager.php b/src/ZM/Utils/Manager/WorkerManager.php index 40afc4b1..097d36b6 100644 --- a/src/ZM/Utils/Manager/WorkerManager.php +++ b/src/ZM/Utils/Manager/WorkerManager.php @@ -1,5 +1,7 @@ method = quick_reply_closure($data["data"][1]); - $obj->match = $data["data"][0]; - $obj->class = ""; + $obj->method = quick_reply_closure($data['data'][1]); + $obj->match = $data['data'][0]; + $obj->class = ''; EventManager::addEvent(CQCommand::class, $obj); break; - case "eval": - eval($data["data"]); + case 'eval': + eval($data['data']); break; - case "call_static": - call_user_func_array([$data["data"]["class"], $data["data"]["method"]], $data["data"]["params"]); + case 'call_static': + call_user_func_array([$data['data']['class'], $data['data']['method']], $data['data']['params']); break; - case "save_persistence": + case 'save_persistence': LightCache::savePersistence(); break; - case "resume_ws_message": - $obj = $data["data"]; - Coroutine::resume($obj["coroutine"]); + case 'resume_ws_message': + $obj = $data['data']; + Coroutine::resume($obj['coroutine']); break; - case "getWorkerCache": - $r = WorkerCache::get($data["key"]); - $action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r]; + case 'getWorkerCache': + $r = WorkerCache::get($data['key']); + $action = ['action' => 'returnWorkerCache', 'cid' => $data['cid'], 'value' => $r]; $server->sendMessage(json_encode($action, 256), $src_worker_id); break; - case "setWorkerCache": - $r = WorkerCache::set($data["key"], $data["value"]); - $action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r]; + case 'setWorkerCache': + $r = WorkerCache::set($data['key'], $data['value']); + $action = ['action' => 'returnWorkerCache', 'cid' => $data['cid'], 'value' => $r]; $server->sendMessage(json_encode($action, 256), $src_worker_id); break; - case "unsetWorkerCache": - $r = WorkerCache::unset($data["key"]); - $action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r]; + case 'unsetWorkerCache': + $r = WorkerCache::unset($data['key']); + $action = ['action' => 'returnWorkerCache', 'cid' => $data['cid'], 'value' => $r]; $server->sendMessage(json_encode($action, 256), $src_worker_id); break; - case "hasKeyWorkerCache": - $r = WorkerCache::hasKey($data["key"], $data["subkey"]); - $action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r]; + case 'hasKeyWorkerCache': + $r = WorkerCache::hasKey($data['key'], $data['subkey']); + $action = ['action' => 'returnWorkerCache', 'cid' => $data['cid'], 'value' => $r]; $server->sendMessage(json_encode($action, 256), $src_worker_id); break; - case "asyncAddWorkerCache": - WorkerCache::add($data["key"], $data["value"], true); + case 'asyncAddWorkerCache': + WorkerCache::add($data['key'], $data['value'], true); break; - case "asyncSubWorkerCache": - WorkerCache::sub($data["key"], $data["value"], true); + case 'asyncSubWorkerCache': + WorkerCache::sub($data['key'], $data['value'], true); break; - case "asyncSetWorkerCache": - WorkerCache::set($data["key"], $data["value"], true); + case 'asyncSetWorkerCache': + WorkerCache::set($data['key'], $data['value'], true); break; - case "asyncUnsetWorkerCache": - WorkerCache::unset($data["key"], true); + case 'asyncUnsetWorkerCache': + WorkerCache::unset($data['key'], true); break; - case "addWorkerCache": - $r = WorkerCache::add($data["key"], $data["value"]); - $action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r]; + case 'addWorkerCache': + $r = WorkerCache::add($data['key'], $data['value']); + $action = ['action' => 'returnWorkerCache', 'cid' => $data['cid'], 'value' => $r]; $server->sendMessage(json_encode($action, 256), $src_worker_id); break; - case "subWorkerCache": - $r = WorkerCache::sub($data["key"], $data["value"]); - $action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r]; + case 'subWorkerCache': + $r = WorkerCache::sub($data['key'], $data['value']); + $action = ['action' => 'returnWorkerCache', 'cid' => $data['cid'], 'value' => $r]; $server->sendMessage(json_encode($action, 256), $src_worker_id); break; - case "returnWorkerCache": - WorkerCache::$transfer[$data["cid"]] = $data["value"]; - zm_resume($data["cid"]); + case 'returnWorkerCache': + WorkerCache::$transfer[$data['cid']] = $data['value']; + zm_resume($data['cid']); break; default: $dispatcher = new EventDispatcher(OnPipeMessageEvent::class); $dispatcher->setRuleFunction(function (OnPipeMessageEvent $v) use ($data) { - return $v->action == $data["action"]; + return $v->action == $data['action']; }); $dispatcher->dispatchEvents($data); break; @@ -111,9 +113,9 @@ class WorkerManager */ public static function sendActionToWorker($worker_id, $action, $data) { - $obj = ["action" => $action, "data" => $data]; + $obj = ['action' => $action, 'data' => $data]; if (server()->worker_id === -1 && server()->getManagerPid() != posix_getpid()) { - Console::warning(zm_internal_errcode("E00022") . "Cannot send worker action from master or manager process!"); + Console::warning(zm_internal_errcode('E00022') . 'Cannot send worker action from master or manager process!'); return; } if (server()->worker_id == $worker_id) { @@ -132,10 +134,12 @@ class WorkerManager Console::warning("Cannot call '" . __FUNCTION__ . "' in non-worker process!"); return; } - foreach ((LightCacheInside::get("wait_api", "wait_api") ?? []) as $v) { - if (isset($v["coroutine"], $v["worker_id"])) { - if (server()->worker_id == $v["worker_id"]) Coroutine::resume($v["coroutine"]); + foreach ((LightCacheInside::get('wait_api', 'wait_api') ?? []) as $v) { + if (isset($v['coroutine'], $v['worker_id'])) { + if (server()->worker_id == $v['worker_id']) { + Coroutine::resume($v['coroutine']); + } } } } -} \ No newline at end of file +} diff --git a/src/ZM/Utils/MessageUtil.php b/src/ZM/Utils/MessageUtil.php index 0abe0ae9..12d76864 100644 --- a/src/ZM/Utils/MessageUtil.php +++ b/src/ZM/Utils/MessageUtil.php @@ -1,9 +1,10 @@ -type == "image") { - $result = ZMRequest::downloadFile($v->params["url"], $path . "/" . $v->params["file"]); + if ($v->type == 'image') { + $result = ZMRequest::downloadFile($v->params['url'], $path . '/' . $v->params['file']); if ($result === false) { - Console::warning(zm_internal_errcode("E00060") . "图片 " . $v->params["url"] . " 下载失败!"); + Console::warning(zm_internal_errcode('E00060') . '图片 ' . $v->params['url'] . ' 下载失败!'); return false; } - $files[] = $path . "/" . $v->params["file"]; + $files[] = $path . '/' . $v->params['file']; } } return $files; @@ -47,19 +51,20 @@ class MessageUtil /** * 检查消息中是否含有图片 CQ 码 * @param $msg - * @return bool */ - public static function containsImage($msg): bool { + public static function containsImage($msg): bool + { $cq = CQ::getAllCQ($msg, true); foreach ($cq as $v) { - if ($v->type == "image") { + if ($v->type == 'image') { return true; } } return false; } - public static function isAtMe($msg, $me_id): bool { + public static function isAtMe($msg, $me_id): bool + { return strpos($msg, CQ::at($me_id)) !== false; } @@ -69,20 +74,19 @@ class MessageUtil * type == 1 : 返回图片的 file://路径 CQ 码(路径必须为绝对路径) * type == 2 : 返回图片的 http://xxx CQ 码(默认为 /images/ 路径就是文件对应所在的目录) * @param $file - * @param int $type - * @return string */ - public static function getImageCQFromLocal($file, int $type = 0): string { + public static function getImageCQFromLocal($file, int $type = 0): string + { switch ($type) { case 0: - return CQ::image("base64://" . base64_encode(file_get_contents($file))); + return CQ::image('base64://' . base64_encode(file_get_contents($file))); case 1: - return CQ::image("file://" . $file); + return CQ::image('file://' . $file); case 2: $info = pathinfo($file); - return CQ::image(ZMConfig::get("global", "http_reverse_link") . "/images/" . $info["basename"]); + return CQ::image(ZMConfig::get('global', 'http_reverse_link') . '/images/' . $info['basename']); } - return ""; + return ''; } /** @@ -90,12 +94,15 @@ class MessageUtil * @param $msg * @return array|string[] */ - public static function splitCommand($msg): array { - $word = explodeMsg(str_replace("\r", "", $msg)); - if (empty($word)) $word = [""]; + public static function splitCommand($msg): array + { + $word = explodeMsg(str_replace("\r", '', $msg)); + if (empty($word)) { + $word = ['']; + } if (count(explode("\n", $word[0])) >= 2) { $enter = explode("\n", $msg); - $first = split_explode(" ", array_shift($enter)); + $first = split_explode(' ', array_shift($enter)); $word = array_merge($first, $enter); foreach ($word as $k => $v) { $word[$k] = trim($v); @@ -107,9 +114,9 @@ class MessageUtil /** * @param $msg * @param $obj - * @return MatchResult */ - public static function matchCommand($msg, $obj): MatchResult { + public static function matchCommand($msg, $obj): MatchResult + { $ls = EventManager::$events[CQCommand::class] ?? []; if (is_array($msg)) { $msg = self::arrayToStr($msg); @@ -117,33 +124,39 @@ class MessageUtil $word = self::splitCommand($msg); $matched = new MatchResult(); foreach ($ls as $v) { - if (array_diff([$v->match, $v->pattern, $v->regex, $v->keyword, $v->end_with, $v->start_with], [""]) == []) continue; - elseif (($v->user_id == 0 || ($v->user_id == $obj["user_id"])) && - ($v->group_id == 0 || ($v->group_id == ($obj["group_id"] ?? 0))) && - ($v->message_type == '' || ($v->message_type == $obj["message_type"])) + if (array_diff([$v->match, $v->pattern, $v->regex, $v->keyword, $v->end_with, $v->start_with], ['']) == []) { + continue; + } + if (($v->user_id == 0 || ($v->user_id == $obj['user_id'])) + && ($v->group_id == 0 || ($v->group_id == ($obj['group_id'] ?? 0))) + && ($v->message_type == '' || ($v->message_type == $obj['message_type'])) ) { - if (($word[0] != "" && $v->match == $word[0]) || in_array($word[0], $v->alias)) { + if (($word[0] != '' && $v->match == $word[0]) || in_array($word[0], $v->alias)) { array_shift($word); $matched->match = $word; $matched->object = $v; $matched->status = true; break; - } elseif ($v->start_with != "" && mb_substr($msg, 0, mb_strlen($v->start_with)) === $v->start_with) { + } + if ($v->start_with != '' && mb_substr($msg, 0, mb_strlen($v->start_with)) === $v->start_with) { $matched->match = [mb_substr($msg, mb_strlen($v->start_with))]; $matched->object = $v; $matched->status = true; break; - } elseif ($v->end_with != "" && mb_substr($msg, 0 - mb_strlen($v->end_with)) === $v->end_with) { + } + if ($v->end_with != '' && mb_substr($msg, 0 - mb_strlen($v->end_with)) === $v->end_with) { $matched->match = [substr($msg, 0, strripos($msg, $v->end_with))]; $matched->object = $v; $matched->status = true; break; - } elseif ($v->keyword != "" && mb_strpos($msg, $v->keyword) !== false) { + } + if ($v->keyword != '' && mb_strpos($msg, $v->keyword) !== false) { $matched->match = explode($v->keyword, $msg); $matched->object = $v; $matched->status = true; break; - } elseif ($v->pattern != "") { + } + if ($v->pattern != '') { $match = matchArgs($v->pattern, $msg); if ($match !== false) { $matched->match = $match; @@ -151,8 +164,8 @@ class MessageUtil $matched->status = true; break; } - } elseif ($v->regex != "") { - if (preg_match("/" . $v->regex . "/u", $msg, $word2) != 0) { + } elseif ($v->regex != '') { + if (preg_match('/' . $v->regex . '/u', $msg, $word2) != 0) { $matched->match = $word2; $matched->object = $v; $matched->status = true; @@ -164,20 +177,24 @@ class MessageUtil return $matched; } - public static function addShortCommand($command, string $reply) { + /** + * @param $command + * @throws Exception + */ + public static function addShortCommand($command, string $reply) + { for ($i = 0; $i < ZM_WORKER_NUM; ++$i) { - ProcessManager::sendActionToWorker($i, "add_short_command", [$command, $reply]); + WorkerManager::sendActionToWorker($i, 'add_short_command', [$command, $reply]); } } /** * 字符串转数组 * @param $msg - * @param bool $ignore_space * @param false $trim_text - * @return array */ - public static function strToArray($msg, bool $ignore_space = true, bool $trim_text = false): array { + public static function strToArray($msg, bool $ignore_space = true, bool $trim_text = false): array + { $arr = []; while (($rear = mb_strstr($msg, '[CQ:')) !== false && ($end = mb_strstr($rear, ']', true)) !== false) { // 把 [CQ: 前面的文字生成段落 @@ -188,14 +205,14 @@ class MessageUtil } // 处理 CQ 码 $content = mb_substr($end, 4); - $cq = explode(",", $content); + $cq = explode(',', $content); $object_type = array_shift($cq); $object_params = []; foreach ($cq as $v) { - $key = mb_strstr($v, "=", true); - $object_params[$key] = CQ::decode(mb_substr(mb_strstr($v, "="), 1), true); + $key = mb_strstr($v, '=', true); + $object_params[$key] = CQ::decode(mb_substr(mb_strstr($v, '='), 1), true); } - $arr[] = ["type" => $object_type, "data" => $object_params]; + $arr[] = ['type' => $object_type, 'data' => $object_params]; $msg = mb_substr(mb_strstr($rear, ']'), 1); } if (($trim_msg = trim($msg)) !== '' || ($msg !== '' && !$ignore_space)) { @@ -207,23 +224,22 @@ class MessageUtil /** * 数组转字符串 * 纪念一下,这段代码完全由AI生成,没有人知道它是怎么写的,这句话是我自己写的,不知道是不是有人知道的 - * @param array $array - * @return string * @author Copilot */ - public static function arrayToStr(array $array): string { - $str = ""; + public static function arrayToStr(array $array): string + { + $str = ''; foreach ($array as $v) { if ($v['type'] == 'text') { $str .= $v['data']['text']; } else { - $str .= "[CQ:" . $v['type']; + $str .= '[CQ:' . $v['type']; foreach ($v['data'] as $key => $value) { - $str .= "," . $key . "=" . CQ::encode($value, true); + $str .= ',' . $key . '=' . CQ::encode($value, true); } - $str .= "]"; + $str .= ']'; } } return $str; } -} \ No newline at end of file +} diff --git a/src/ZM/Utils/SignalListener.php b/src/ZM/Utils/SignalListener.php index 9f85b72b..1bc9d389 100644 --- a/src/ZM/Utils/SignalListener.php +++ b/src/ZM/Utils/SignalListener.php @@ -1,9 +1,9 @@ get() === 1) { - zm_atomic("_int_is_reload")->set(0); + if (zm_atomic('_int_is_reload')->get() === 1) { + zm_atomic('_int_is_reload')->set(0); $server->reload(); } else { echo "\r"; - Console::warning("Server interrupted(SIGINT) on Master."); - Console::warning("Server will be shutdown."); + Console::warning('Server interrupted(SIGINT) on Master.'); + Console::warning('Server will be shutdown.'); Process::kill($server->master_pid, SIGTERM); } }); @@ -39,39 +39,40 @@ class SignalListener /** * 监听Manager进程的Ctrl+C */ - public static function signalManager() { + public static function signalManager() + { $func = function () { if (\server()->master_pid == \server()->manager_pid) { echo "\r"; - Console::warning("Server interrupted(SIGINT) on Manager."); - swoole_timer_after(2, function() { + Console::warning('Server interrupted(SIGINT) on Manager.'); + swoole_timer_after(2, function () { Process::kill(posix_getpid(), SIGTERM); }); } else { - Console::verbose("Interrupted in manager!"); + Console::verbose('Interrupted in manager!'); } self::processKillerPrompt(); }; - Console::debug("Listening Manager SIGINT"); - if (version_compare(SWOOLE_VERSION, "4.6.7") >= 0) { + Console::debug('Listening Manager SIGINT'); + if (version_compare(SWOOLE_VERSION, '4.6.7') >= 0) { Process::signal(SIGINT, $func); - } elseif (extension_loaded("pcntl")) { + } elseif (extension_loaded('pcntl')) { pcntl_signal(SIGINT, $func); } } /** * 监听Worker/TaskWorker进程的Ctrl+C - * @param Server $server * @param $worker_id */ - public static function signalWorker(Server $server, $worker_id) { - Console::debug("Listening Worker #".$worker_id." SIGINT"); - Process::signal(SIGINT, function () use ($worker_id, $server) { + public static function signalWorker(Server $server, $worker_id) + { + Console::debug('Listening Worker #' . $worker_id . ' SIGINT'); + Process::signal(SIGINT, function () use ($server) { if ($server->master_pid == $server->worker_pid) { // 当Swoole以单进程模型运行的时候,Worker需要监听杀死的信号 echo "\r"; - Console::warning("Server interrupted(SIGINT) on Worker."); - swoole_timer_after(2, function() { + Console::warning('Server interrupted(SIGINT) on Worker.'); + swoole_timer_after(2, function () { Process::kill(posix_getpid(), SIGTERM); }); self::processKillerPrompt(); @@ -84,24 +85,25 @@ class SignalListener /** * 按5次Ctrl+C后强行杀死框架的处理函数 */ - private static function processKillerPrompt() { + private static function processKillerPrompt() + { if (self::$manager_kill_time > 0) { if (self::$manager_kill_time >= 5) { $file_path = _zm_pid_dir(); $flist = DataProvider::scanDirFiles($file_path, false, true); - foreach($flist as $file) { + foreach ($flist as $file) { $name = explode('.', $file); if (end($name) == 'pid' && $name[0] !== 'manager') { - $pid = file_get_contents($file_path.'/'.$file); + $pid = file_get_contents($file_path . '/' . $file); Process::kill($pid, SIGKILL); } - unlink($file_path.'/'.$file); + unlink($file_path . '/' . $file); } } else { echo "\r"; - Console::log("再按" . (5 - self::$manager_kill_time) . "次Ctrl+C所有Worker进程就会被强制杀死", 'red'); + Console::log('再按' . (5 - self::$manager_kill_time) . '次Ctrl+C所有Worker进程就会被强制杀死', 'red'); } } - self::$manager_kill_time++; + ++self::$manager_kill_time; } -} \ No newline at end of file +} diff --git a/src/ZM/Utils/SingletonTrait.php b/src/ZM/Utils/SingletonTrait.php index 53295e92..b7fe5e08 100644 --- a/src/ZM/Utils/SingletonTrait.php +++ b/src/ZM/Utils/SingletonTrait.php @@ -1,24 +1,27 @@ -setRuleFunction(function ($v) use ($it) { - /** @var TerminalCommand $v */ + /* @var TerminalCommand $v */ return !empty($it) && ($v->command == $it[0] || $v->alias == $it[0]); }); $dispatcher->setReturnFunction(function () { EventDispatcher::interrupt('none'); }); $dispatcher->dispatchEvents($it); - if ($dispatcher->store !== 'none' && $cmd !== "") { - Console::info("Command not found: " . $cmd); + if ($dispatcher->store !== 'none' && $cmd !== '') { + Console::info('Command not found: ' . $cmd); return true; } return false; } - public static function log($type, $log_msg) { + public static function log($type, $log_msg) + { ob_start(); - if (!in_array($type, ["log", "info", "debug", "success", "warning", "error", "verbose"])) { + if (!in_array($type, ['log', 'info', 'debug', 'success', 'warning', 'error', 'verbose'])) { ob_get_clean(); return; } Console::$type($log_msg); $r = ob_get_clean(); - $all = ManagerGM::getAllByName("terminal"); + $all = ManagerGM::getAllByName('terminal'); foreach ($all as $v) { server()->send($v->getFd(), "\r" . $r); - server()->send($v->getFd(), ">>> "); + server()->send($v->getFd(), '>>> '); } } - public static function init() { - Console::debug("Initializing Terminal..."); + public static function init() + { + Console::debug('Initializing Terminal...'); foreach ((EventManager::$events[TerminalCommand::class] ?? []) as $v) { - if ($v->command == "help") { + if ($v->command == 'help') { self::$default_commands = true; break; } @@ -75,7 +79,7 @@ class Terminal foreach ($reflection->getMethods() as $v) { $r = $reader->getMethodAnnotation($v, TerminalCommand::class); if ($r !== null) { - Console::debug("adding command " . $r->command); + Console::debug('adding command ' . $r->command); $r->class = Terminal::class; $r->method = $v->getName(); EventManager::addEvent(TerminalCommand::class, $r); @@ -87,13 +91,14 @@ class Terminal /** * @TerminalCommand(command="help",alias="h",description="显示帮助菜单") */ - public function help() { + public function help() + { $help = []; foreach ((EventManager::$events[TerminalCommand::class] ?? []) as $v) { /** @var TerminalCommand $v */ - $cmd = $v->command . ($v->alias !== "" ? (" | " . $v->alias) : ""); - $painted = Console::setColor($v->command, "green") . ($v->alias !== "" ? (" | " . Console::setColor($v->alias, "green")) : ""); - $help[] = $painted . ":" . str_pad("", 16 - strlen($cmd) - 1) . ($v->description === "" ? "<无描述>" : $v->description); + $cmd = $v->command . ($v->alias !== '' ? (' | ' . $v->alias) : ''); + $painted = Console::setColor($v->command, 'green') . ($v->alias !== '' ? (' | ' . Console::setColor($v->alias, 'green')) : ''); + $help[] = $painted . ':' . str_pad('', 16 - strlen($cmd) - 1) . ($v->description === '' ? '<无描述>' : $v->description); } echo implode("\n", $help) . PHP_EOL; } @@ -102,61 +107,71 @@ class Terminal * @TerminalCommand(command="status",description="显示Swoole Server运行状态(需要安装league/climate组件)") * @noinspection PhpFullyQualifiedNameUsageInspection */ - public function status() { - if (!class_exists("\League\CLImate\CLImate")) { - Console::warning("你还没有安装 league/climate 组件,无法使用此功能!"); + public function status() + { + if (!class_exists('\\League\\CLImate\\CLImate')) { + Console::warning('你还没有安装 league/climate 组件,无法使用此功能!'); return; } - $climate = new \League\CLImate\CLImate; + $climate = new \League\CLImate\CLImate(); $climate->output->addDefault('buffer'); $objs = server()->stats(); $climate->columns($objs); $obj = $climate->output->get('buffer')->get(); - $climate->output->get("buffer")->clean(); + $climate->output->get('buffer')->clean(); echo $obj; } /** * @TerminalCommand(command="logtest",description="测试log的显示等级") */ - public function testlog() { - Console::log(date("[H:i:s]") . " [L] This is normal msg. (0)"); - Console::error("This is error msg. (0)"); - Console::warning("This is warning msg. (1)"); - Console::info("This is info msg. (2)"); - Console::success("This is success msg. (2)"); - Console::verbose("This is verbose msg. (3)"); - Console::debug("This is debug msg. (4)"); + public function testlog() + { + Console::log(date('[H:i:s]') . ' [L] This is normal msg. (0)'); + Console::error('This is error msg. (0)'); + Console::warning('This is warning msg. (1)'); + Console::info('This is info msg. (2)'); + Console::success('This is success msg. (2)'); + Console::verbose('This is verbose msg. (3)'); + Console::debug('This is debug msg. (4)'); } /** * @TerminalCommand(command="call",description="用于执行不需要参数的动态函数,比如 `call \Module\Example\Hello hitokoto`") * @param $it */ - public function call($it) { + public function call($it) + { $class_name = $it[1]; $function_name = $it[2]; $class = new $class_name([]); - $r = $class->$function_name(); - if (is_string($r)) Console::success($r); + $r = $class->{$function_name}(); + if (is_string($r)) { + Console::success($r); + } } /** * @TerminalCommand(command="level",description="设置log等级,例如 `level 0|1|2|3|4`") * @param $it */ - public function level($it) { + public function level($it) + { $level = intval(is_numeric($it[1] ?? 99) ? ($it[1] ?? 99) : 99); - if ($level > 4 || $level < 0) Console::warning("Usage: 'level 0|1|2|3|4'"); - else Console::setLevel($level) || Console::success("Success!!"); + if ($level > 4 || $level < 0) { + Console::warning("Usage: 'level 0|1|2|3|4'"); + } else { + Console::setLevel($level) || Console::success('Success!!'); + } } /** * @TerminalCommand(command="bc",description="eval执行代码,但输入必须是将代码base64之后的,如 `bc em1faW5mbygn5L2g5aW9Jyk7`") * @param $it */ - public function bc($it) { + public function bc($it) + { $code = base64_decode($it[1] ?? '', true); try { eval($code); @@ -168,21 +183,24 @@ class Terminal * @TerminalCommand(command="echo",description="输出内容,用法:`echo hello`") * @param $it */ - public function echoI($it) { + public function echoI($it) + { Console::info($it[1]); } /** * @TerminalCommand(command="stop",description="停止框架") */ - public function stop() { + public function stop() + { posix_kill(server()->master_pid, SIGTERM); } /** * @TerminalCommand(command="reload",alias="r",description="重启框架(重载用户代码)") */ - public function reload() { + public function reload() + { Process::kill(server()->master_pid, SIGUSR1); } } diff --git a/src/ZM/Utils/ZMUtil.php b/src/ZM/Utils/ZMUtil.php index 71467519..84c6423f 100644 --- a/src/ZM/Utils/ZMUtil.php +++ b/src/ZM/Utils/ZMUtil.php @@ -1,9 +1,9 @@ = 4) Console::trace(); + if (Console::getLevel() >= 4) { + Console::trace(); + } ZMAtomic::get('stop_signal')->set(1); server()->shutdown(); } @@ -39,29 +44,31 @@ class ZMUtil /** * @throws Exception */ - public static function reload() { + public static function reload() + { Process::kill(server()->master_pid, SIGUSR1); } - public static function getModInstance($class) { + public static function getModInstance($class) + { if (!isset(ZMBuf::$instance[$class])) { //Console::debug('Class instance $class not exist, so I created it.'); return ZMBuf::$instance[$class] = new $class(); - } else { - return ZMBuf::$instance[$class]; } + return ZMBuf::$instance[$class]; } /** * 在工作进程中返回可以通过reload重新加载的php文件列表 * @return string[]|string[][] */ - public static function getReloadableFiles(): array { + public static function getReloadableFiles(): array + { $array_map = []; foreach (array_diff( - get_included_files(), - Framework::$loaded_files - ) as $key => $x) { + get_included_files(), + Framework::$loaded_files + ) as $key => $x) { $array_map[$key] = str_replace(DataProvider::getSourceRootDir() . '/', '', $x); } return $array_map; @@ -71,11 +78,12 @@ class ZMUtil * 使用Psr-4标准获取目录下的所有类 * @param $dir * @param $base_namespace - * @param null|mixed $rule - * @param bool $return_path_value - * @return String[] + * @param null|mixed $rule + * @param bool $return_path_value + * @return string[] */ - public static function getClassesPsr4($dir, $base_namespace, $rule = null, $return_path_value = false): array { + public static function getClassesPsr4($dir, $base_namespace, $rule = null, $return_path_value = false): array + { // 预先读取下composer的file列表 $composer = json_decode(file_get_contents(DataProvider::getSourceRootDir() . '/composer.json'), true); $classes = []; @@ -85,16 +93,30 @@ class ZMUtil $pathinfo = pathinfo($v); if (($pathinfo['extension'] ?? '') == 'php') { if ($rule === null) { //规则未设置回调时候,使用默认的识别过滤规则 - if (substr(file_get_contents($dir . '/' . $v), 6, 6) == '#plain') continue; - elseif (mb_substr($pathinfo["basename"], 0, 7) == 'global_' || mb_substr($pathinfo["basename"], 0, 7) == 'script_') continue; - foreach (($composer['autoload']['files'] ?? []) as $fi) { - if (md5_file(DataProvider::getSourceRootDir().'/'.$fi) == md5_file($dir.'/'.$v)) continue 2; + /*if (substr(file_get_contents($dir . '/' . $v), 6, 6) == '#plain') { + continue; + }*/ + if (file_exists($dir . '/' . $pathinfo['basename'] . '.plain')) { + continue; } - } elseif (is_callable($rule) && !($rule($dir, $pathinfo))) continue; + if (mb_substr($pathinfo['basename'], 0, 7) == 'global_' || mb_substr($pathinfo['basename'], 0, 7) == 'script_') { + continue; + } + foreach (($composer['autoload']['files'] ?? []) as $fi) { + if (md5_file(DataProvider::getSourceRootDir() . '/' . $fi) == md5_file($dir . '/' . $v)) { + continue 2; + } + } + } elseif (is_callable($rule) && !($rule($dir, $pathinfo))) { + continue; + } $dirname = $pathinfo['dirname'] == '.' ? '' : (str_replace('/', '\\', $pathinfo['dirname']) . '\\'); $class_name = $base_namespace . '\\' . $dirname . $pathinfo['filename']; - if (is_string($return_path_value)) $classes[$class_name] = $return_path_value . "/" .$v; - else $classes[] = $class_name; + if (is_string($return_path_value)) { + $classes[$class_name] = $return_path_value . '/' . $v; + } else { + $classes[] = $class_name; + } } } return $classes; diff --git a/src/ZM/ZMServer.php b/src/ZM/ZMServer.php index 70104bd6..798f35f8 100644 --- a/src/ZM/ZMServer.php +++ b/src/ZM/ZMServer.php @@ -1,5 +1,7 @@ app_name = $app_name; } - public function addModule($module_class) { + public function addModule($module_class) + { $this->modules[] = $module_class; } - public function run() { + public function run() + { Console::setLevel(4); foreach ($this->modules as $module_class) { foreach ($module_class->getEvents() as $event) { @@ -34,16 +39,18 @@ class ZMServer } } echo "Running...\n"; - if (defined("WORKDING_DIR")) throw new InitException(); + if (defined('WORKDING_DIR')) { + throw new InitException(); + } _zm_env_check(); - define("WORKING_DIR", getcwd()); - define("SOURCE_ROOT_DIR", WORKING_DIR); - define("LOAD_MODE", is_dir(SOURCE_ROOT_DIR . "/src/ZM") ? 0 : 1); - define("FRAMEWORK_ROOT_DIR", realpath(__DIR__ . "/../../")); - define("ZM_VERSION_ID", ConsoleApplication::VERSION_ID); - define("ZM_VERSION", ConsoleApplication::VERSION); + define('WORKING_DIR', getcwd()); + define('SOURCE_ROOT_DIR', WORKING_DIR); + define('LOAD_MODE', is_dir(SOURCE_ROOT_DIR . '/src/ZM') ? 0 : 1); + define('FRAMEWORK_ROOT_DIR', realpath(__DIR__ . '/../../')); + define('ZM_VERSION_ID', ConsoleApplication::VERSION_ID); + define('ZM_VERSION', ConsoleApplication::VERSION); $options = array_map(function ($x) { return $x->getDefault(); }, RunServerCommand::exportDefinition()->getOptions()); @@ -53,7 +60,8 @@ class ZMServer /** * @return mixed */ - public function getAppName() { + public function getAppName() + { return $this->app_name; } -} \ No newline at end of file +} diff --git a/src/ZM/global_defines.php b/src/ZM/global_defines.php index b46424d0..8af53448 100644 --- a/src/ZM/global_defines.php +++ b/src/ZM/global_defines.php @@ -1,28 +1,34 @@ -= 4.5.0 !"); - if (version_compare(PHP_VERSION, "7.2") == -1) die(zm_internal_errcode("E00003") . "PHP >= 7.2 required."); - if (version_compare(SWOOLE_VERSION, "4.6.7") < 0 && !extension_loaded("pcntl")) { - Console::error(zm_internal_errcode("E00004") . "Swoole 版本必须不低于 4.6.7 或 PHP 安装加载了 pcntl 扩展!"); - die(); + if (!extension_loaded('swoole')) { + exit(zm_internal_errcode('E00001') . "Can not find swoole extension.\n"); + } + if (version_compare(SWOOLE_VERSION, '4.5.0') == -1) { + exit(zm_internal_errcode('E00002') . 'You must install swoole version >= 4.5.0 !'); + } + if (version_compare(PHP_VERSION, '7.2') == -1) { + exit(zm_internal_errcode('E00003') . 'PHP >= 7.2 required.'); + } + if (version_compare(SWOOLE_VERSION, '4.6.7') < 0 && !extension_loaded('pcntl')) { + Console::error(zm_internal_errcode('E00004') . 'Swoole 版本必须不低于 4.6.7 或 PHP 安装加载了 pcntl 扩展!'); + exit(); } } @@ -50,11 +60,10 @@ function _zm_env_check() * 使用自己定义的万(san)能分割函数 * @param $msg * @param bool $ban_comma - * @return array */ function explodeMsg($msg, $ban_comma = false): array { - $msg = str_replace(" ", "\n", trim($msg)); + $msg = str_replace(' ', "\n", trim($msg)); if (!$ban_comma) { //$msg = str_replace(",", "\n", $msg); $msg = str_replace("\t", "\n", $msg); @@ -62,7 +71,9 @@ function explodeMsg($msg, $ban_comma = false): array $msgs = explode("\n", $msg); $ls = []; foreach ($msgs as $v) { - if (trim($v) == "") continue; + if (trim($v) == '') { + continue; + } $ls[] = trim($v); } return $ls; @@ -72,41 +83,45 @@ function explodeMsg($msg, $ban_comma = false): array function unicode_decode($str) { return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', function ($matches) { - return mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UCS-2BE"); + return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UCS-2BE'); }, $str); } function matchPattern($pattern, $context): bool { - if (mb_substr($pattern, 0, 1) == "" && mb_substr($context, 0, 1) == "") + if (mb_substr($pattern, 0, 1) == '' && mb_substr($context, 0, 1) == '') { return true; - if ('*' == mb_substr($pattern, 0, 1) && "" != mb_substr($pattern, 1, 1) && "" == mb_substr($context, 0, 1)) + } + if (mb_substr($pattern, 0, 1) == '*' && mb_substr($pattern, 1, 1) != '' && mb_substr($context, 0, 1) == '') { return false; - if (mb_substr($pattern, 0, 1) == mb_substr($context, 0, 1)) + } + if (mb_substr($pattern, 0, 1) == mb_substr($context, 0, 1)) { return matchPattern(mb_substr($pattern, 1), mb_substr($context, 1)); - if (mb_substr($pattern, 0, 1) == "*") + } + if (mb_substr($pattern, 0, 1) == '*') { return matchPattern(mb_substr($pattern, 1), $context) || matchPattern($pattern, mb_substr($context, 1)); + } return false; } function split_explode($del, $str, $divide_en = false): array { $str = explode($del, $str); - for ($i = 0; $i < mb_strlen($str[0]); $i++) { + for ($i = 0; $i < mb_strlen($str[0]); ++$i) { if ( - is_numeric(mb_substr($str[0], $i, 1)) && - ( - !is_numeric(mb_substr($str[0], $i - 1, 1)) && - mb_substr($str[0], $i - 1, 1) != ' ' && - ctype_alpha(mb_substr($str[0], $i - 1, 1)) === false + is_numeric(mb_substr($str[0], $i, 1)) + && ( + !is_numeric(mb_substr($str[0], $i - 1, 1)) + && mb_substr($str[0], $i - 1, 1) != ' ' + && ctype_alpha(mb_substr($str[0], $i - 1, 1)) === false ) ) { - $str[0] = mb_substr($str[0], 0, $i) . " " . mb_substr($str[0], $i); + $str[0] = mb_substr($str[0], 0, $i) . ' ' . mb_substr($str[0], $i); } elseif ( - $divide_en && - ctype_alnum(mb_substr($str[0], $i, 1)) && - !ctype_alnum(mb_substr($str[0], $i - 1, 1)) && - mb_substr($str[0], $i - 1, 1) != ' ' + $divide_en + && ctype_alnum(mb_substr($str[0], $i, 1)) + && !ctype_alnum(mb_substr($str[0], $i - 1, 1)) + && mb_substr($str[0], $i - 1, 1) != ' ' ) { $str[0] = mb_substr($str[0], 0, $i) . ' ' . mb_substr($str[0], $i); } @@ -115,31 +130,37 @@ function split_explode($del, $str, $divide_en = false): array //echo $str."\n"; $ls = []; foreach (explode($del, $str) as $v) { - if (trim($v) == "") continue; + if (trim($v) == '') { + continue; + } $ls[] = $v; } //var_dump($ls); - return $ls == [] ? [""] : $ls; + return $ls == [] ? [''] : $ls; } function matchArgs($pattern, $context) { $result = []; if (matchPattern($pattern, $context)) { - if (mb_strpos($pattern, "*") === false) return []; - $exp = explode("*", $pattern); + if (mb_strpos($pattern, '*') === false) { + return []; + } + $exp = explode('*', $pattern); $i = 0; foreach ($exp as $k => $v) { //echo "[MATCH$k] " . $v . PHP_EOL; - if ($v == "" && $k == 0) continue; - elseif ($v == "" && $k == count($exp) - 1) { - $context = $context . "^EOL"; - $v = "^EOL"; + if ($v == '' && $k == 0) { + continue; } - $cur_var = ""; + if ($v == '' && $k == count($exp) - 1) { + $context = $context . '^EOL'; + $v = '^EOL'; + } + $cur_var = ''; //echo mb_substr($context, $i) . "|" . $v . PHP_EOL; $ori = $i; - while (($a = mb_substr($context, $i, mb_strlen($v))) != $v && $a != "") { + while (($a = mb_substr($context, $i, mb_strlen($v))) != $v && $a != '') { $cur_var .= mb_substr($context, $i, 1); ++$i; } @@ -150,7 +171,8 @@ function matchArgs($pattern, $context) $i += mb_strlen($v); } return $result; - } else return false; + } + return false; } function connectIsQQ(): bool @@ -176,7 +198,7 @@ function getAnnotations(): array foreach (EventManager::$events as $v) { foreach ($v as $vs) { //echo get_class($vs).": ".$vs->class." => ".$vs->method.PHP_EOL; - if ($vs->class == $s["class"] && $vs->method == $s["function"]) { + if ($vs->class == $s['class'] && $vs->method == $s['function']) { $list[get_class($vs)][] = $vs; } } @@ -187,50 +209,56 @@ function getAnnotations(): array function set_coroutine_params($array) { $cid = Co::getCid(); - if ($cid == -1) die(zm_internal_errcode("E00061") . "Cannot set coroutine params at none coroutine mode."); - if (isset(Context::$context[$cid])) Context::$context[$cid] = array_merge(Context::$context[$cid], $array); - else Context::$context[$cid] = $array; + if ($cid == -1) { + exit(zm_internal_errcode('E00061') . 'Cannot set coroutine params at none coroutine mode.'); + } + if (isset(Context::$context[$cid])) { + Context::$context[$cid] = array_merge(Context::$context[$cid], $array); + } else { + Context::$context[$cid] = $array; + } foreach (Context::$context as $c => $v) { - if (!Co::exists($c)) unset(Context::$context[$c], ZMBuf::$context_class[$c]); + if (!Co::exists($c)) { + unset(Context::$context[$c], ZMBuf::$context_class[$c]); + } } } -/** - * @return ContextInterface|null - */ function context(): ?ContextInterface { return ctx(); } -/** - * @return ContextInterface|null - */ function ctx(): ?ContextInterface { $cid = Co::getCid(); - $c_class = ZMConfig::get("global", "context_class"); + $c_class = ZMConfig::get('global', 'context_class'); if (isset(Context::$context[$cid])) { return ZMBuf::$context_class[$cid] ?? (ZMBuf::$context_class[$cid] = new $c_class($cid)); - } else { - Console::debug("未找到当前协程的上下文($cid),正在找父进程的上下文"); - while (($pcid = Co::getPcid($cid)) !== -1) { - $cid = $pcid; - if (isset(Context::$context[$cid])) return ZMBuf::$context_class[$cid] ?? (ZMBuf::$context_class[$cid] = new $c_class($cid)); - } - return null; } + Console::debug("未找到当前协程的上下文({$cid}),正在找父进程的上下文"); + while (($pcid = Co::getPcid($cid)) !== -1) { + $cid = $pcid; + if (isset(Context::$context[$cid])) { + return ZMBuf::$context_class[$cid] ?? (ZMBuf::$context_class[$cid] = new $c_class($cid)); + } + } + + return null; } function onebot_target_id_name($message_type): string { - return ($message_type == "group" ? "group_id" : "user_id"); + return $message_type == 'group' ? 'group_id' : 'user_id'; } function zm_sleep($s = 1): bool { - if (Coroutine::getCid() != -1) System::sleep($s); - else usleep($s * 1000 * 1000); + if (Coroutine::getCid() != -1) { + System::sleep($s); + } else { + usleep($s * 1000 * 1000); + } return true; } @@ -266,12 +294,12 @@ function call_with_catch($callable) try { $callable(); } catch (Exception $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00033") . "Uncaught exception " . get_class($e) . ": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00033') . 'Uncaught exception ' . get_class($e) . ': ' . $error_msg); Console::trace(); } catch (Error $e) { - $error_msg = $e->getMessage() . " at " . $e->getFile() . "(" . $e->getLine() . ")"; - Console::error(zm_internal_errcode("E00033") . "Uncaught " . get_class($e) . ": " . $error_msg); + $error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'; + Console::error(zm_internal_errcode('E00033') . 'Uncaught ' . get_class($e) . ': ' . $error_msg); Console::trace(); } } @@ -280,7 +308,7 @@ function zm_timer_tick($ms, callable $callable) { if (zm_cid() === -1) { return go(function () use ($ms, $callable) { - Console::debug("Adding extra timer tick of " . $ms . " ms"); + Console::debug('Adding extra timer tick of ' . $ms . ' ms'); Swoole\Timer::tick($ms, function () use ($callable) { call_with_catch($callable); }); @@ -299,7 +327,7 @@ function zm_go(callable $callable) function zm_data_hash($v): string { - return md5($v["user_id"] . "^" . $v["self_id"] . "^" . $v["message_type"] . "^" . ($v[$v["message_type"] . "_id"] ?? $v["user_id"])); + return md5($v['user_id'] . '^' . $v['self_id'] . '^' . $v['message_type'] . '^' . ($v[$v['message_type'] . '_id'] ?? $v['user_id'])); } function server(): ?Server @@ -309,36 +337,37 @@ function server(): ?Server /** * 获取缓存当前框架pid的临时目录 - * @return string */ function _zm_pid_dir(): string { global $_ZM_HASH; - if (!isset($_ZM_HASH)) $_ZM_HASH = md5(DataProvider::getWorkingDir()); + if (!isset($_ZM_HASH)) { + $_ZM_HASH = md5(DataProvider::getWorkingDir()); + } return '/tmp/.zm_' . $_ZM_HASH; } /** - * @return OneBotV11 * @throws RobotNotFoundException * @throws ZMException + * @return OneBotV11 */ function bot() { - if (($conn = LightCacheInside::get("connect", "conn_fd")) == -2) { + if (($conn = LightCacheInside::get('connect', 'conn_fd')) == -2) { return OneBotV11::getRandom(); - } elseif ($conn != -1) { - if (($obj = ManagerGM::get($conn)) !== null) return new OneBotV11($obj); - else throw new RobotNotFoundException("单机器人连接模式可能连接了多个机器人!"); - } else { - throw new RobotNotFoundException("没有任何机器人连接到框架!"); } + if ($conn != -1) { + if (($obj = ManagerGM::get($conn)) !== null) { + return new OneBotV11($obj); + } + throw new RobotNotFoundException('单机器人连接模式可能连接了多个机器人!'); + } + throw new RobotNotFoundException('没有任何机器人连接到框架!'); } /** * 获取同类型所有连接的文件描述符 ID - * @param string $type - * @return array * @author 854854321 */ function getAllFdByConnectType(string $type = 'default'): array @@ -360,10 +389,10 @@ function uuidgen($uppercase = false): string try { $data = random_bytes(16); } catch (Exception $e) { - return ""; + return ''; } - $data[6] = chr(ord($data[6]) & 0x0f | 0x40); - $data[8] = chr(ord($data[8]) & 0x3f | 0x80); + $data[6] = chr(ord($data[6]) & 0x0F | 0x40); + $data[8] = chr(ord($data[8]) & 0x3F | 0x80); return $uppercase ? strtoupper(vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4))) : vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } @@ -432,5 +461,5 @@ function quick_reply_closure($reply) function zm_internal_errcode($code): string { - return "[ErrCode:$code] "; + return "[ErrCode:{$code}] "; } diff --git a/src/ZM/script_orm_bootstrap.php b/src/ZM/script_orm_bootstrap.php deleted file mode 100644 index fb756ae1..00000000 --- a/src/ZM/script_orm_bootstrap.php +++ /dev/null @@ -1,18 +0,0 @@ - 'pdo_mysql', - 'user' => 'root', - 'password' => '', - 'dbname' => 'foo', -); - -$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode); -$entityManager = EntityManager::create($dbParams, $config); diff --git a/src/ZM/script_phar_stub.php b/src/ZM/script_phar_stub.php index 3c10e4cf..215ad62e 100644 --- a/src/ZM/script_phar_stub.php +++ b/src/ZM/script_phar_stub.php @@ -1,10 +1,12 @@ false]; \ No newline at end of file +return json_decode(file_get_contents(__DIR__ . '/zmplugin.json'), true) ?? ['zm_module' => false]; diff --git a/src/ZM/script_setup_loader.php b/src/ZM/script_setup_loader.php index 5f8ffcd7..f816b067 100644 --- a/src/ZM/script_setup_loader.php +++ b/src/ZM/script_setup_loader.php @@ -1,5 +1,7 @@ initEnv(); } catch (InitException $e) { - } $base_path = DataProvider::getSourceRootDir(); $scan_paths = []; - $composer = json_decode(file_get_contents($base_path . "/composer.json"), true); - foreach (($composer["autoload"]["psr-4"] ?? []) as $k => $v) { - if (is_dir($base_path . "/" . $v) && !in_array($v, $composer["extra"]["exclude_annotate"] ?? [])) { - $scan_paths[trim($k, "\\")] = $base_path . "/" . $v; + $composer = json_decode(file_get_contents($base_path . '/composer.json'), true); + foreach (($composer['autoload']['psr-4'] ?? []) as $k => $v) { + if (is_dir($base_path . '/' . $v) && !in_array($v, $composer['extra']['exclude_annotate'] ?? [])) { + $scan_paths[trim($k, '\\')] = $base_path . '/' . $v; } } - foreach (($composer["autoload-dev"]["psr-4"] ?? []) as $k => $v) { - if (is_dir($base_path . "/" . $v) && !in_array($v, $composer["extra"]["exclude_annotate"] ?? [])) { - $scan_paths[trim($k, "\\")] = $base_path . "/" . $v; + foreach (($composer['autoload-dev']['psr-4'] ?? []) as $k => $v) { + if (is_dir($base_path . '/' . $v) && !in_array($v, $composer['extra']['exclude_annotate'] ?? [])) { + $scan_paths[trim($k, '\\')] = $base_path . '/' . $v; } } $all_event_class = []; @@ -46,23 +47,23 @@ try { $annotation = $method_annotations[0]; if ($annotation instanceof SwooleHandler) { $event_list[] = [ - "class" => $v, - "method" => $vs->getName(), - "event" => $annotation->event + 'class' => $v, + 'method' => $vs->getName(), + 'event' => $annotation->event, ]; } elseif ($annotation instanceof OnSetup) { $setup_list[] = [ - "class" => $v, - "method" => $vs->getName() + 'class' => $v, + 'method' => $vs->getName(), ]; } } } } - echo json_encode(["setup" => $setup_list, "event" => $event_list]); + echo json_encode(['setup' => $setup_list, 'event' => $event_list]); } catch (Throwable $e) { - $stderr = fopen("php://stderr", "w"); - fwrite($stderr, zm_internal_errcode("E00031") . $e->getMessage() . " in " . $e->getFile() . " at line " . $e->getLine() . PHP_EOL); + $stderr = fopen('php://stderr', 'w'); + fwrite($stderr, zm_internal_errcode('E00031') . $e->getMessage() . ' in ' . $e->getFile() . ' at line ' . $e->getLine() . PHP_EOL); fclose($stderr); exit(1); } @@ -79,4 +80,4 @@ try { 在最开始单独启动进程,加载一遍所有类,获取需要在启动前就执行的类,然后在启动的时候执行。 这样就可以不在爷进程里面加载所有类,在爹进程里面 Fork 的子进程再加载所有类,每次 reload 时可以重新加载了。 以上均为乱写的,请勿完全当真,本人对待框架代码还是比较认真的。 -*/ \ No newline at end of file +*/ diff --git a/src/entry.php b/src/entry.php index 9dd3cff1..a43f6af4 100644 --- a/src/entry.php +++ b/src/entry.php @@ -1,5 +1,8 @@ -initEnv()->run(); \ No newline at end of file +initEnv()->run();