update to v2.4.0 (build 399)

add CheckConfigCommand.php
add config update record docs
adjust swoole version to 4.5.0
fix stop and reload bugs
add $_running_annotation
add remote terminal
update global config
add timer tick exception handler
add zm_xxx global functions
add isAtMe(), splitCommand(), matchCommand() function for MessageUtil
add workerAction(), sendActionToWorker(), resumeAllWorkerCoroutines() functions for ProcessManager
optimize CQCommand match function
add custom TerminalCommand annotation
add TuringAPI
add getReloadableFiles() function for ZMUtil
This commit is contained in:
jerry
2021-03-24 23:34:46 +08:00
parent 28f7f20728
commit 6155236d3c
39 changed files with 1244 additions and 252 deletions

View File

@@ -134,10 +134,6 @@ set_coroutine_params(["data" => [
别名:`context()`,获取当前协程的上下文,见 [上下文](/component/context/)。
## zm_debug()
同 `Console::debug($msg)`。
## zm_sleep()
协程版 `sleep()` 函数。
@@ -255,4 +251,62 @@ bot()->sendPrivateMsg(123456, "你好啊!!");
定义:`getAllFdByConnectType(string $type = 'default'): array`
当 `$type` 为 `qq` 时,则返回所有 OneBot 机器人接入的 WebSocket 连接号。
当 `$type` 为 `qq` 时,则返回所有 OneBot 机器人接入的 WebSocket 连接号。
## zm_dump()
更漂亮地输出变量值,可替代 `var_dump()`。
```php
class Pass {
public $foo = 123;
public $bar = ["a", "b"];
}
$pass = new Pass();
$pass->obj = true;
zm_dump($pass);
```
<img src="../assets/img/image-20210321193956832.png" alt="image-20210321193956832" style="zoom:50%;" />
## zm_config()
> v2.4.0 起可用。
同 `ZMConfig::get()`。
定义:`zm_config($name, $key = null)`。
有关 ZMConfig 模块的说明,见 [指南 - 基本配置](/guide/basic-config/)。
```php
zm_config("global"); //等同于 ZMConfig::get("global");
zm_config("global", "swoole"); //等同于 ZMConfig::get("global", "swoole");
```
## zm_info()
> v2.4.0 起可用。(下面的 log 类也一样)
同 `Console::info($msg)`。
## zm_debug()
同 `Console::debug($msg)`。
## zm_warning()
同 `Console::warning($msg)`。
## zm_success()
同 `Console::success($msg)`。
## zm_error()
同 `Console::error($msg)`。
## zm_verbose()
同 `Console::verbose($msg)`。

View File

@@ -0,0 +1,89 @@
# MessageUtil 消息处理工具类
类定义:`\ZM\Utils\MessageUtil`
> 2.3.0 版本起可用。
这里放置一些机器人聊天消息处理的便捷静态方法,例如下载图片等。
## 方法
### downloadCQImage()
下载用户消息中所带的所有图片,并返回文件路径。
定义:`downloadCQImage($msg, $path = null)`
参数 `$msg` 为带图片的用户消息,例如 `你好啊!\n[CQ:image,file=a.jpg,url=https://zhamao.xin/file/hello.jpg]`
参数 `$path` 为图片下载的路径,如果不填(默认 null则指定为 `zm_data/images/` 目录,且不存在会自动创建。
```php
$r = MessageUtil::downloadCQImage("你好啊!\n[CQ:image,file=a.jpg,url=https://zhamao.xin/file/hello.jpg]");
/*
$r == [
"/path-to/zhamao-framework/zm_data/images/a.jpg"
];
*/
```
如果返回的是空数组 `[ ]`,则表明消息中没有图片。如果返回的是 `false`,则表明其中至少一张下载失败或路径有误。
### containsImage()
检查消息中是否含有图片。
定义:`containsImage($msg)`
返回:`bool`你懂的true 就是有false 就没有。
```php
MessageUtil::containsImage("[CQ:image,file=a.jpg,url=http://xxx]"); // true
MessageUtil::containsImage("[CQ:face,id=140] 咦,这是一条带表情的消息"); // false
```
### getImageCQFromLocal()
通过文件路径获取图片的发送 CQ 码。
定义:`getImageCQFromLocal($file, $type = 0)`
参数 `$file` 为图片的绝对路径。
返回:图片的 CQ 码,如 `[CQ:image,file=xxxxx]`
参数 `$type`
- `0`:以 base64 的方式发送图片,返回结果如 `[CQ:image,file=base64://xxxxxx]`
- `1`:以 `file://` 本地文件的方式发送图片,返回结果如 `[CQ:image,file=file:///path-to/images/a.jpg]`
- `2`:返回图片的 http:// CQ 码(默认为 /images/ 路径就是文件对应所在的目录),如 `[CQ:image,file=http://127.0.0.1:20001/images/a.jpg]`
### splitCommand()
切割用户消息为数组形式(`@CQCommand` 就是使用此方式切割的)
定义:`splitCommand($msg): array`
返回:数组,切分后的。
!!! tip "为什么不直接使用 explode 呢"
因为 `explode()` 只会简单粗暴的切割字符串,假设用户输入的消息中两个词中间有多个空格,则会有空的词出现。例如 `你好 我是一个长空格`。此函数会将多个空格当作一个空格来对待。
```php
MessageUtil::splitCommand("你好 我是傻瓜\n我是傻瓜二号"); // ["你好","我是傻瓜","我是傻瓜二号"]
MessageUtil::splitCommand("我有 三个空格"); // ["我有","三个空格"]
```
### matchCommand()
匹配一条消息到 `@CQCommand` 规则的注解事件,返回要执行的类和函数位置。
定义:`matchCommand($msg, $obj)`
参数 `$msg` 为消息内容。
参数 `$obj` 为事件的对象,可使用 `ctx()->getData()` 获取原先的事件体(仅限 OneBot 消息类型事件中使用)
返回:`\ZM\Entity\MatchObject` 对象,含有匹配成功与否,匹配到的注解对象,匹配到的分割词等,见 []

View File

@@ -0,0 +1,54 @@
# HTTP 路由管理
HTTP 路由管理器用作管理炸毛框架内 `@RequestMapping` 和静态目录的路由操作的,可在运行过程中编写添加路由。
类定义:`\ZM\Http\RouteManager`
> 2.3.0 版本起可用。
!!! warning "注意"
因为炸毛框架的路由实现是不基于跨进程的共享内存的,所以每次使用这里面的工具函数都需要单独在所有 Worker 进程中执行一次,最好的办法就是在启动框架时执行(`@OnStart(-1)` 即可,代表此注解事件将在每个工作进程中都被执行一次)。
## 方法
### importRouteByAnnotation()
通过注解类导入路由。(注:此方法一般为框架内部使用)
定义:`importRouteByAnnotation(RequestMapping $vss, $method, $class, $methods_annotations)`
参数 `$vss`RequestMapping 注解类,类中定义 `route``request_method` 即可。
参数 `$method, $class`:执行的目标注解事件函数位置,比如 `$class = \Module\Example\Hello::class``$method = 'hitokoto'`
参数 `$methods_annotations`:需要绑定的 Controller 注解类数组,一般数组内建议只带有一个 Controller`[$controller]`
### addStaticFileRoute()
添加一个单目录(此目录下无子目录,只有文件)并绑定为一个路由。
定义:`addStaticFileRoute($route, $path)`
参数 `$route`:绑定的目标路由,如 `/images/`
参数 `$path`:绑定的文件目录位置,如 `/root/zhamao-framework-starter/zm_data/images/`
```php
/**
* @OnStart(-1)
*/
public function onStart() {
RouteManager::addStaticFileRoute("/images/", DataProvider::getDataFolder()."images/");
}
```
## 属性
### RouteManager::$routes
此为存放路由树的变量,请谨慎操作。
定义:`\Symfony\Component\Routing\RouteCollection | null`
炸毛框架使用了 Symfony 框架的 route 组件,有关详情请查阅 [文档](https://symfony.com/doc/current/routing.html)。

View File

@@ -0,0 +1,26 @@
# TaskManager 工作进程管理
此类管理的是 TaskWorker 相关工作。有关使用 TaskWorker 的教程,见 [进阶 - 使用 TaskWorker 进程处理密集运算](/advanced/task-worker)
类定义:`\ZM\Utils\TaskManager`
使用 TaskWorker 需要先在 `global.php` 配置文件中开启!
## 方法
### runTask()
在 TaskWorker 运行任务。
定义:`runTask($task_name, $timeout = -1, ...$params)`
参数 `$task_name`:对应 `@OnTask` 注解绑定的任务函数。
参数 `$timeout`:等待任务函数最长运行的时间(秒),如果超过此时间将返回 false。
参数 `剩余`:将变量传入 TaskWorker 进程,除 Closure资源类型外可序列化的变量均可。
```php
TaskManager::runTask("heavy_task", 100, "param1", "param2");
```

View File

@@ -21,3 +21,47 @@ class ASD{
ZMUtil::getModInstance(ASD::class)->test = 5;
```
## ZMUtil::getReloadableFiles()
返回可通过热重启reload来重新加载的 php 文件列表。
以下是示例模块下的例子(直接拉取最新的框架源码并运行框架后获取的)。
```php
array:31 [
94 => "src/ZM/Context/Context.php"
95 => "src/ZM/Context/ContextInterface.php"
96 => "src/ZM/Annotation/AnnotationParser.php"
97 => "src/Custom/Annotation/Example.php"
98 => "src/ZM/Annotation/Interfaces/CustomAnnotation.php"
99 => "src/Module/Example/Hello.php"
100 => "src/ZM/Annotation/Swoole/OnStart.php"
101 => "src/ZM/Annotation/CQ/CQCommand.php"
102 => "src/ZM/Annotation/Interfaces/Level.php"
103 => "src/ZM/Annotation/Command/TerminalCommand.php"
104 => "src/ZM/Annotation/Http/RequestMapping.php"
105 => "src/ZM/Annotation/Http/RequestMethod.php"
106 => "src/ZM/Annotation/Http/Middleware.php"
107 => "src/ZM/Annotation/Interfaces/ErgodicAnnotation.php"
108 => "src/ZM/Annotation/Swoole/OnOpenEvent.php"
109 => "src/ZM/Annotation/Swoole/OnSwooleEventBase.php"
110 => "src/ZM/Annotation/Interfaces/Rule.php"
111 => "src/ZM/Annotation/Swoole/OnCloseEvent.php"
112 => "src/ZM/Annotation/Swoole/OnRequestEvent.php"
113 => "src/ZM/Http/RouteManager.php"
114 => "vendor/symfony/routing/RouteCollection.php"
115 => "vendor/symfony/routing/Route.php"
116 => "src/Module/Middleware/TimerMiddleware.php"
117 => "src/ZM/Http/MiddlewareInterface.php"
118 => "src/ZM/Annotation/Http/MiddlewareClass.php"
119 => "src/ZM/Annotation/Http/HandleBefore.php"
120 => "src/ZM/Annotation/Http/HandleAfter.php"
121 => "src/ZM/Annotation/Http/HandleException.php"
122 => "src/ZM/Event/EventManager.php"
123 => "src/ZM/Annotation/Swoole/OnSwooleEvent.php"
124 => "src/ZM/Event/EventDispatcher.php"
]
```
> 为什么不能重载所有文件?因为框架是多进程模型,而重载相当于只重新启动了一次 Worker 进程Manager 和 Master 进程未重启,所以被 Manager、Master 进程已经加载的 PHP 文件无法使用 reload 命令重新加载。详见 [进阶 - 进程间隔离](/advanced/multi-process/#_5)。