From 82a1f86bbd109bf0335c6a60f57f752de7a1efd9 Mon Sep 17 00:00:00 2001 From: whale Date: Sat, 2 May 2020 23:27:26 +0800 Subject: [PATCH] update to 1.2.1 add phar build script --- .gitignore | 3 +- bin/phar-build | 64 ++++++++++++++++++ composer.json | 5 +- phar-starter.php | 82 ++++++++++++++++++++++++ src/Framework/Console.php | 6 ++ src/Framework/DataProvider.php | 63 ++++++++++++++++++ src/Framework/FrameworkLoader.php | 35 +++++----- src/Framework/GlobalConfig.php | 3 +- src/Framework/global_functions.php | 20 ++++-- src/Module/Example/Hello.php | 11 ++-- src/ZM/Annotation/AnnotationParser.php | 15 +++-- src/ZM/Connection/CQConnection.php | 2 +- src/ZM/Connection/ConnectionManager.php | 3 +- src/ZM/DB/DB.php | 1 + src/ZM/Event/EventHandler.php | 2 +- src/ZM/Event/Swoole/RequestEvent.php | 3 +- src/ZM/Event/Swoole/WorkerStartEvent.php | 28 ++++---- src/ZM/Utils/DataProvider.php | 64 ------------------ src/ZM/Utils/ZMUtil.php | 1 + 19 files changed, 292 insertions(+), 119 deletions(-) create mode 100755 bin/phar-build create mode 100644 phar-starter.php create mode 100644 src/Framework/DataProvider.php delete mode 100644 src/ZM/Utils/DataProvider.php diff --git a/.gitignore b/.gitignore index deac3474..8823c742 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /vendor/ zm.json /zm_data/ -composer.lock \ No newline at end of file +composer.lock +/resources/server.phar diff --git a/bin/phar-build b/bin/phar-build new file mode 100755 index 00000000..30f9ddaa --- /dev/null +++ b/bin/phar-build @@ -0,0 +1,64 @@ +#!/usr/bin/env php +startBuffering(); + $src = realpath(__DIR__ . '/../'); + $hello = file_get_contents($src . '/src/Module/Example/Hello.php'); + $middleware = file_get_contents($src . '/src/Module/Middleware/TimerMiddleware.php'); + unlink($src . '/src/Module/Example/Hello.php'); + unlink($src . '/src/Module/Middleware/TimerMiddleware.php'); + if ($with_wechat_patch) { + global $wechat_patch; + $wechat = base64_decode($wechat_patch); + } else { + $wechat = false; + } + if ($wechat !== false) { + echo "Using wechat patch.\n"; + $modbase = file_get_contents($src . '/src/ZM/ModBase.php'); + unlink($src . '/src/ZM/ModBase.php'); + } + $phar->buildFromDirectory($src); + $phar->addFromString('tmp/Hello.php.bak', $hello); + $phar->addFromString('tmp/TimerMiddleware.php.bak', $middleware); + if ($wechat !== false) { + $phar->addFromString('src/ZM/ModBase.php', $wechat); + file_put_contents($src . '/src/ZM/ModBase.php', $modbase); + } + //$phar->compressFiles(Phar::GZ); + $phar->setStub($phar->createDefaultStub('phar-starter.php')); + $phar->stopBuffering(); + file_put_contents($src . '/src/Module/Example/Hello.php', $hello); + file_put_contents($src . '/src/Module/Middleware/TimerMiddleware.php', $middleware); + echo "Successfully built. Location: " . $src . "/resources/$filename\n"; +} + diff --git a/composer.json b/composer.json index 0998a710..86e0dc16 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "high-performance intelligent assistant", "minimum-stability": "stable", "license": "proprietary", - "version": "1.2.0", + "version": "1.2.1", "authors": [ { "name": "whale", @@ -22,7 +22,8 @@ "ext-json": "*", "ext-posix": "*", "ext-ctype": "*", - "ext-pcntl": "*" + "ext-pcntl": "*", + "nikic/php-parser": "^4.4" }, "repositories": { "packagist": { diff --git a/phar-starter.php b/phar-starter.php new file mode 100644 index 00000000..ddd6baa6 --- /dev/null +++ b/phar-starter.php @@ -0,0 +1,82 @@ + 30000, +]); + +date_default_timezone_set("Asia/Shanghai"); + +define('WORKING_DIR', __DIR__); + +$s = new FrameworkLoader($argv); + +function loadPhp($dir) { + $dirs = scandir($dir); + foreach ($dirs as $v) { + $path = $dir . '/' . $v; + if (is_dir($path)) { + loadPhp($path); + } else { + if (pathinfo($dir . '/' . $v)['extension'] == 'php') { + //echo 'loading '.$path.PHP_EOL; + require_once $path; + } + } + } +} + +function testEnvironment() { + $current_dir = realpath('.'); + @mkdir($current_dir . '/config/'); + if (!is_file($current_dir . '/config/global.php')) { + echo "Exporting default global config...\n"; + $global = file_get_contents(__DIR__ . '/config/global.php'); + $global = str_replace("WORKING_DIR", 'realpath("../")', $global); + file_put_contents($current_dir . '/config/global.php', $global); + } + if (!is_file($current_dir . '/config/file_header.json')) { + echo "Exporting default file_header config...\n"; + $global = file_get_contents(__DIR__ . '/config/file_header.json'); + file_put_contents($current_dir . '/config/file_header.json', $global); + } + if (!is_dir($current_dir . '/resources')) mkdir($current_dir . '/resources'); + if (!is_dir($current_dir . '/src')) mkdir($current_dir . '/src'); + if (!is_dir($current_dir . '/src')) mkdir($current_dir . '/src'); + if (!is_dir($current_dir . '/src/Module')) { + mkdir($current_dir . '/src/Module'); + mkdir($current_dir . '/src/Module/Example'); + file_put_contents($current_dir . '/src/Module/Example/Hello.php', file_get_contents(__DIR__ . '/tmp/Hello.php.bak')); + mkdir($current_dir . '/src/Module/Middleware'); + file_put_contents($current_dir . '/src/Module/Middleware/TimerMiddleware.php', file_get_contents(__DIR__ . '/tmp/TimerMiddleware.php.bak')); + } + if (!is_dir($current_dir . '/src/Custom')) { + mkdir($current_dir . '/src/Custom'); + mkdir($current_dir . '/src/Custom/Annotation'); + mkdir($current_dir . '/src/Custom/Connection'); + file_put_contents($current_dir . '/src/Custom/global_function.php', "get(); + ZMBuf::$atomics["info_level"]->set(3); + DataProvider::saveBuffer(); + ZMBuf::$atomics["info_level"]->set($origin); + return true; case '': return true; default: diff --git a/src/Framework/DataProvider.php b/src/Framework/DataProvider.php new file mode 100644 index 00000000..002fe310 --- /dev/null +++ b/src/Framework/DataProvider.php @@ -0,0 +1,63 @@ +get() >= 3) + echo $head; + foreach (self::$buffer_list as $k => $v) { + self::setJsonData($v, ZMBuf::get($k)); + } + if (ZMBuf::$atomics["info_level"]->get() >= 3) + echo Console::setColor("saved", "blue") . PHP_EOL; + } + + public static function getFrameworkLink() { + return ZMBuf::globals("http_reverse_link"); + } + + public static function getJsonData(string $string) { + if (!file_exists(self::getDataConfig() . $string)) return []; + return json_decode(file_get_contents(self::getDataConfig() . $string), true); + } + + private static function setJsonData($filename, array $args) { + Console::debug("Saving ".$filename); + file_put_contents(self::getDataConfig() . $filename, json_encode($args, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING)); + } + + public static function getDataFolder() { + return ZM_DATA; + } +} diff --git a/src/Framework/FrameworkLoader.php b/src/Framework/FrameworkLoader.php index 398821d8..bf4eff19 100644 --- a/src/Framework/FrameworkLoader.php +++ b/src/Framework/FrameworkLoader.php @@ -35,17 +35,20 @@ class FrameworkLoader /** @var Server */ private $server; - public function __construct($args = []) - { + public function __construct($args = []) { if (self::$instance !== null) die("Cannot run two FrameworkLoader in one process!"); self::$instance = $this; self::$argv = $args; - - chdir(__DIR__ . '/../..'); - define('WORKING_DIR', getcwd()); - Runtime::enableCoroutine(); $this->requireGlobalFunctions(); + if (!isPharMode()) { + define('WORKING_DIR', getcwd()); + } else { + echo "Phar mode: " . WORKING_DIR . PHP_EOL; + } $this->registerAutoloader('classLoader'); + Runtime::enableCoroutine(); + + self::$settings = new GlobalConfig(); ZMBuf::$globals = self::$settings; if (!self::$settings->success) die("Failed to load global config. Please check config/global.php file"); @@ -91,7 +94,8 @@ class FrameworkLoader "host: " . self::$settings->get("host") . ", port: " . self::$settings->get("port") . ", log_level: " . ZMBuf::$atomics["info_level"]->get() . - ", version: " . json_decode(file_get_contents(WORKING_DIR . "/composer.json"), true)["version"] + ", version: " . json_decode(file_get_contents(WORKING_DIR . "/composer.json"), true)["version"] . + "\nworking_dir: ".(isPharMode() ? realpath('.') : WORKING_DIR) ); global $motd; echo $motd . PHP_EOL; @@ -103,18 +107,15 @@ class FrameworkLoader } } - private function requireGlobalFunctions() - { - require __DIR__ . '/global_functions.php'; + private function requireGlobalFunctions() { + require_once __DIR__ . '/global_functions.php'; } - private function registerAutoloader(string $string) - { + private function registerAutoloader(string $string) { if (!spl_autoload_register($string)) die("Failed to register autoloader named \"$string\" !"); } - private function defineProperties() - { + private function defineProperties() { define("ZM_START_TIME", microtime(true)); define("ZM_DATA", self::$settings->get("zm_data")); define("CONFIG_DIR", self::$settings->get("config_dir")); @@ -128,8 +129,7 @@ class FrameworkLoader define("ZM_MATCH_SECOND", 3); } - private function selfCheck() - { + private function selfCheck() { if (!extension_loaded("swoole")) die("Can not find swoole extension.\n"); //if (!extension_loaded("gd")) die("Can not find gd extension.\n"); if (!extension_loaded("sockets")) die("Can not find sockets extension.\n"); @@ -141,8 +141,7 @@ class FrameworkLoader return true; } - public function onWorkerStart(\Swoole\Server $server, $worker_id) - { + public function onWorkerStart(\Swoole\Server $server, $worker_id) { self::$instance = $this; self::$run_time = microtime(true); EventHandler::callSwooleEvent("WorkerStart", $server, $worker_id); diff --git a/src/Framework/GlobalConfig.php b/src/Framework/GlobalConfig.php index e4413cac..d2a4fe53 100644 --- a/src/Framework/GlobalConfig.php +++ b/src/Framework/GlobalConfig.php @@ -18,7 +18,8 @@ class GlobalConfig public $success = false; public function __construct() { - include_once WORKING_DIR . '/config/global.php'; + /** @noinspection PhpIncludeInspection */ + include_once DataProvider::getWorkingDir() . '/config/global.php'; global $config; $this->success = true; $this->config = $config; diff --git a/src/Framework/global_functions.php b/src/Framework/global_functions.php index 511c21ec..4dace297 100644 --- a/src/Framework/global_functions.php +++ b/src/Framework/global_functions.php @@ -1,9 +1,14 @@ getQQ()." 已连接!"); + public function onConnect(CQConnection $conn) { + Console::info("机器人 " . $conn->getQQ() . " 已连接!"); } + /** * 向机器人发送"你好",即可回复这句话 * @CQCommand("你好") */ - public function hello(){ + public function hello() { return "你好啊,我是由炸毛框架构建的机器人!"; } @@ -40,7 +41,7 @@ class Hello extends ModBase * @RequestMapping("/httpTimer") * @Middleware("timer") */ - public function timer(){ + public function timer() { return "This page is used as testing TimerMiddleware! Do not use it in production."; } @@ -48,7 +49,7 @@ class Hello extends ModBase * 框架会默认关闭未知的WebSocket链接,因为这个绑定的事件,你可以根据你自己的需求进行修改 * @SwooleEventAt(type="open",rule="connectType:unknown") */ - public function closeUnknownConn(){ + public function closeUnknownConn() { Console::info("Unknown connection , I will close it."); $this->connection->close(); } diff --git a/src/ZM/Annotation/AnnotationParser.php b/src/ZM/Annotation/AnnotationParser.php index 24149c7a..c9bb3487 100644 --- a/src/ZM/Annotation/AnnotationParser.php +++ b/src/ZM/Annotation/AnnotationParser.php @@ -18,7 +18,7 @@ use ZM\Annotation\Swoole\{OnStart, OnTick, SwooleEventAfter, SwooleEventAt}; use ZM\Annotation\Interfaces\Rule; use ZM\Connection\WSConnection; use ZM\Http\MiddlewareInterface; -use ZM\Utils\DataProvider; +use Framework\DataProvider; use ZM\Utils\ZMUtil; class AnnotationParser @@ -30,7 +30,7 @@ class AnnotationParser */ public static function registerMods() { self::loadAnnotationClasses(); - $all_class = getAllClasses(WORKING_DIR . "/src/Module/", "Module"); + $all_class = getAllClasses(DataProvider::getWorkingDir() . "/src/Module/", "Module"); ZMBuf::$req_mapping[0] = [ 'id' => 0, 'pid' => -1, @@ -38,6 +38,7 @@ class AnnotationParser ]; $reader = new AnnotationReader(); foreach ($all_class as $v) { + Console::debug("正在检索 ".$v); $reflection_class = new ReflectionClass($v); $class_prefix = ''; $methods = $reflection_class->getMethods(ReflectionMethod::IS_PUBLIC); @@ -47,15 +48,15 @@ class AnnotationParser if ($vs instanceof Closed) { continue 2; } elseif ($vs instanceof Controller) { - Console::debug("找到 Controller 中间件: ".$vs->class); + Console::debug("找到 Controller 中间件: " . $vs->class); $class_prefix = $vs->prefix; } elseif ($vs instanceof SaveBuffer) { - Console::debug("注册自动保存的缓存变量: ".$vs->buf_name." (Dir:".$vs->sub_folder.")"); + Console::debug("注册自动保存的缓存变量: " . $vs->buf_name . " (Dir:" . $vs->sub_folder . ")"); DataProvider::addSaveBuffer($vs->buf_name, $vs->sub_folder); } elseif ($vs instanceof InitBuffer) { ZMBuf::set($vs->buf_name, []); } elseif ($vs instanceof MiddlewareClass) { - Console::verbose("正在注册中间件 " . $vs->class); + Console::verbose("正在注册中间件 " . $reflection_class->getName()); $result = [ "class" => "\\" . $reflection_class->getName() ]; @@ -299,9 +300,9 @@ class AnnotationParser $s = WORKING_DIR . '/src/' . str_replace("\\", "/", $v) . ".php"; require_once $s; } - $class = getAllClasses(WORKING_DIR . "/src/Custom/Annotation/", "Custom\\Annotation"); + $class = getAllClasses(DataProvider::getWorkingDir() . "/src/Custom/Annotation/", "Custom\\Annotation"); foreach ($class as $v) { - $s = WORKING_DIR . '/src/' . str_replace("\\", "/", $v) . ".php"; + $s = DataProvider::getWorkingDir() . '/src/' . str_replace("\\", "/", $v) . ".php"; require_once $s; } } diff --git a/src/ZM/Connection/CQConnection.php b/src/ZM/Connection/CQConnection.php index a3f2a483..28ffc434 100644 --- a/src/ZM/Connection/CQConnection.php +++ b/src/ZM/Connection/CQConnection.php @@ -20,4 +20,4 @@ class CQConnection extends WSConnection public function getType() { return "qq"; } -} \ No newline at end of file +} diff --git a/src/ZM/Connection/ConnectionManager.php b/src/ZM/Connection/ConnectionManager.php index 194e34d9..79037825 100644 --- a/src/ZM/Connection/ConnectionManager.php +++ b/src/ZM/Connection/ConnectionManager.php @@ -5,6 +5,7 @@ namespace ZM\Connection; use Framework\ZMBuf; +use Framework\DataProvider; class ConnectionManager { @@ -67,7 +68,7 @@ class ConnectionManager } public static function registerCustomClass() { - $classes = getAllClasses(WORKING_DIR . "/src/Custom/Connection/", "Custom\\Connection"); + $classes = getAllClasses(DataProvider::getWorkingDir(). "/src/Custom/Connection/", "Custom\\Connection"); ZMBuf::$custom_connection_class = $classes; } } diff --git a/src/ZM/DB/DB.php b/src/ZM/DB/DB.php index d605714a..e274c1da 100644 --- a/src/ZM/DB/DB.php +++ b/src/ZM/DB/DB.php @@ -91,6 +91,7 @@ class DB if (ZMBuf::get("sql_log") === true) { $starttime = microtime(true); } + Console::debug("MySQL: ".$line); try { $conn = ZMBuf::$sql_pool->get(); if ($conn === false) { diff --git a/src/ZM/Event/EventHandler.php b/src/ZM/Event/EventHandler.php index 9fb8b540..e322ff9f 100644 --- a/src/ZM/Event/EventHandler.php +++ b/src/ZM/Event/EventHandler.php @@ -11,7 +11,7 @@ use Framework\Console; use Framework\ZMBuf; use ZM\Event\Swoole\{MessageEvent, RequestEvent, WorkerStartEvent, WSCloseEvent, WSOpenEvent}; use ZM\Http\Response; -use ZM\Utils\DataProvider; +use Framework\DataProvider; use ZM\Utils\ZMUtil; class EventHandler diff --git a/src/ZM/Event/Swoole/RequestEvent.php b/src/ZM/Event/Swoole/RequestEvent.php index 22cfd612..9b454ba4 100644 --- a/src/ZM/Event/Swoole/RequestEvent.php +++ b/src/ZM/Event/Swoole/RequestEvent.php @@ -17,6 +17,7 @@ use ZM\Http\MiddlewareInterface; use ZM\Http\Response; use ZM\ModBase; use ZM\ModHandleType; +use Framework\DataProvider; use ZM\Utils\ZMUtil; class RequestEvent implements SwooleEvent @@ -90,7 +91,7 @@ class RequestEvent implements SwooleEvent $path = realpath($base_dir . urldecode($uri)); if ($path !== false) { if (is_dir($path)) $path = $path . '/'; - $work = realpath(WORKING_DIR) . '/'; + $work = realpath(DataProvider::getWorkingDir()) . '/'; if (strpos($path, $work) !== 0) { $this->responseStatus(403); return $this; diff --git a/src/ZM/Event/Swoole/WorkerStartEvent.php b/src/ZM/Event/Swoole/WorkerStartEvent.php index 73122f77..2f6bfc78 100644 --- a/src/ZM/Event/Swoole/WorkerStartEvent.php +++ b/src/ZM/Event/Swoole/WorkerStartEvent.php @@ -25,7 +25,7 @@ use Swoole\Server; use ZM\Exception\DbException; use ZM\ModBase; use ZM\ModHandleType; -use ZM\Utils\DataProvider; +use Framework\DataProvider; use ZM\Utils\SQLPool; use ZM\Utils\ZMUtil; @@ -50,7 +50,7 @@ class WorkerStartEvent implements SwooleEvent */ public function onActivate(): WorkerStartEvent { Console::info("Worker启动中"); - Process::signal(SIGINT, function (){ + Process::signal(SIGINT, function () { Console::warning("Server interrupted by keyboard."); ZMUtil::stop(true); }); @@ -61,16 +61,16 @@ class WorkerStartEvent implements SwooleEvent //设置炸毛buf中储存的对象 ZMBuf::$globals = new GlobalConfig(); ZMBuf::$config = []; - $file = scandir(WORKING_DIR . '/config/'); + $file = scandir(DataProvider::getWorkingDir() . '/config/'); unset($file[0], $file[1]); foreach ($file as $k => $v) { if ($v == "global.php") continue; $name = explode(".", $v); if (($prefix = end($name)) == "json") { - ZMBuf::$config[$name[0]] = json_decode(Co::readFile(WORKING_DIR . '/config/' . $v), true); + ZMBuf::$config[$name[0]] = json_decode(Co::readFile(DataProvider::getWorkingDir() . '/config/' . $v), true); Console::info("已读取配置文件:" . $v); } elseif ($prefix == "php") { - ZMBuf::$config[$name[0]] = include_once WORKING_DIR . '/config/' . $v; + ZMBuf::$config[$name[0]] = include_once DataProvider::getWorkingDir() . '/config/' . $v; if (is_array(ZMBuf::$config[$name[0]])) Console::info("已读取配置文件:" . $v); } @@ -98,7 +98,7 @@ class WorkerStartEvent implements SwooleEvent Coroutine::resume($v); } ZMBuf::unsetCache("wait_start"); - foreach(ZMBuf::$events[OnStart::class] ?? [] as $v) { + foreach (ZMBuf::$events[OnStart::class] ?? [] as $v) { $class_name = $v->class; /** @var ModBase $class */ $class = new $class_name(["server" => $this->server, "worker_id" => $this->worker_id], ModHandleType::SWOOLE_WORKER_START); @@ -136,7 +136,7 @@ class WorkerStartEvent implements SwooleEvent private function loadAllClass() { //加载phar包 Console::info("加载外部phar包中"); - $dir = WORKING_DIR . "/resources/package/"; + $dir = DataProvider::getWorkingDir() . "/resources/package/"; if (is_dir($dir)) { $list = scandir($dir); unset($list[0], $list[1]); @@ -147,8 +147,12 @@ class WorkerStartEvent implements SwooleEvent } //加载composer类 - Console::info("加载composer资源中"); - require_once WORKING_DIR . "/vendor/autoload.php"; + if (file_exists(DataProvider::getWorkingDir() . "/vendor/autoload.php")) { + Console::info("加载composer资源中"); + require_once DataProvider::getWorkingDir() . "/vendor/autoload.php"; + } else { + if(isPharMode()) require_once WORKING_DIR . "/vendor/autoload.php"; + } //加载各个模块的注解类,以及反射 Console::info("检索Module中"); @@ -158,8 +162,8 @@ class WorkerStartEvent implements SwooleEvent ConnectionManager::registerCustomClass(); //加载自定义的全局函数 - if(file_exists(WORKING_DIR."/src/Custom/global_function.php")) - require_once WORKING_DIR."/src/Custom/global_function.php"; + if (file_exists(DataProvider::getWorkingDir() . "/src/Custom/global_function.php")) + require_once DataProvider::getWorkingDir() . "/src/Custom/global_function.php"; $this->afterCheck(); } @@ -175,7 +179,7 @@ class WorkerStartEvent implements SwooleEvent */ private function afterCheck() { $context_class = ZMBuf::globals("context_class"); - if(!is_a($context_class, ContextInterface::class, true)) { + if (!is_a($context_class, ContextInterface::class, true)) { throw new Exception("Context class must implemented from ContextInterface!"); } } diff --git a/src/ZM/Utils/DataProvider.php b/src/ZM/Utils/DataProvider.php deleted file mode 100644 index e1f9682a..00000000 --- a/src/ZM/Utils/DataProvider.php +++ /dev/null @@ -1,64 +0,0 @@ -get() >= 3) - echo $head; - foreach (self::$buffer_list as $k => $v) { - self::setJsonData($v, ZMBuf::get($k)); - } - if (ZMBuf::$atomics["info_level"]->get() >= 3) - echo Console::setColor("saved", "blue") . PHP_EOL; - } - - public static function getFrameworkLink() - { - return ZMBuf::globals("http_reverse_link"); - } - - public static function getJsonData(string $string) - { - if (!file_exists(self::getDataConfig() . $string)) return []; - return json_decode(Co::readFile(self::getDataConfig() . $string), true); - } - - private static function setJsonData($filename, array $args) - { - Co::writeFile(self::getDataConfig() . $filename, json_encode($args, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING)); - } - - public static function getDataFolder() - { - return ZM_DATA; - } -} diff --git a/src/ZM/Utils/ZMUtil.php b/src/ZM/Utils/ZMUtil.php index dd25953f..e1010c13 100644 --- a/src/ZM/Utils/ZMUtil.php +++ b/src/ZM/Utils/ZMUtil.php @@ -6,6 +6,7 @@ namespace ZM\Utils; use Co; use framework\Console; +use Framework\DataProvider; use Framework\ZMBuf; class ZMUtil