mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-02 22:35:38 +08:00
Compare commits
521 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0cba01bd7 | ||
|
|
ea83ea2cce | ||
|
|
21f310852a | ||
|
|
6173cf2e37 | ||
|
|
4791099a78 | ||
|
|
9d1952f5f8 | ||
|
|
6543574695 | ||
|
|
5b1c771a2d | ||
|
|
29d7d07c8e | ||
|
|
e85e1e57b1 | ||
|
|
90a4c6803e | ||
|
|
ff1b43ad89 | ||
|
|
cdd273808c | ||
|
|
f8bcc359da | ||
|
|
ccc0280d2f | ||
|
|
bd98608d2e | ||
|
|
90b6580e80 | ||
|
|
64899a50c1 | ||
|
|
d12f0bf317 | ||
|
|
422dd81bbf | ||
|
|
3a6c821249 | ||
|
|
a12b5eadf3 | ||
|
|
27c5debcb0 | ||
|
|
594b7f5f82 | ||
|
|
2c28ed9ab8 | ||
|
|
5f3a626557 | ||
|
|
1ebcfa8e7e | ||
|
|
3edab143c3 | ||
|
|
9cd5f24d2f | ||
|
|
34919afb36 | ||
|
|
6282da4972 | ||
|
|
de4748860c | ||
|
|
c7736a7c3e | ||
|
|
3f9493ae7e | ||
|
|
dbda5dc299 | ||
|
|
c9ab695a9e | ||
|
|
bb57efc149 | ||
|
|
76543d5ec0 | ||
|
|
598f568b8c | ||
|
|
fc8c0b540a | ||
|
|
af75fc2f94 | ||
|
|
b94bbbca20 | ||
|
|
784fc1697b | ||
|
|
190eba585b | ||
|
|
f97b87d5e5 | ||
|
|
2c1a158d3e | ||
|
|
90de54c6a3 | ||
|
|
d596c315f2 | ||
|
|
52afaa3fb9 | ||
|
|
47cca37854 | ||
|
|
0fa49171b9 | ||
|
|
ea1d14ba00 | ||
|
|
a01791ddbe | ||
|
|
51a9c5c4e8 | ||
|
|
b1e37943df | ||
|
|
5459d1c5ff | ||
|
|
21373097bb | ||
|
|
f4f7327695 | ||
|
|
36fc2cb4cd | ||
|
|
b7469b9dd4 | ||
|
|
e7e77c99d0 | ||
|
|
6fbd35ed33 | ||
|
|
fba2339280 | ||
|
|
bd8270a4ae | ||
|
|
5299061c87 | ||
|
|
e843aeac55 | ||
|
|
19c792209b | ||
|
|
277d442634 | ||
|
|
51bec043e3 | ||
|
|
b7595f6f22 | ||
|
|
55181d583f | ||
|
|
b5a5a4f32e | ||
|
|
a746779efa | ||
|
|
736b6ea0a5 | ||
|
|
884f07baa6 | ||
|
|
b496c3136e | ||
|
|
bbfb40f973 | ||
|
|
a73e1fc164 | ||
|
|
ef7acb7fa0 | ||
|
|
fcd108adbe | ||
|
|
c9c76bfd10 | ||
|
|
d9302a3120 | ||
|
|
0cb3308dd1 | ||
|
|
583b9d7cf7 | ||
|
|
d7728ebc25 | ||
|
|
b6742526aa | ||
|
|
4defd8ac1b | ||
|
|
d28672e2ad | ||
|
|
94d6a51358 | ||
|
|
54eabc948f | ||
|
|
6c9e26ce83 | ||
|
|
a934037179 | ||
|
|
396444a089 | ||
|
|
699444abdd | ||
|
|
088031f807 | ||
|
|
8ce6e2c111 | ||
|
|
e7f36b9fcf | ||
|
|
dab91f526e | ||
|
|
35e23a7cbc | ||
|
|
7df05df48f | ||
|
|
707a1ae628 | ||
|
|
a65fc4076b | ||
|
|
f487897cf2 | ||
|
|
869d9ed543 | ||
|
|
8f61ed7561 | ||
|
|
8cb6a32341 | ||
|
|
687260e53c | ||
|
|
a919ce4554 | ||
|
|
d19d7acedd | ||
|
|
a393b3aff5 | ||
|
|
8c2036b6b4 | ||
|
|
dc081861ad | ||
|
|
ec76d2ba7d | ||
|
|
47ce0a8e9c | ||
|
|
f1c730962b | ||
|
|
d95a5131f6 | ||
|
|
69637cf482 | ||
|
|
25d6ec3a92 | ||
|
|
8bf5ff4e7f | ||
|
|
fd4e4be3a8 | ||
|
|
e0a01ea2ca | ||
|
|
256ccb96a6 | ||
|
|
bfffdc7d21 | ||
|
|
3bbe21268b | ||
|
|
1537e88a74 | ||
|
|
0d9711e62d | ||
|
|
0a7c5f06c6 | ||
|
|
e7a8a32b73 | ||
|
|
62b703f2e4 | ||
|
|
f44921d136 | ||
|
|
cd42545c7d | ||
|
|
0df3fd7bed | ||
|
|
56241da281 | ||
|
|
05a04104dd | ||
|
|
50d27ee186 | ||
|
|
371926b5a6 | ||
|
|
97face2406 | ||
|
|
ea64b40011 | ||
|
|
6d23e489aa | ||
|
|
f4d75e211f | ||
|
|
48f6cc644d | ||
|
|
33f517333f | ||
|
|
7253a309c7 | ||
|
|
f2aff5882d | ||
|
|
0dd61a7270 | ||
|
|
420b8e6d67 | ||
|
|
9e08919ce0 | ||
|
|
a7324f6c49 | ||
|
|
721c0834db | ||
|
|
e37629aaea | ||
|
|
a43a4a429e | ||
|
|
f5d34198e7 | ||
|
|
46604293e9 | ||
|
|
58e405cccd | ||
|
|
1deea5bebc | ||
|
|
cad5636f92 | ||
|
|
90290bee94 | ||
|
|
9f7ebceeb9 | ||
|
|
60ea2c7e12 | ||
|
|
441c866160 | ||
|
|
33d3341bb3 | ||
|
|
1d778fd78e | ||
|
|
0cd73a6304 | ||
|
|
2fedfe5b18 | ||
|
|
77c140bee6 | ||
|
|
c06e38d71f | ||
|
|
9b59cec22a | ||
|
|
306e992789 | ||
|
|
8335cfed69 | ||
|
|
4702aa1987 | ||
|
|
145e1b31a0 | ||
|
|
f2e28de20c | ||
|
|
bcaaf88edb | ||
|
|
120698fb43 | ||
|
|
dd88585ffa | ||
|
|
93a8c450ad | ||
|
|
3451434997 | ||
|
|
0bab2e74b0 | ||
|
|
c1a877489b | ||
|
|
520099aaba | ||
|
|
9bd02b3dd2 | ||
|
|
ba64f2c189 | ||
|
|
fbb194a6c5 | ||
|
|
30b2d2134b | ||
|
|
7eea71e282 | ||
|
|
e40b3029e0 | ||
|
|
17492c78fa | ||
|
|
a9276d3f72 | ||
|
|
eecbe49955 | ||
|
|
be9874a9ad | ||
|
|
b4fcc057c5 | ||
|
|
d9499dc56b | ||
|
|
f6806c88ab | ||
|
|
2caca545ad | ||
|
|
ff0f11da7f | ||
|
|
daa1822bc5 | ||
|
|
d490892092 | ||
|
|
182a4e7b06 | ||
|
|
e9beed03ea | ||
|
|
8351527aea | ||
|
|
ddff663b0b | ||
|
|
31b4fb9201 | ||
|
|
1f7f0da383 | ||
|
|
9fa1079248 | ||
|
|
ae0cf5e3d7 | ||
|
|
672369c598 | ||
|
|
73687f248b | ||
|
|
65cc2a948a | ||
|
|
299f36dcc0 | ||
|
|
f5cbce5195 | ||
|
|
a3780667b2 | ||
|
|
a21742a326 | ||
|
|
40aacb2e61 | ||
|
|
ba18869c85 | ||
|
|
a454f2c523 | ||
|
|
7caebaa6ba | ||
|
|
580abd7317 | ||
|
|
3187431611 | ||
|
|
81c37c9a0a | ||
|
|
ba5bca20da | ||
|
|
533fe187bd | ||
|
|
c4da26c19d | ||
|
|
ca7bfcc8c6 | ||
|
|
6c7b582faf | ||
|
|
6f2e6135f1 | ||
|
|
37a92e03c1 | ||
|
|
35385f8916 | ||
|
|
a2fbdd8e0a | ||
|
|
bab610722f | ||
|
|
4cabc8d132 | ||
|
|
e8bd381907 | ||
|
|
42aac802dd | ||
|
|
d748a20445 | ||
|
|
5db3ff934d | ||
|
|
9bfa3ede20 | ||
|
|
127466e546 | ||
|
|
16aa30cac7 | ||
|
|
05a3d0111b | ||
|
|
9f4b5fb14a | ||
|
|
a716e68f87 | ||
|
|
2e127771ed | ||
|
|
c6bbba6051 | ||
|
|
443ed115b0 | ||
|
|
f450b8d863 | ||
|
|
acf570e652 | ||
|
|
4e9199c68e | ||
|
|
6f5575b155 | ||
|
|
700b854434 | ||
|
|
37b5d954e9 | ||
|
|
ac50e96568 | ||
|
|
86174c2e9f | ||
|
|
c1ae1dee06 | ||
|
|
c4aedf2958 | ||
|
|
736c8f2fc0 | ||
|
|
294084299e | ||
|
|
b1d30da4bc | ||
|
|
506f2e7c0c | ||
|
|
e13660dcdc | ||
|
|
4fbe2aa5af | ||
|
|
5ddc514545 | ||
|
|
3cfcbaec16 | ||
|
|
50f06e6a4f | ||
|
|
c7e2b15629 | ||
|
|
8e81f72584 | ||
|
|
0fb5ed00f6 | ||
|
|
bf7920cc15 | ||
|
|
971f03ae0f | ||
|
|
24b9d93920 | ||
|
|
8d81f4d5df | ||
|
|
b6e135a642 | ||
|
|
d3f4ade215 | ||
|
|
56d2a52706 | ||
|
|
b40dc1e05e | ||
|
|
bed3337866 | ||
|
|
28dc73d060 | ||
|
|
5ea1226ad0 | ||
|
|
e43f2a4158 | ||
|
|
d73e771ef3 | ||
|
|
c077e9418c | ||
|
|
2ce888c84c | ||
|
|
b4d175ff98 | ||
|
|
35e18d0481 | ||
|
|
f6cccb00e3 | ||
|
|
2a82c82039 | ||
|
|
a2e8a1b582 | ||
|
|
dbd78d4b86 | ||
|
|
8105892b6e | ||
|
|
bc7d5871e4 | ||
|
|
680e6a8c5f | ||
|
|
c364084cb2 | ||
|
|
63f8042746 | ||
|
|
48e6b2cea0 | ||
|
|
228309c571 | ||
|
|
ca3a3df3ba | ||
|
|
c7df37b17c | ||
|
|
41f03fbba4 | ||
|
|
b3089c1bba | ||
|
|
c5a6f1fea4 | ||
|
|
ba2777137b | ||
|
|
6d90be164a | ||
|
|
4da6f5859a | ||
|
|
15d4ea710a | ||
|
|
f0541c1f32 | ||
|
|
2b8cab1824 | ||
|
|
61c7972915 | ||
|
|
44a0eec74c | ||
|
|
e57753e44b | ||
|
|
74e91a2950 | ||
|
|
7ce3ef41df | ||
|
|
444a77933a | ||
|
|
78f78c607d | ||
|
|
69155002dc | ||
|
|
475d14fab7 | ||
|
|
f4d7e63358 | ||
|
|
f222d2b45b | ||
|
|
d0155fe1da | ||
|
|
4737d0b507 | ||
|
|
09bd0197bb | ||
|
|
f0f120bd32 | ||
|
|
c897da29c6 | ||
|
|
e347e254e8 | ||
|
|
12363aebf0 | ||
|
|
ff0b925313 | ||
|
|
a6b4bd9b80 | ||
|
|
485fa5476c | ||
|
|
689076d97c | ||
|
|
cca6102e91 | ||
|
|
095855162b | ||
|
|
326f934013 | ||
|
|
35b0c258fe | ||
|
|
6650846b15 | ||
|
|
a33d320f4c | ||
|
|
0bcfea6aa4 | ||
|
|
db6e63e91c | ||
|
|
a7f84fb53a | ||
|
|
ce7f2b1765 | ||
|
|
abbfb59eff | ||
|
|
b57fef16f9 | ||
|
|
1706afbcd0 | ||
|
|
d01bd69aa5 | ||
|
|
e6b9ae3ee1 | ||
|
|
73b6b8045d | ||
|
|
3c87abc6e8 | ||
|
|
e95925c129 | ||
|
|
82c44d6c40 | ||
|
|
e0a268e05e | ||
|
|
487892e1d9 | ||
|
|
7ab4e88359 | ||
|
|
4702b6ee75 | ||
|
|
20cd3aa66d | ||
|
|
391114bdef | ||
|
|
ffe1052ecc | ||
|
|
b4159152a7 | ||
|
|
8fc6e4b0f7 | ||
|
|
c8938b7a4b | ||
|
|
34db1626a5 | ||
|
|
7f0c97c5b9 | ||
|
|
74050c46e7 | ||
| 3ed1cb665a | |||
|
|
a6f33ba69d | ||
|
|
176b690417 | ||
|
|
e22b1b90ec | ||
|
|
a3c560790c | ||
| 570e2108dd | |||
|
|
59c0d95e5d | ||
|
|
9ceaecdc02 | ||
|
|
19d50898ef | ||
|
|
5b62ca62ae | ||
| fb528d30ce | |||
| 5f2d5ed334 | |||
| c20e459900 | |||
| 09220825cf | |||
|
|
3d4db23d27 | ||
|
|
4496b67dcc | ||
|
|
2a13298384 | ||
|
|
d6ec404d76 | ||
|
|
3235fd4dc1 | ||
|
|
293740fee2 | ||
|
|
d3c420ec84 | ||
|
|
85ef09d43c | ||
|
|
e4561d69c4 | ||
|
|
6b4d206099 | ||
|
|
50843edf6a | ||
|
|
3a1686f8da | ||
|
|
66dd91bb97 | ||
|
|
e020e5d593 | ||
|
|
3d62663281 | ||
|
|
8d9485c02e | ||
|
|
9fb45dd683 | ||
|
|
8a4924dba9 | ||
|
|
beaf7be606 | ||
|
|
7dbd21bdf4 | ||
|
|
9ce3056203 | ||
|
|
880b4e847c | ||
|
|
71e83d5bc8 | ||
|
|
432fd92cca | ||
|
|
907a9cea25 | ||
| 07391810ff | |||
| 5063421364 | |||
| 2b4d308783 | |||
| e2f49968b3 | |||
| 229778ebf9 | |||
|
|
d2c0972c93 | ||
|
|
d300b6e518 | ||
|
|
56cb7b2223 | ||
|
|
2fc42d5d60 | ||
|
|
999e90f709 | ||
|
|
45c6cd7d2a | ||
|
|
5aa0858021 | ||
|
|
e981da3932 | ||
|
|
2685be7306 | ||
|
|
a13c4628f5 | ||
|
|
b36417454c | ||
|
|
a6f5952dee | ||
|
|
d67dfe46f6 | ||
|
|
e57cc43500 | ||
|
|
481063285b | ||
|
|
d805523dbd | ||
|
|
58267f66fc | ||
|
|
48215f2e5e | ||
|
|
7e0fc1528a | ||
|
|
c185d20a93 | ||
|
|
7ec847e576 | ||
|
|
4ee16d4fc6 | ||
|
|
59d614a24e | ||
|
|
40037b3f4b | ||
|
|
f91c8b6205 | ||
|
|
8f73a99ff7 | ||
|
|
e0f07cb396 | ||
|
|
2950ab7472 | ||
|
|
0ab4053dfb | ||
|
|
745aa0f268 | ||
|
|
12bb93c2f0 | ||
| 95ca175901 | |||
| 71585ed29d | |||
|
|
231a377718 | ||
|
|
a80ee902a9 | ||
|
|
c2d3b5f92a | ||
|
|
64365af124 | ||
|
|
60619dbffc | ||
|
|
77e77e9cc3 | ||
|
|
d72b41a902 | ||
|
|
dfddaaea94 | ||
|
|
6b872c6f74 | ||
|
|
202c8aee77 | ||
|
|
ba397a1744 | ||
|
|
d699a152d5 | ||
|
|
beef44ea50 | ||
|
|
b991a2da7b | ||
|
|
bbe4addd83 | ||
|
|
600829645d | ||
|
|
68280cfe7e | ||
|
|
c5523aa95d | ||
|
|
93a68a5582 | ||
|
|
6155236d3c | ||
| 28f7f20728 | |||
| 235256d679 | |||
| 626d569858 | |||
| 0492179bdd | |||
| 1dfd1de5c1 | |||
| d15d01c32b | |||
|
|
c9f4278d9b | ||
|
|
6aa0540c9e | ||
|
|
9689dc9db1 | ||
|
|
c20e3324d4 | ||
| 303f44cd2b | |||
| 66b73973b4 | |||
|
|
0ff4e52ed3 | ||
| b6d1f724e9 | |||
| e77b9d4970 | |||
|
|
456b102c15 | ||
|
|
cc57997abc | ||
|
|
19e61c7cc3 | ||
|
|
f908513dca | ||
|
|
7dc39e6ada | ||
|
|
b0be53554d | ||
|
|
b98048bd39 | ||
|
|
fffd3fdc95 | ||
|
|
dea9ed2ccd | ||
|
|
de5744c9e4 | ||
|
|
a23f3d8f16 | ||
|
|
0c24bfdedd | ||
|
|
c0b95c6840 | ||
|
|
e977b09e20 | ||
|
|
4ff75cf199 | ||
|
|
24e70c70ce | ||
|
|
275a7bf00b | ||
|
|
455fc79818 | ||
|
|
8740c3c255 | ||
|
|
98bfca5bb9 | ||
|
|
fc8d01ad5f | ||
|
|
d9b8df1725 | ||
|
|
9b7802ac04 | ||
|
|
6e1f3e0406 | ||
|
|
a2d4bab062 | ||
|
|
f1cefad910 | ||
|
|
957c69bd1e | ||
|
|
2902c5e805 | ||
|
|
faf9f5d988 | ||
|
|
874f061468 | ||
|
|
69521a1f1f | ||
|
|
fb9dbed306 | ||
|
|
d42158ac90 | ||
|
|
ff3ebec562 | ||
|
|
ea79de617e | ||
|
|
9e1ad6a983 | ||
|
|
c17248df31 | ||
|
|
4c116ebd86 | ||
|
|
c490fe0c1c | ||
|
|
cefdf23799 | ||
|
|
7f70642606 | ||
|
|
1d5b2609f9 | ||
|
|
a206fe8b87 | ||
|
|
fb4f6c45ce | ||
|
|
c50ae245bd | ||
|
|
f6c2131ebf | ||
|
|
543d1d2922 | ||
|
|
bb61e6f6a2 | ||
|
|
2d1bbf6b48 | ||
|
|
67e42cfe3e | ||
|
|
429a2cf230 |
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
if [ ! -d "/app/zhamao-framework/bin" ]; then
|
||||
cp -r /app/zhamao-framework-bak/* /app/zhamao-framework/
|
||||
fi
|
||||
php /app/zhamao-framework/bin/start
|
||||
38
.github/ISSUE_TEMPLATE/1_Bug_report.yaml
vendored
Normal file
38
.github/ISSUE_TEMPLATE/1_Bug_report.yaml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: 🐛 漏洞(BUG)报告
|
||||
description: ⚠️ 请不要直接在此提交安全漏洞
|
||||
labels: bug
|
||||
|
||||
body:
|
||||
- type: input
|
||||
id: affected-versions
|
||||
attributes:
|
||||
label: 受影响版本
|
||||
placeholder: x.y.z
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: 描述
|
||||
description: 请详细地描述您的问题
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce-steps
|
||||
attributes:
|
||||
label: 复现步骤
|
||||
description: |
|
||||
请尽可能地提供可以复现此步骤的漏洞。
|
||||
如果步骤过长或难以描述,您可以自行建立一个用于复现漏洞的仓库。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: possible-solution
|
||||
attributes:
|
||||
label: 解决方案
|
||||
description: 如果您对这个漏洞的成因或修复有任何意见的话,请在此提出
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: 附加信息
|
||||
description: 其他可能有帮助的信息,如日志、截图等
|
||||
19
.github/ISSUE_TEMPLATE/2_Feature_request.yaml
vendored
Normal file
19
.github/ISSUE_TEMPLATE/2_Feature_request.yaml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: 🚀 功能建议
|
||||
description: 新功能、改进的意见、草案
|
||||
labels: enhancement
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: 描述
|
||||
description: 请提供简洁清楚的描述
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: example
|
||||
attributes:
|
||||
label: 例子
|
||||
description: |
|
||||
一个简单的例子,展示该功能将如何被使用(包括代码、配置文件等)
|
||||
如果这是针对已有功能的改进,请展示改进前后使用方式(或效能)的对比
|
||||
69
.github/workflows/increment-build-number.yml
vendored
Normal file
69
.github/workflows/increment-build-number.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: Increment Build Number
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
types:
|
||||
- closed
|
||||
paths:
|
||||
- 'src/**.php'
|
||||
|
||||
jobs:
|
||||
incremental-build-number:
|
||||
if: github.event.pull_request.merged == true
|
||||
name: Incremental Build Number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: swoole, posix, json
|
||||
|
||||
- name: Setup problem matchers for PHP
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install Composer Dependencies
|
||||
run: "composer install --prefer-dist --no-progress --optimize-autoloader"
|
||||
|
||||
- name: Generate API Docs
|
||||
id: generate-api-docs
|
||||
continue-on-error: true
|
||||
run: bin/gendoc
|
||||
|
||||
- name: Commit api docs
|
||||
if: steps.generate-api-docs.outcome == 'success'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
git config --global user.name 'Github Build Bot'
|
||||
git config --global user.email 'noreply@github.com'
|
||||
git add docs
|
||||
git commit -m "update api docs"
|
||||
git push
|
||||
|
||||
- name: Increment build number
|
||||
run: sed -i -r 's/(.*)(\VERSION_ID\s=\s)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge' src/ZM/ConsoleApplication.php
|
||||
|
||||
- name: Commit build number
|
||||
run: |
|
||||
BUILD_ID=$(cat src/ZM/ConsoleApplication.php | grep "VERSION_ID = " | sed 's/[^0-9]//g')
|
||||
git config --global user.name 'Github Build Bot'
|
||||
git config --global user.email 'noreply@github.com'
|
||||
git add src/ZM/ConsoleApplication.php
|
||||
git commit -m "increment build number (build $BUILD_ID)"
|
||||
git push
|
||||
101
.github/workflows/integration-test.yml
vendored
Normal file
101
.github/workflows/integration-test.yml
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
name: Integration and Style Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**/**.php'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
- review_requested
|
||||
paths:
|
||||
- '**/**.php'
|
||||
|
||||
jobs:
|
||||
integration:
|
||||
name: Integration Test (PHP ${{ matrix.php-versions }}) (OS ${{ matrix.operating-system }})
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system: [ "ubuntu-latest", "macos-latest" ]
|
||||
php-versions: [ "7.2", "7.3", "7.4", "8.0", "8.1" ]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: swoole, posix, json
|
||||
env:
|
||||
SWOOLE_CONFIGURE_OPTS: --enable-openssl
|
||||
|
||||
- name: Setup problem matchers for PHP
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
|
||||
- name: Validate composer.json
|
||||
run: "composer validate --strict"
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install Composer Dependencies
|
||||
run: "composer install --prefer-dist --no-progress --optimize-autoloader"
|
||||
|
||||
- name: Run Static Analysis
|
||||
run: "composer analyse"
|
||||
|
||||
- name: Run PHPUnit
|
||||
run: "composer test"
|
||||
|
||||
cs-check:
|
||||
name: PHP CS Fixer Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP 7.2
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "7.2"
|
||||
extensions: swoole, posix, json
|
||||
|
||||
- name: Setup problem matchers for PHP
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
|
||||
- name: Validate composer.json
|
||||
run: "composer validate --strict"
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install Composer Dependencies
|
||||
run: "composer install --prefer-dist --no-progress --optimize-autoloader"
|
||||
|
||||
- name: Run PHP CS Fixer Check
|
||||
run: "composer cs-fix -- --dry-run --diff"
|
||||
43
.github/workflows/vuepress-deploy.yml
vendored
Normal file
43
.github/workflows/vuepress-deploy.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Docs and Script Auto Deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'ext/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Deploy docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout master
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Deploy docs to GitHub Pages
|
||||
uses: jenkey2011/vuepress-deploy@master
|
||||
env:
|
||||
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BUILD_SCRIPT: yarn && yarn docs:build
|
||||
BUILD_DIR: docs/.vuepress/dist/
|
||||
- name: Copy deployment to current folder
|
||||
run: |
|
||||
cp -r "${GITHUB_WORKSPACE}/docs/.vuepress/dist" "./deploy"
|
||||
- name: Deploy to Zhamao Server
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.ZHAMAO_XIN_PRIVATE_KEY }}
|
||||
ARGS: "-rltgoDzvO --delete"
|
||||
SOURCE: "deploy/"
|
||||
REMOTE_HOST: ${{ secrets.ZHAMAO_XIN_HOST }}
|
||||
REMOTE_USER: ${{ secrets.ZHAMAO_XIN_USER }}
|
||||
TARGET: ${{ secrets.ZHAMAO_XIN_TARGET }}
|
||||
- name: deploy script file
|
||||
uses: wlixcc/SFTP-Deploy-Action@v1.0
|
||||
with:
|
||||
username: ${{ secrets.ZHAMAO_XIN_USER }}
|
||||
server: ${{ secrets.ZHAMAO_XIN_HOST }}
|
||||
ssh_private_key: ${{ secrets.ZHAMAO_XIN_PRIVATE_KEY }}
|
||||
local_path: './ext/go.sh'
|
||||
remote_path: ${{ secrets.ZHAMAO_XIN_MAIN_TARGET }}
|
||||
83
.gitignore
vendored
83
.gitignore
vendored
@@ -1,13 +1,80 @@
|
||||
.idea/
|
||||
/src/test/
|
||||
/src/webconsole/config/
|
||||
/vendor/
|
||||
zm.json
|
||||
### Zhamao Framework ###
|
||||
/zm_data/
|
||||
composer.lock
|
||||
/resources/server.phar
|
||||
/distribute/
|
||||
/bin/.phpunit.result.cache
|
||||
/resources/zhamao.service
|
||||
/runtime/
|
||||
/tmp/
|
||||
/temp/
|
||||
/site/
|
||||
|
||||
# 框架审计文件
|
||||
audit.log
|
||||
|
||||
# 进程锁文件
|
||||
.daemon_pid
|
||||
.zm_worker_*.pid
|
||||
|
||||
### Composer ###
|
||||
composer.phar
|
||||
/vendor/
|
||||
composer.lock
|
||||
|
||||
### 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
|
||||
|
||||
### Git ###
|
||||
# 备份文件
|
||||
*.orig
|
||||
|
||||
# 解决 Merge 冲突时可能会自动生成的文件
|
||||
*.BACKUP.*
|
||||
*.BASE.*
|
||||
*.LOCAL.*
|
||||
*.REMOTE.*
|
||||
*_BACKUP_*.txt
|
||||
*_BASE_*.txt
|
||||
*_LOCAL_*.txt
|
||||
*_REMOTE_*.txt
|
||||
|
||||
# Git Hooks
|
||||
cghooks.lock
|
||||
|
||||
### VuePress ###
|
||||
/node_modules/
|
||||
/docs/.vuepress/dist/
|
||||
package-lock.json
|
||||
|
||||
### PHPUnit ###
|
||||
|
||||
# 生成的文件
|
||||
/bin/.phpunit.result.cache
|
||||
.phpunit.result.cache
|
||||
.daemon_pid
|
||||
.phpunit.cache
|
||||
|
||||
# 本地配置
|
||||
/phpunit.xml
|
||||
|
||||
# 构建目录
|
||||
/build/
|
||||
|
||||
### PhpStorm ###
|
||||
# 兼容 PHPStorm 及其他 Jetbrains IDE
|
||||
|
||||
# 除了代码格式配置和运行配置之外的所有文件
|
||||
.idea/*
|
||||
|
||||
!.idea/codeStyles
|
||||
!.idea/runConfigurations
|
||||
|
||||
### Phive ###
|
||||
/.phive/
|
||||
/tools/
|
||||
|
||||
### ASDF ###
|
||||
/.tool-version
|
||||
|
||||
85
.php-cs-fixer.php
Normal file
85
.php-cs-fixer.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
*/
|
||||
|
||||
$rules = [
|
||||
'@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,
|
||||
'php_unit_test_class_requires_covers' => false,
|
||||
'global_namespace_import' => false,
|
||||
'phpdoc_order' => false,
|
||||
];
|
||||
|
||||
if (PHP_VERSION_ID > 70400) {
|
||||
$rules['no_useless_concat_operator'] = false;
|
||||
}
|
||||
|
||||
// 'no_useless_concat_operator' => false,
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules($rules)
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__ . '/src')
|
||||
->in(__DIR__ . '/tests')
|
||||
)
|
||||
->setUsingCache(false);
|
||||
17
.run/Reload Zhamao Server.run.xml
Normal file
17
.run/Reload Zhamao Server.run.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Reload Zhamao Server" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="./zhamao server:reload && exit" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
17
.run/Run Zhamao Server.run.xml
Normal file
17
.run/Run Zhamao Server.run.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Zhamao Server" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="./zhamao server" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="./zhamao" />
|
||||
<option name="SCRIPT_OPTIONS" value="server" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
17
.run/Run watcher.run.xml
Normal file
17
.run/Run watcher.run.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run watcher" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="bin/watcher" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/zsh" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
17
.run/Stop Zhamao Server.run.xml
Normal file
17
.run/Stop Zhamao Server.run.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Stop Zhamao Server" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="./zhamao server:stop && exit" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,3 +0,0 @@
|
||||
FROM zmbot/swoole:latest
|
||||
|
||||
# TODO: auto-setup entrypoint
|
||||
132
README.md
132
README.md
@@ -1,27 +1,57 @@
|
||||
<div align="center">
|
||||
<img src="/resources/images/logo_trans.png" height = "150" alt="炸毛框架"><br>
|
||||
<img src="https://cdn.jsdelivr.net/gh/zhamao-robot/zhamao-framework/resources/images/logo_trans.png" width = "150" height = "150" alt="炸毛框架"><br>
|
||||
<h2>炸毛框架</h2>
|
||||
炸毛框架 (zhamao-framework) 是一个协程高性能的聊天机器人 + Web 服务器开发框架<br><br>
|
||||
|
||||
[]()
|
||||
[](https://github.com/zhamao-robot/zhamao-framework/blob/master/LICENSE)
|
||||
[](https://packagist.org/packages/zhamao/framework)
|
||||
[]()
|
||||
<p align="center">
|
||||
<a href="https://onebot.dev/">
|
||||
<img src="https://img.shields.io/badge/OneBot-11-black?style=flat-square" alt="OneBot">
|
||||
</a>
|
||||
|
||||
[](https://github.com/zhamao-robot/zhamao-framework/search?q=AnnotationBase)
|
||||
[](https://github.com/zhamao-robot/zhamao-framework/search?q=TODO)
|
||||
<a href="https://github.com/zhamao-robot/zhamao-framework/actions">
|
||||
<img src="https://img.shields.io/github/workflow/status/zhamao-robot/zhamao-framework/Integration%20and%20Style%20Test?label=Test&style=flat-square" alt="Integration Test">
|
||||
</a>
|
||||
|
||||
<a href="https://packagist.org/packages/zhamao/framework">
|
||||
<img src="https://img.shields.io/packagist/dt/zhamao/framework?label=Downloads&style=flat-square" alt="下载数">
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/zhamao-robot/zhamao-framework/releases">
|
||||
<img src="https://img.shields.io/packagist/v/zhamao/framework?include_prereleases&label=Release&style=flat-square" alt="最新版本">
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/zhamao-robot/zhamao-framework/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/zhamao-robot/zhamao-framework?label=License&style=flat-square" alt="开源协议">
|
||||
</a>
|
||||
|
||||
<a href="https://wpa.qq.com/msgrd?v=3&uin=627577391&site=qq&menu=yes">
|
||||
<img src="https://img.shields.io/badge/作者QQ-627577391-orange?style=flat-square" alt="作者QQ">
|
||||
</a>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<a href="https://github.com/zhamao-robot/zhamao-framework/search?q=AnnotationBase">
|
||||
<img src="https://img.shields.io/github/search/zhamao-robot/zhamao-framework/AnnotationBase?label=Annotations&style=flat-square" alt="注解数量">
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/zhamao-robot/zhamao-framework/search?q=TODO">
|
||||
<img src="https://img.shields.io/github/search/zhamao-robot/zhamao-framework/TODO?label=TODO&style=flat-square" alt="TODO">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
## 开发者注意
|
||||
开发者 QQ 群:**670821194**
|
||||
开发者 QQ 群:**670821194** [点击加入群聊](https://jq.qq.com/?_wv=1027&k=YkNI3AIr)
|
||||
|
||||
当前 v2 版本已正式发布,此 master 分支为 2.0 版本,如需查看 v1 版本,请移步 `v1-legacy` 分支!
|
||||
**如果有愿意一起开发框架本身的开发者,请提出 PR 或 Issue 参与开发!如果对框架本身的核心设计有更好的想法,可与作者成立开发组(目前仅 2 人),参与 OneBot V12 生态和框架本身的开发。**
|
||||
|
||||
2.0 版本如果有问题请第一时间加群反馈!
|
||||
**3.0已进入Alpha阶段**
|
||||
|
||||
## 简介
|
||||
炸毛框架使用 PHP 编写,采用 Swoole 扩展为基础,主要面向 API 服务,聊天机器人(OneBot 兼容的 QQ 机器人对接),包含 Websocket、HTTP 等监听和请求库,用户代码采用模块化处理,使用注解可以方便地编写各类功能。
|
||||
|
||||
炸毛框架使用 PHP 编写,采用 Swoole 扩展为基础,主要面向 API 服务,聊天机器人(OneBot 兼容的 QQ 机器人对接),包含 Websocket、HTTP
|
||||
等监听和请求库,用户代码采用模块化处理,使用注解可以方便地编写各类功能。
|
||||
|
||||
框架主要用途为 HTTP 服务器,机器人搭建框架。尤其对于 QQ 机器人消息处理较为方便和全面,提供了众多会话机制和内部调用机制,可以以各种方式设计你自己的模块。
|
||||
|
||||
@@ -40,33 +70,68 @@ public function index() {
|
||||
}
|
||||
```
|
||||
|
||||
> 从 2.7.0 版本开始,框架已支持同时使用 Annotation 和原生 Attribute 注解,供开发者根据需要自由选用。
|
||||
|
||||
## 开始
|
||||
框架首先需要部署环境,可以参考下方文档中部署环境和框架的方法进行。
|
||||
|
||||
## 文档(v2 版本)
|
||||
查看文档:[https://docs-v2.zhamao.xin/](https://docs-v2.zhamao.xin/)
|
||||
框架目前支持 Linux、WSL、macOS 环境直接运行,上述环境可直接使用下方一键安装脚本。
|
||||
|
||||
备用链接:[https://docs-v2.zhamao.me/](https://docs-v2.zhamao.me/)
|
||||
> 如果你想在其他环境安装部署,可使用 Docker、Cygwin,详见文档。
|
||||
|
||||
自行构建文档:`mkdocs build -d distribute`
|
||||
```bash
|
||||
# 检测PHP环境、安装框架
|
||||
bash <(curl -fsSL https://zhamao.xin/go.sh)
|
||||
|
||||
# 启动框架
|
||||
cd zhamao-app
|
||||
./zhamao server
|
||||
```
|
||||
|
||||
一键安装脚本还有可以自定义参数的方式,比如:
|
||||
|
||||
```bash
|
||||
# 脚本默认会检测系统的PHP,如果想直接跳过检测,安装独立的PHP版本,则添加此环境变量
|
||||
export ZM_NO_LOCAL_PHP="yes"
|
||||
# 脚本如果安装独立版本PHP,默认版本为8.0,如果想使用其他版本,则添加此环境变量指定版本
|
||||
export ZM_DOWN_PHP_VERSION="8.1"
|
||||
# 脚本默认会将框架在当前目录下的 `zhamao-app` 目录进行安装,如果想使用其他目录,则添加此环境变量
|
||||
export ZM_CUSTOM_DIR="my-custom-app"
|
||||
# 脚本默认会对本项目使用阿里云国内加速镜像,如果想使用packagist源,则添加此环境变量
|
||||
export ZM_COMPOSER_PACKAGIST="yes"
|
||||
# 执行完前面的环境变量再执行一键安装脚本,就可以实现自定义参数!
|
||||
bash <(curl -fsSL https://zhamao.xin/go.sh)
|
||||
```
|
||||
|
||||
关于其他安装方式,请参阅[文档](https://framework.zhamao.xin/guide/installation.html) 。
|
||||
|
||||
## 文档
|
||||
|
||||
查看文档(国内自建):<https://framework.zhamao.xin/>
|
||||
|
||||
备用链接(国外托管):<https://framework.zhamao.me/>
|
||||
|
||||
## 特点
|
||||
- 原生为多账号设计,支持多个机器人负载均衡
|
||||
|
||||
- 原生支持多个机器人客户端同时连接
|
||||
- 使用 Swoole 多工作进程机制和协程加持,尽可能简单的情况下提升了性能
|
||||
- 灵活的注解事件绑定机制
|
||||
- 灵活的注解事件绑定机制,可同时使用 Annotation 和原生 Attribute 注解
|
||||
- 易用的上下文,模块内随处可用
|
||||
- 采用模块化编写,可自由搭配其他 composer 组件
|
||||
- 采用模块化编写,可自由搭配其他 Composer 组件,也可单文件面向过程编写
|
||||
- 支持模块打包、热加载,分享模块更方便
|
||||
- 常驻内存,全局缓存变量随处使用,提供多种缓存方案
|
||||
- 自带 MySQL、Redis 等数据库连接池等数据库连接方案
|
||||
- 本身为 HTTP 服务器、WebSocket 服务器,可以构建属于自己的 HTTP API 接口
|
||||
- 静态文件服务器,可将前端合并到一起
|
||||
- 自带 PHP + Swoole 环境,无需手动编译安装,by [crazywhalecc/static-php-cli](https://github.com/crazywhalecc/static-php-cli)
|
||||
|
||||
## 从 v1 升级
|
||||
炸毛框架 v2 相对 v1 版本改动了不少内容,其中包括框架底层机制、注解事件分发、调试、命名空间等变化,详情可查看上方文档。
|
||||
## 下载源码
|
||||
|
||||
如果旧版框架使用过程中无问题且对新功能暂无需求,可以继续使用 v1 版本,后续也将维护安全类更新和修复致命 bug。
|
||||
框架源码可直接克隆本仓库进行编辑,如果你在国内,访问 GitHub 和克隆仓库比较慢,可以将 `github.com` 替换为 `fgit.zhamao.me` 进行加速。
|
||||
|
||||
例如:`git clone https://fgit.zhamao.me/zhamao-robot/zhamao-framework.git --depth 1`。
|
||||
|
||||
## 贡献和捐赠
|
||||
|
||||
如果你在使用过程中发现任何问题,可以提交 Issue 或自行 Fork 后修改并提交 Pull Request。
|
||||
|
||||
目前项目仅一人维护,耗费精力较大,所以非常欢迎对框架的贡献。
|
||||
@@ -75,17 +140,20 @@ public function index() {
|
||||
|
||||
我们会将捐赠的资金用于本项目驱动的炸毛机器人和框架文档的服务器开销上。[捐赠列表](https://github.com/zhamao-robot/thanks)
|
||||
|
||||
### 支付宝
|
||||

|
||||
如果您不想直接参与框架的开发,也可以分享你编写的模块,帮助完善框架生态。
|
||||
|
||||
如果你对我们的周边感兴趣,我们还有炸毛机器人定制 logo 的雨伞,详情咨询作者 QQ,我们会作为您捐助了本项目!
|
||||
### 支付宝
|
||||
|
||||

|
||||
|
||||
## 关于
|
||||
|
||||
框架和 SDK 是 炸毛机器人 项目的核心框架开源部分。炸毛机器人是作者写的一个高性能机器人,曾获全国计算机设计大赛一等奖。
|
||||
|
||||
作者的炸毛机器人已从2018年初起稳定运行了**三年**,并且持续迭代。
|
||||
作者的炸毛机器人已从2018年初起稳定运行了**五年**,并且持续迭代。
|
||||
|
||||
欢迎随时在 HTTP-API 插件群里提问,当然更好的话可以加作者 QQ(627577391)或提交 Issue 进行疑难解答。
|
||||
欢迎随时在 HTTP-API 插件群里提问,当然更好的话可以加作者 QQ([627577391](http://wpa.qq.com/msgrd?v=3&uin=627577391&site=qq&menu=yes))
|
||||
或提交 [Issue](https://github.com/zhamao-robot/zhamao-framework/issues/new/choose) 进行疑难解答。
|
||||
|
||||
本项目在更新内容时,请及时关注 GitHub 动态,更新前请将自己的模块代码做好备份。
|
||||
|
||||
@@ -95,4 +163,10 @@ public function index() {
|
||||
|
||||
在贡献代码时,请保管好自己的全局配置文件中的敏感信息,请勿将带有个人信息的配置文件上传 GitHub 等网站。
|
||||
|
||||

|
||||
感谢 JetBrains 为此开源项目提供 PhpStorm 开发工具支持:
|
||||
|
||||
<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/PhpStorm.svg" width="300">
|
||||
|
||||
感谢 [php-libonebot](https://github.com/botuniverse/php-libonebot) 开发者 @sunxyw 中为项目开发规范化提出的一些建议。
|
||||
|
||||
<!--  -->
|
||||
|
||||
14
SECURITY.md
14
SECURITY.md
@@ -1,14 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 2.0 | :white_check_mark: |
|
||||
| 1.6.x | :white_check_mark: |
|
||||
| 1.1.x | :x: |
|
||||
| 1.0.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you find a bug which is safety related, you should post a new issue named **Security Issue**, and I will check it as soon as possible.
|
||||
401
bin/gendoc
Executable file
401
bin/gendoc
Executable file
@@ -0,0 +1,401 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 决定是否忽略该类
|
||||
*
|
||||
* @param ReflectionClass $class 准备生成的类的反射类
|
||||
*/
|
||||
function should_ignore_class(ReflectionClass $class): bool
|
||||
{
|
||||
// 注解类
|
||||
if (($doc = $class->getDocComment()) && strpos($doc, '@Annotation') !== false) {
|
||||
return true;
|
||||
}
|
||||
if (str_ends_with($class->getName(), 'Exception')) {
|
||||
return true;
|
||||
}
|
||||
if (str_contains($class->getName(), '_')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70400) {
|
||||
echo 'PHP 版本必须为 7.4 或以上';
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function check_composer_executable(string $composer): bool
|
||||
{
|
||||
passthru($composer . ' --version 2>/dev/null', $exit_code);
|
||||
return $exit_code === 0;
|
||||
}
|
||||
|
||||
function find_valid_root(string $current_dir, int $max_loop): string
|
||||
{
|
||||
if ($max_loop <= 0) {
|
||||
return '';
|
||||
}
|
||||
if (!file_exists($current_dir . '/composer.json')) {
|
||||
return find_valid_root(dirname($current_dir), $max_loop - 1);
|
||||
}
|
||||
return $current_dir;
|
||||
}
|
||||
|
||||
$root = find_valid_root(getcwd(), 3);
|
||||
if (empty($root)) {
|
||||
echo '找不到有效的根目录';
|
||||
exit(1);
|
||||
}
|
||||
echo '根目录: ' . $root . PHP_EOL;
|
||||
|
||||
chdir($root);
|
||||
|
||||
if (!is_dir($root . '/src/ZM')) {
|
||||
echo '源码目录不存在';
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$phpdoc_package_temp_installed = false;
|
||||
if (file_exists($root . '/vendor/jasny/phpdoc-parser/composer.json')) {
|
||||
echo '正在使用现有的 PHPDoc 解析库' . PHP_EOL;
|
||||
} else {
|
||||
echo 'PHPDoc 解析库不存在,正在尝试安装...' . PHP_EOL;
|
||||
echo '本次生成完成后将会自动移除' . PHP_EOL;
|
||||
$composers = [
|
||||
'runtime/composer', 'composer', 'php composer.phar',
|
||||
];
|
||||
foreach ($composers as $composer) {
|
||||
if (check_composer_executable($composer)) {
|
||||
echo '正在使用 ' . $composer . ' 安装 PHPDoc 解析库,请稍候...' . PHP_EOL;
|
||||
passthru("{$composer} require --quiet jasny/phpdoc-parser", $exit_code);
|
||||
if ($exit_code === 0) {
|
||||
$phpdoc_package_temp_installed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$phpdoc_package_temp_installed) {
|
||||
echo '安装失败,请手动安装:composer require jasny/phpdoc-parser' . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 从这里开始是主要生成逻辑
|
||||
|
||||
require_once $root . '/vendor/autoload.php';
|
||||
|
||||
use Jasny\PhpdocParser\PhpdocParser;
|
||||
use Jasny\PhpdocParser\Set\PhpDocumentor;
|
||||
use Jasny\PhpdocParser\Tag\Summery;
|
||||
use ZM\Console\Console;
|
||||
|
||||
$opts = getopt('', ['show-warnings', 'show-debug']);
|
||||
|
||||
if (array_key_exists('show-warnings', $opts)) {
|
||||
$show_warnings = true;
|
||||
} else {
|
||||
$show_warnings = false;
|
||||
}
|
||||
|
||||
Console::init(array_key_exists('show-debug', $opts) ? 4 : 2);
|
||||
|
||||
$errors = [];
|
||||
$warnings = [];
|
||||
|
||||
// 获取源码目录的文件遍历器
|
||||
$fs = new \RecursiveDirectoryIterator($root . '/src/ZM', FilesystemIterator::SKIP_DOTS);
|
||||
|
||||
// 初始化文档解析器
|
||||
$parser = new PhpdocParser(PhpDocumentor::tags()->with([
|
||||
new Summery(),
|
||||
]));
|
||||
|
||||
$metas = [];
|
||||
$class_count = 0;
|
||||
$method_count = 0;
|
||||
|
||||
function error(string $message)
|
||||
{
|
||||
global $errors;
|
||||
$errors[] = $message;
|
||||
Console::error($message);
|
||||
}
|
||||
|
||||
function warning(string $message)
|
||||
{
|
||||
global $warnings, $show_warnings;
|
||||
$warnings[] = $message;
|
||||
if ($show_warnings) {
|
||||
Console::warning($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类的元数据
|
||||
*
|
||||
* 包括类的注释、方法的注释、参数、返回值等
|
||||
*/
|
||||
function get_class_metas(string $class_name, PhpdocParser $parser): array
|
||||
{
|
||||
// 尝试获取反射类
|
||||
try {
|
||||
$class = new \ReflectionClass($class_name);
|
||||
} catch (\ReflectionException $e) {
|
||||
error('无法获取类 ' . $class_name . ' 的反射类');
|
||||
return [];
|
||||
}
|
||||
|
||||
// 判断是否略过该类
|
||||
if (should_ignore_class($class)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$metas = [];
|
||||
|
||||
// 遍历类方法
|
||||
foreach ($class->getMethods() as $method) {
|
||||
if ($method->getDeclaringClass()->getName() !== $class_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Console::verbose('正在解析方法:' . $class_name . '::' . $method->getName());
|
||||
|
||||
// 获取方法的注释并解析
|
||||
$doc = $method->getDocComment();
|
||||
if (!$doc) {
|
||||
warning('找不到文档:' . $class_name . '::' . $method->getName());
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$meta = $parser->parse($doc);
|
||||
} catch (\Exception $e) {
|
||||
error('解析失败:' . $class_name . '::' . $method->getName() . ',' . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
// 少数情况解析后会带有 */,需要去除
|
||||
array_walk_recursive($meta, static function (&$item) {
|
||||
if (is_string($item)) {
|
||||
$item = trim(str_replace('*/', '', $item));
|
||||
}
|
||||
});
|
||||
|
||||
// 对比反射方法获取的参数和注释声明的参数
|
||||
$parameters = $method->getParameters();
|
||||
$params_in_doc = $meta['params'] ?? [];
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
$parameter_name = $parameter->getName();
|
||||
// 不存在则添加进参数列表中
|
||||
if (!isset($params_in_doc[$parameter_name])) {
|
||||
$params_in_doc[$parameter_name] = [
|
||||
'type' => $parameter->getType()?->getName(),
|
||||
'description' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
// 确保所有参数都有对应的类型和描述
|
||||
foreach ($params_in_doc as &$param) {
|
||||
if (!isset($param['type'])) {
|
||||
$param['type'] = 'mixed';
|
||||
}
|
||||
if (!isset($param['description'])) {
|
||||
$param['description'] = '';
|
||||
}
|
||||
}
|
||||
// 清除引用
|
||||
unset($param);
|
||||
$meta['params'] = $params_in_doc;
|
||||
|
||||
// 设定方法默认返回值
|
||||
if (!isset($meta['return'])) {
|
||||
$meta['return'] = [
|
||||
'type' => $method->getReturnType()?->getName() ?: 'mixed',
|
||||
'description' => '',
|
||||
];
|
||||
}
|
||||
|
||||
// 设定默认描述
|
||||
if (!isset($meta['return']['description'])) {
|
||||
$meta['return']['description'] = '';
|
||||
}
|
||||
|
||||
$metas[$method->getName()] = $meta;
|
||||
}
|
||||
|
||||
return $metas;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将方法的元数据转换为 Markdown 格式
|
||||
*
|
||||
* @param string $method 方法名
|
||||
* @param array $meta 元数据
|
||||
*/
|
||||
function convert_meta_to_markdown(string $method, array $meta): string
|
||||
{
|
||||
// 方法名作为标题
|
||||
$markdown = '## ' . $method . "\n\n";
|
||||
|
||||
// 构造方法代码块
|
||||
$markdown .= '```php' . "\n";
|
||||
// TODO: 适配 private 等修饰符
|
||||
$markdown .= 'public function ' . $method . '(';
|
||||
$params = [];
|
||||
// 添加参数
|
||||
foreach ($meta['params'] as $param_name => $param_meta) {
|
||||
$params[] = sprintf('%s $%s', $param_meta['type'] ?? 'mixed', $param_name);
|
||||
}
|
||||
$markdown .= implode(', ', $params) . ')';
|
||||
// 添加返回值
|
||||
$markdown .= ': ' . $meta['return']['type'];
|
||||
$markdown .= "\n```\n\n";
|
||||
|
||||
// 方法描述
|
||||
$markdown .= '### 描述' . "\n\n";
|
||||
$markdown .= ($meta['description'] ?? '作者很懒,什么也没有说') . "\n\n";
|
||||
|
||||
// 参数
|
||||
if (count($meta['params'])) {
|
||||
$markdown .= '### 参数' . "\n\n";
|
||||
$markdown .= '| 名称 | 类型 | 描述 |' . "\n";
|
||||
$markdown .= '| -------- | ---- | ----------- |' . "\n";
|
||||
foreach ($meta['params'] as $param_name => $param_meta) {
|
||||
$markdown .= '| ' . $param_name . ' | ' . $param_meta['type'] . ' | ' . $param_meta['description'] . ' |' . "\n";
|
||||
}
|
||||
$markdown .= "\n";
|
||||
}
|
||||
|
||||
// 返回值
|
||||
$markdown .= '### 返回' . "\n\n";
|
||||
$markdown .= '| 类型 | 描述 |' . "\n";
|
||||
$markdown .= '| ---- | ----------- |' . "\n";
|
||||
$markdown .= '| ' . $meta['return']['type'] . ' | ' . $meta['return']['description'] . ' |' . "\n";
|
||||
|
||||
return $markdown;
|
||||
}
|
||||
|
||||
function generate_sidebar_config(string $title, array $items): array
|
||||
{
|
||||
return [
|
||||
'title' => $title,
|
||||
'collapsable' => true,
|
||||
'children' => $items,
|
||||
];
|
||||
}
|
||||
|
||||
Console::info('开始生成!');
|
||||
|
||||
// 遍历类并将元数据添加至数组中
|
||||
foreach (new \RecursiveIteratorIterator($fs) as $file) {
|
||||
if (!$file->isFile()) {
|
||||
continue;
|
||||
}
|
||||
$path = $file->getPathname();
|
||||
|
||||
// 过滤不包含类的文件
|
||||
$tokens = token_get_all(file_get_contents($path));
|
||||
$found = false;
|
||||
foreach ($tokens as $k => $token) {
|
||||
if (!is_array($token)) {
|
||||
continue;
|
||||
}
|
||||
if ($token[0] === T_CLASS && $tokens[$k - 2][0] !== T_NEW) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
if ($k >= 100) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取完整类名
|
||||
$path = ltrim($path, $root . '/');
|
||||
$class = str_replace(['.php', 'src/', '/'], ['', '', '\\'], $path);
|
||||
Console::verbose('正在解析类:' . $class);
|
||||
$meta = get_class_metas($class, $parser);
|
||||
// 忽略不包含任何方法的类
|
||||
if (empty($meta)) {
|
||||
continue;
|
||||
}
|
||||
$metas[$class] = $meta;
|
||||
++$class_count;
|
||||
$method_count += count($meta);
|
||||
}
|
||||
|
||||
// 将元数据转换为 Markdown
|
||||
$markdown = [];
|
||||
foreach ($metas as $class => $class_metas) {
|
||||
$markdown[$class] = [];
|
||||
// 将类名作为页面大标题
|
||||
$markdown[$class]['class'] = '# ' . $class;
|
||||
foreach ($class_metas as $method => $meta) {
|
||||
$markdown[$class][$method] = convert_meta_to_markdown($method, $meta);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成文档
|
||||
$docs = $root . '/docs/api/';
|
||||
foreach ($markdown as $class => $methods) {
|
||||
$file = $docs . str_replace('\\', '/', $class) . '.md';
|
||||
// 确保目录存在
|
||||
if (!file_exists(dirname($file)) && !mkdir($concurrent_directory = dirname($file), 0777, true) && !is_dir($concurrent_directory)) {
|
||||
throw new \RuntimeException(sprintf('无法建立目录 %s', $concurrent_directory));
|
||||
}
|
||||
Console::verbose('正在生成文档:' . $file);
|
||||
$text = implode("\n\n", $methods);
|
||||
file_put_contents($file, $text);
|
||||
}
|
||||
|
||||
// 生成文档目录
|
||||
$children = array_keys($markdown);
|
||||
$children = str_replace('\\', '/', $children);
|
||||
$class_tree = [];
|
||||
foreach ($children as $child) {
|
||||
$parent = dirname($child);
|
||||
$class_tree[$parent][] = $child;
|
||||
}
|
||||
ksort($class_tree);
|
||||
$config = 'module.exports = [';
|
||||
foreach ($class_tree as $parent => $children) {
|
||||
$encode = json_encode(generate_sidebar_config($parent, $children));
|
||||
$encode = str_replace('\/', '/', $encode);
|
||||
$config .= $encode . ',';
|
||||
}
|
||||
$config = rtrim($config, ',');
|
||||
$config .= ']';
|
||||
|
||||
$file = $root . '/docs/.vuepress/api.js';
|
||||
file_put_contents($file, $config);
|
||||
|
||||
if (count($warnings)) {
|
||||
Console::warning('生成过程中发现 ' . count($warnings) . ' 次警告');
|
||||
if (!$show_warnings) {
|
||||
Console::info('生成器默认忽略了警告,你可以通过 gendoc --show-warnings 来查看警告');
|
||||
}
|
||||
}
|
||||
if (count($errors)) {
|
||||
Console::error('生成过程中发现错误:');
|
||||
foreach ($errors as $error) {
|
||||
Console::error($error);
|
||||
}
|
||||
}
|
||||
|
||||
Console::success('API 文档生成完毕');
|
||||
Console::success(sprintf('共生成 %d 个类,共 %d 个方法', $class_count, $method_count));
|
||||
|
||||
// 完成生成,进行善后
|
||||
|
||||
if ($phpdoc_package_temp_installed) {
|
||||
echo '正在移除 PHPDoc 解析库,请稍候...' . PHP_EOL;
|
||||
passthru('composer remove --quiet jasny/phpdoc-parser', $exit_code);
|
||||
if ($exit_code !== 0) {
|
||||
echo '移除失败,请手动移除:composer remove jasny/phpdoc-parser' . PHP_EOL;
|
||||
}
|
||||
echo '移除完成';
|
||||
}
|
||||
exit(0);
|
||||
@@ -1,65 +1,111 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Copyright: Swlib
|
||||
* Author: Twosee <twose@qq.com>
|
||||
* Date: 2018/4/14 下午10:58
|
||||
*/
|
||||
/** For Swoole coroutine tests */
|
||||
|
||||
Co::set([
|
||||
'log_level' => SWOOLE_LOG_INFO,
|
||||
'trace_flags' => 0
|
||||
// 如果改成 true,则会在终端显示所有炸毛框架的 Log
|
||||
const ZM_TEST_LOG_DEBUG = false;
|
||||
|
||||
use PHPUnit\Runner\Version;
|
||||
use PHPUnit\TextUI\TestRunner;
|
||||
use Swoole\Coroutine;
|
||||
use ZM\Annotation\Swoole\OnStart;
|
||||
use ZM\Command\RunServerCommand;
|
||||
use ZM\Console\Console;
|
||||
use ZM\ConsoleApplication;
|
||||
use ZM\Event\EventManager;
|
||||
use ZM\Framework;
|
||||
use ZM\Store\ZMAtomic;
|
||||
use ZM\Utils\ZMUtil;
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
|
||||
Coroutine::set([
|
||||
'log_level' => SWOOLE_LOG_INFO,
|
||||
'trace_flags' => 0,
|
||||
]);
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
ini_set('date.timezone', 'UTC');
|
||||
}
|
||||
/*
|
||||
* This file is part of PHPUnit.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
foreach ([
|
||||
__DIR__ . '/../../../autoload.php',
|
||||
__DIR__ . '/../../autoload.php',
|
||||
__DIR__ . '/../vendor/autoload.php',
|
||||
__DIR__ . '/vendor/autoload.php'
|
||||
] as $file
|
||||
) {
|
||||
if (file_exists($file)) {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', $file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
|
||||
if (PHP_VERSION_ID <= 70100) {
|
||||
fwrite(
|
||||
STDERR,
|
||||
'You need to set up the project dependencies using Composer:' . PHP_EOL . PHP_EOL .
|
||||
' composer install' . PHP_EOL . PHP_EOL .
|
||||
'You can learn all about Composer on https://getcomposer.org/.' . PHP_EOL
|
||||
sprintf(
|
||||
'This version of PHPUnit is supported on PHP 7.1 and above.' . PHP_EOL .
|
||||
'You are using PHP %s (%s).' . PHP_EOL,
|
||||
PHP_VERSION,
|
||||
PHP_BINARY
|
||||
)
|
||||
);
|
||||
|
||||
die(1);
|
||||
} else {
|
||||
if (array_reverse(explode('/', __DIR__))[0] ?? '' === 'test') {
|
||||
$vendor_dir = dirname(PHPUNIT_COMPOSER_INSTALL);
|
||||
$bin_unit = "{$vendor_dir}/bin/phpunit";
|
||||
$unit_uint = "{$vendor_dir}/phpunit/phpunit/phpunit";
|
||||
if (file_exists($bin_unit)) {
|
||||
@unlink($bin_unit);
|
||||
@symlink(__FILE__, $bin_unit);
|
||||
}
|
||||
if (file_exists($unit_uint)) {
|
||||
@unlink($unit_uint);
|
||||
@symlink(__FILE__, $unit_uint);
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
require PHPUNIT_COMPOSER_INSTALL;
|
||||
$starttime = microtime(true);
|
||||
go(function (){
|
||||
try{
|
||||
PHPUnit\TextUI\Command::main(false);
|
||||
} catch(Exception $e) {
|
||||
echo $e->getMessage().PHP_EOL;
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
ini_set('date.timezone', 'Asia/Shanghai');
|
||||
}
|
||||
|
||||
require $root . '/vendor/autoload.php';
|
||||
|
||||
const ZM_VERSION_ID = ConsoleApplication::VERSION_ID;
|
||||
const ZM_VERSION = ConsoleApplication::VERSION;
|
||||
|
||||
// 模拟define
|
||||
const ZM_PROCESS_MASTER = 1;
|
||||
const ZM_PROCESS_MANAGER = 2;
|
||||
const ZM_PROCESS_WORKER = 4;
|
||||
const ZM_PROCESS_USER = 8;
|
||||
const ZM_PROCESS_TASKWORKER = 16;
|
||||
|
||||
define('FRAMEWORK_ROOT_DIR', $root);
|
||||
define('WORKING_DIR', $root);
|
||||
const SOURCE_ROOT_DIR = WORKING_DIR;
|
||||
define('LOAD_MODE', is_dir(SOURCE_ROOT_DIR . '/src/ZM') ? 0 : 1);
|
||||
chdir(__DIR__ . '/../');
|
||||
|
||||
$options = array_map(function ($x) {
|
||||
return $x->getDefault();
|
||||
}, RunServerCommand::exportDefinition()->getOptions());
|
||||
$options['disable-safe-exit'] = true;
|
||||
$options['worker-num'] = 1;
|
||||
$options['private-mode'] = true;
|
||||
$options['log-error'] = true;
|
||||
|
||||
spl_autoload_register(static function ($class) {
|
||||
$map = [
|
||||
TestRunner::class => 'vendor/phpunit/phpunit/src/TextUI/TestRunner.php',
|
||||
Version::class => 'vendor/phpunit/phpunit/src/Runner/Version.php',
|
||||
];
|
||||
if (isset($map[$class])) {
|
||||
$source = file_get_contents(SOURCE_ROOT_DIR . '/' . $map[$class]);
|
||||
$source = str_replace(['#StandWith', 'Ukraine', 'declare(strict_types=1);'], '', $source);
|
||||
eval('?>' . $source);
|
||||
}
|
||||
});
|
||||
}, true, true);
|
||||
|
||||
Console::setLevel(0);
|
||||
$framework = new Framework($options);
|
||||
$start = new OnStart();
|
||||
$start->method = function () {
|
||||
try {
|
||||
Console::setLevel(ZM_TEST_LOG_DEBUG ? 4 : 0);
|
||||
$retcode = PHPUnit\TextUI\Command::main(false);
|
||||
} finally {
|
||||
Console::setLevel(0);
|
||||
ZMUtil::stop(($retcode ?? 1) !== 0);
|
||||
}
|
||||
};
|
||||
EventManager::addEvent(OnStart::class, $start);
|
||||
|
||||
$framework->start();
|
||||
|
||||
Swoole\Event::wait();
|
||||
echo "Took ".round(microtime(true) - $starttime, 4). "s\n";
|
||||
if (ZMAtomic::get('stop_signal')->get() === 2) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
44
bin/start
44
bin/start
@@ -1,14 +1,34 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
#!/bin/sh
|
||||
|
||||
if (!is_dir(__DIR__ . '/../vendor')) {
|
||||
define("LOAD_MODE", 1); //composer项目模式
|
||||
define("LOAD_MODE_COMPOSER_PATH", getcwd());
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require_once LOAD_MODE_COMPOSER_PATH . "/vendor/autoload.php";
|
||||
} else {
|
||||
define("LOAD_MODE", 0); //源码模式
|
||||
require_once __DIR__ . "/../vendor/autoload.php";
|
||||
}
|
||||
# shellcheck disable=SC2068
|
||||
# shellcheck disable=SC2181
|
||||
# author: crazywhalecc
|
||||
# since: 2.5.0
|
||||
|
||||
(new ZM\ConsoleApplication("zhamao-framework"))->initEnv()->run();
|
||||
if [ -f "$(pwd)/runtime/php" ]; then
|
||||
executable="$(pwd)/runtime/php"
|
||||
echo "* Framework started with built-in php."
|
||||
else
|
||||
which php >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
executable=$(which php)
|
||||
else
|
||||
echo '[ErrCode:E00014] Cannot find any PHP runtime, please use command "./install-runtime.sh" or install PHP manually!'
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
result=$(echo "$1" | grep -E "module|build")
|
||||
|
||||
if [ "$result" != "" ]; then
|
||||
executable="$executable -d phar.readonly=off"
|
||||
fi
|
||||
|
||||
if [ -f "$(pwd)/src/entry.php" ]; then
|
||||
$executable "$(pwd)/src/entry.php" $@
|
||||
elif [ -f "$(pwd)/vendor/zhamao/framework/src/entry.php" ]; then
|
||||
$executable "$(pwd)/vendor/zhamao/framework/src/entry.php" $@
|
||||
else
|
||||
echo "[ErrCode:E00015] Cannot find zhamao-framework entry file!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
31
bin/systemd
31
bin/systemd
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php /** @since 1.2 */
|
||||
switch ($argv[1] ?? '') {
|
||||
case '--generate':
|
||||
case '':
|
||||
generate($argv);
|
||||
break;
|
||||
case '--help':
|
||||
case '-h':
|
||||
default:
|
||||
echo "\nUsage: " . $argv[0] . " [OPTION]\n";
|
||||
echo "\nzhamao-framework systemd generator.";
|
||||
echo "\n\n -h, --help\t\tShow this help menu";
|
||||
echo "\n --generate\tGenerate a systemd service file\n\n";
|
||||
break;
|
||||
}
|
||||
|
||||
function generate($argv) {
|
||||
$s = "[Unit]\nDescription=zhamao-framework Daemon\nAfter=rc-local.service\n\n[Service]\nType=simple";
|
||||
$s .= "\nUser=" . exec("whoami");
|
||||
$s .= "\nGroup=" . exec("groups | awk '{print $1}'");
|
||||
$s .= "\nWorkingDirectory=" . getcwd();
|
||||
if ($argv[0] == "systemd" && !file_exists(getcwd() . '/systemd'))
|
||||
$s .= "\nExecStart=" . getcwd() . "/vendor/bin/start server --disable-console-input";
|
||||
else
|
||||
$s .= "\nExecStart=" . getcwd() . "/bin/start server --disable-console-input";
|
||||
$s .= "\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\n";
|
||||
@mkdir(getcwd() . "/resources/");
|
||||
file_put_contents(getcwd() . "/resources/zhamao.service", $s);
|
||||
echo "File successfully generated. Path: " . getcwd() . "/resources/zhamao.service\n";
|
||||
}
|
||||
118
bin/watcher
Executable file
118
bin/watcher
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
_red="\e[33m"
|
||||
_green="\e[32m"
|
||||
_reset="\e[0m"
|
||||
|
||||
unix_s=$(uname -s)
|
||||
|
||||
unix_release=$(
|
||||
marked_release=""
|
||||
if [ "$unix_s" = "Linux" ]; then
|
||||
echo $HOME | grep com.termux >/dev/null
|
||||
if [ $? == 0 ]; then
|
||||
marked_release="termux"
|
||||
elif [ -f "/etc/redhat-release" ]; then
|
||||
if [ "$(cat /etc/redhat-release | awk '{print $1}' | grep -v '^$')" = "CentOS" ]; then
|
||||
marked_release="CentOS"
|
||||
else
|
||||
marked_release="unknown"
|
||||
fi
|
||||
elif [ -f "/etc/os-release" ]; then
|
||||
cat /etc/os-release | grep Alpine > /dev/null
|
||||
if [ $? == 0 ]; then
|
||||
marked_release="Alpine"
|
||||
fi
|
||||
fi
|
||||
if [ "$marked_release" = "" ]; then
|
||||
if [ -f "/etc/issue" ]; then
|
||||
marked_release=$(cat /etc/issue | grep -v '^$' | awk '{print $1}')
|
||||
else
|
||||
marked_release="unknown"
|
||||
fi
|
||||
fi
|
||||
elif [ "$unix_s" = "Darwin" ]; then
|
||||
marked_release=$(sw_vers | grep ProductName | awk '{print $2" "$3" "$4}')
|
||||
fi
|
||||
echo $marked_release
|
||||
)
|
||||
unix_release=$(echo $unix_release | xargs)
|
||||
|
||||
function echo_error() {
|
||||
echo -e "${_red}$1${_reset}"
|
||||
}
|
||||
|
||||
function echo_info() {
|
||||
echo -e "${_green}$1${_reset}"
|
||||
}
|
||||
|
||||
function install_test() {
|
||||
which fswatch >/dev/null
|
||||
if [ $? != 0 ]; then
|
||||
operate_confirm "fswatch还没有安装,是否确认安装?" && install_fswatch
|
||||
fi
|
||||
}
|
||||
function install_fswatch() {
|
||||
if [ "$unix_s" = "Linux" ]; then
|
||||
case $unix_release in
|
||||
"Kali" | "Ubuntu" | "Debian" | "Raspbian" | 'Pop!_OS')
|
||||
sudo apt-get install fswatch -y ;;
|
||||
#"termux") pkg install $1 -y ;;
|
||||
"CentOS")
|
||||
curl -o fswatch.tgz https://download.fastgit.org/emcrisostomo/fswatch/releases/download/1.16.0/fswatch-1.16.0.tar.gz && \
|
||||
tar -xzf fswatch.tgz && \
|
||||
cd fswatch-1.16.0 && \
|
||||
./configure && \
|
||||
make && \
|
||||
sudo make install && \
|
||||
cd .. && \
|
||||
rm -rf fswatch.tgz fswatch-1.16.0
|
||||
;;
|
||||
#"Alpine") apk add $1 ;;
|
||||
*)
|
||||
echo_error "不支持的 Linux 发行版:$unix_release"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
elif [ "$unix_s" = "Darwin" ]; then
|
||||
brew install fswatch
|
||||
else
|
||||
echo_error "不支持的操作系统:$unix_s"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
function operate_confirm() {
|
||||
echo -n $(echo_info "$1 [Y/n] ")
|
||||
read operate
|
||||
operate=$(echo $operate | tr A-Z a-z)
|
||||
if [[ "$operate" = "y" || "$operate" = "" ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo_info "当前系统:$unix_release"
|
||||
install_test
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
else
|
||||
echo_info "程序路径:$(which fswatch)"
|
||||
fi
|
||||
watch_dir="./src"
|
||||
if [ ! -d "$watch_dir" ]; then
|
||||
echo_error "src目录不存在!"
|
||||
exit 1
|
||||
else
|
||||
echo_info "监听目录:$watch_dir"
|
||||
fi
|
||||
_pid=$(cat .daemon_pid | awk -F"\"pid\": " '{print $2}' | grep -v ^$ | sed 's/,//g')
|
||||
if [ "$_pid" = "" ]; then
|
||||
echo_error "未检测到框架进程"
|
||||
exit 1
|
||||
fi
|
||||
fswatch $watch_dir | while read file
|
||||
do
|
||||
echo "Detect file change: $file"
|
||||
kill -USR1 $_pid
|
||||
done
|
||||
116
composer.json
116
composer.json
@@ -1,49 +1,55 @@
|
||||
{
|
||||
"name": "zhamao/framework",
|
||||
"description": "High performance QQ robot and web server development framework",
|
||||
"minimum-stability": "stable",
|
||||
"description": "High performance chat robot and web server development framework",
|
||||
"license": "Apache-2.0",
|
||||
"version": "2.2.5",
|
||||
"extra": {
|
||||
"exclude_annotate": [
|
||||
"src/ZM"
|
||||
]
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "whale",
|
||||
"email": "crazysnowcc@gmail.com"
|
||||
"name": "jerry",
|
||||
"email": "admin@zhamao.me"
|
||||
},
|
||||
{
|
||||
"name": "swift",
|
||||
"email": "hugo_swift@yahoo.com"
|
||||
"name": "sunxyw",
|
||||
"email": "dev@sunxyw.xyz"
|
||||
}
|
||||
],
|
||||
"prefer-stable": true,
|
||||
"bin": [
|
||||
"bin/start",
|
||||
"bin/phpunit-swoole"
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"doctrine/annotations": "~1.10",
|
||||
"php": "^7.2 || ^7.3 || ^7.4 || ^8.0 || ^8.1",
|
||||
"ext-json": "*",
|
||||
"psy/psysh": "@stable",
|
||||
"symfony/polyfill-ctype": "^1.20",
|
||||
"symfony/polyfill-mbstring": "^1.20",
|
||||
"symfony/console": "^5.1",
|
||||
"zhamao/connection-manager": "*@dev",
|
||||
"zhamao/console": "^1.0",
|
||||
"ext-posix": "*",
|
||||
"doctrine/dbal": "^2.13.1",
|
||||
"dragonmantank/cron-expression": "^3.3",
|
||||
"jelix/version": "^2.0",
|
||||
"koriym/attributes": "^1.0",
|
||||
"psr/container": "^2.0",
|
||||
"psy/psysh": "^0.11.2",
|
||||
"symfony/console": "~6.0 || ~5.0 || ~4.0 || ~3.0",
|
||||
"symfony/polyfill-ctype": "^1.19",
|
||||
"symfony/polyfill-mbstring": "^1.19",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/routing": "~6.0 || ~5.0 || ~4.0 || ~3.0",
|
||||
"zhamao/config": "^1.0",
|
||||
"zhamao/request": "*@dev",
|
||||
"symfony/routing": "^5.1",
|
||||
"symfony/polyfill-php80": "^1.20",
|
||||
"ext-posix": "*"
|
||||
"zhamao/connection-manager": "^1.0",
|
||||
"zhamao/console": "^1.0",
|
||||
"zhamao/request": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"brainmaestro/composer-git-hooks": "^2.8",
|
||||
"friendsofphp/php-cs-fixer": "^3.2 != 3.7.0",
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"phpstan/phpstan": "^1.1",
|
||||
"phpunit/phpunit": "^8.5 || ^9.0",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"swoole/ide-helper": "^4.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*"
|
||||
"ext-ctype": "Use C/C++ extension instead of polyfill will be more efficient",
|
||||
"ext-mbstring": "Use C/C++ extension instead of polyfill will be more efficient",
|
||||
"ext-pdo_mysql": "If you use mysql in framework, you will need this extension",
|
||||
"ext-redis": "If you use Redis in framework, you will need this extension",
|
||||
"league/climate": "Display columns and status in terminal"
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ZM\\": "src/ZM"
|
||||
@@ -52,8 +58,50 @@
|
||||
"src/ZM/global_functions.php"
|
||||
]
|
||||
},
|
||||
"require-dev": {
|
||||
"swoole/ide-helper": "@dev",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Module\\": "src/Module",
|
||||
"Custom\\": "src/Custom",
|
||||
"Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"bin": [
|
||||
"bin/gendoc",
|
||||
"bin/phpunit-swoole",
|
||||
"bin/start"
|
||||
],
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"phpstan/extension-installer": true
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"post-merge": "composer install",
|
||||
"pre-commit": [
|
||||
"echo committing as $(git config user.name)",
|
||||
"composer cs-fix -- --diff"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer cs-fix -- --dry-run --diff",
|
||||
"composer analyse"
|
||||
]
|
||||
},
|
||||
"zm": {
|
||||
"exclude-annotation-path": [
|
||||
"src/ZM",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": [
|
||||
"[ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/cghooks add"
|
||||
],
|
||||
"analyse": "phpstan analyse --memory-limit 300M",
|
||||
"cs-fix": "php-cs-fixer fix",
|
||||
"test": "bin/phpunit-swoole --no-coverage"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,123 +1,154 @@
|
||||
<?php
|
||||
/** @noinspection PhpFullyQualifiedNameUsageInspection */
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
global $config;
|
||||
|
||||
/** bind host */
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/* bind host */
|
||||
$config['host'] = '0.0.0.0';
|
||||
|
||||
/** bind port */
|
||||
/* bind port */
|
||||
$config['port'] = 20001;
|
||||
|
||||
/** 框架开到公网或外部的HTTP访问链接,通过 DataProvider::getFrameworkLink() 获取 */
|
||||
$config['http_reverse_link'] = "http://127.0.0.1:" . $config['port'];
|
||||
/* 框架开到公网或外部的HTTP访问链接,通过 DataProvider::getFrameworkLink() 获取 */
|
||||
$config['http_reverse_link'] = 'http://127.0.0.1:' . $config['port'];
|
||||
|
||||
/** 框架是否启动debug模式 */
|
||||
/* 框架是否启动debug模式,当debug模式为true时,启用热更新(需要安装inotify扩展) */
|
||||
$config['debug_mode'] = false;
|
||||
|
||||
/** 存放框架内文件数据的目录 */
|
||||
$config['zm_data'] = realpath(__DIR__ . "/../") . '/zm_data/';
|
||||
/* 存放框架内文件数据的目录 */
|
||||
$config['zm_data'] = realpath(WORKING_DIR) . '/zm_data/';
|
||||
|
||||
/** 存放各个模块配置文件的目录 */
|
||||
/* 存放各个模块配置文件的目录 */
|
||||
$config['config_dir'] = $config['zm_data'] . 'config/';
|
||||
|
||||
/** 存放崩溃和运行日志的目录 */
|
||||
/* 存放崩溃和运行日志的目录 */
|
||||
$config['crash_dir'] = $config['zm_data'] . 'crash/';
|
||||
|
||||
/** 对应swoole的server->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
|
||||
// 'worker_num' => swoole_cpu_num(), //如果你只有一个 OneBot 实例连接到框架并且代码没有复杂的CPU密集计算,则可把这里改为1使用全局变量
|
||||
'dispatch_mode' => 2, // 包分配原则,见 https://wiki.swoole.com/#/server/setting?id=dispatch_mode
|
||||
'max_coroutine' => 300000,
|
||||
//'task_worker_num' => 4,
|
||||
//'task_enable_coroutine' => true
|
||||
'max_wait_time' => 5,
|
||||
// 'task_worker_num' => 4,
|
||||
// 'task_enable_coroutine' => true
|
||||
];
|
||||
|
||||
/** 轻量字符串缓存,默认开启 */
|
||||
$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
|
||||
];
|
||||
|
||||
/** 大容量跨进程变量存储(2.2.0可用) */
|
||||
$config["worker_cache"] = [
|
||||
"worker" => 0,
|
||||
"transaction_timeout" => 30000
|
||||
];
|
||||
|
||||
/** MySQL数据库连接信息,host留空则启动时不创建sql连接池 */
|
||||
$config['sql_config'] = [
|
||||
'sql_host' => '',
|
||||
'sql_port' => 3306,
|
||||
'sql_username' => 'name',
|
||||
'sql_database' => 'db_name',
|
||||
'sql_password' => '',
|
||||
'sql_options' => [
|
||||
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
PDO::ATTR_EMULATE_PREPARES => false
|
||||
/* 一些框架与框架运行时设置的调整 */
|
||||
$config['runtime'] = [
|
||||
'swoole_coroutine_hook_flags' => SWOOLE_HOOK_ALL & (~SWOOLE_HOOK_CURL),
|
||||
'swoole_server_mode' => SWOOLE_PROCESS,
|
||||
'middleware_error_policy' => 1,
|
||||
'reload_delay_time' => 800,
|
||||
'global_middleware_binding' => [],
|
||||
'save_console_log_file' => false, // 改为目标路径,则将 Console 输出的日志保存到文件
|
||||
'annotation_reader_ignore' => [ // 设置注解解析器忽略的注解名或命名空间,防止解析到不该解析的
|
||||
'name' => [
|
||||
'mixin',
|
||||
],
|
||||
'namespace' => [],
|
||||
],
|
||||
'sql_no_exception' => false,
|
||||
'sql_default_fetch_mode' => PDO::FETCH_ASSOC // added in 1.5.6
|
||||
'inside_table_size' => 65536 // 内部表字符串最大长度(需要2的倍数)
|
||||
// 正常不要低于65536,如果群数量过多可能出现会size不够。若swoole日志出现WARNING TableRow::set_value(): [key=wait_api,field=value]string value is too long可以将该值往大设置。
|
||||
];
|
||||
|
||||
/** Redis连接信息,host留空则启动时不创建Redis连接池 */
|
||||
/* 轻量字符串缓存,默认开启 */
|
||||
$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,
|
||||
];
|
||||
|
||||
/* 大容量跨进程变量存储(2.2.0可用) */
|
||||
$config['worker_cache'] = [
|
||||
'worker' => 0,
|
||||
'transaction_timeout' => 30000,
|
||||
];
|
||||
|
||||
/* MySQL数据库连接信息,host留空则启动时不创建sql连接池 */
|
||||
$config['mysql_config'] = [
|
||||
'host' => '',
|
||||
'port' => 3306,
|
||||
'unix_socket' => null,
|
||||
'username' => 'root',
|
||||
'password' => '123456',
|
||||
'dbname' => '',
|
||||
'charset' => 'utf8mb4',
|
||||
'pool_size' => 64,
|
||||
'options' => [
|
||||
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
],
|
||||
];
|
||||
|
||||
/* Redis连接信息,host留空则启动时不创建Redis连接池 */
|
||||
$config['redis_config'] = [
|
||||
'host' => '',
|
||||
'port' => 6379,
|
||||
'timeout' => 1,
|
||||
'db_index' => 0,
|
||||
'auth' => ''
|
||||
'auth' => '',
|
||||
];
|
||||
|
||||
/** onebot连接约定的token */
|
||||
$config["access_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
|
||||
// 'custom_atomic_name' => 0, //自定义添加的Atomic
|
||||
];
|
||||
|
||||
/** 终端日志显示等级(0-4) */
|
||||
$config["info_level"] = 2;
|
||||
/* 终端日志显示等级(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_root' => realpath(__DIR__ . '/../') . '/resources/html',
|
||||
'document_index' => [
|
||||
'index.html'
|
||||
]
|
||||
'index.html',
|
||||
],
|
||||
];
|
||||
|
||||
/** 注册 Swoole Server 事件注解的类列表 */
|
||||
$config['server_event_handler_class'] = [
|
||||
\ZM\Event\ServerEventHandler::class,
|
||||
/* 机器人解析模块,关闭后无法使用如CQCommand等注解(上面的modules即将废弃) */
|
||||
$config['onebot'] = [
|
||||
'status' => true,
|
||||
'single_bot_mode' => false,
|
||||
'message_level' => 99,
|
||||
'message_convert_string' => true,
|
||||
'message_command_policy' => 'interrupt',
|
||||
];
|
||||
|
||||
/** 服务器启用的外部第三方和内部插件 */
|
||||
$config['modules'] = [
|
||||
'onebot' => [
|
||||
'status' => true,
|
||||
'single_bot_mode' => false
|
||||
], // QQ机器人事件解析器,如果取消此项则默认为 true 开启状态,否则你手动填写 false 才会关闭
|
||||
/* 一个远程简易终端,使用nc直接连接即可,但是不建议开放host为0.0.0.0(远程连接) */
|
||||
$config['remote_terminal'] = [
|
||||
'status' => false,
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 20002,
|
||||
'token' => '',
|
||||
];
|
||||
|
||||
/* 模块(插件)加载器的相关设置 */
|
||||
$config['module_loader'] = [
|
||||
'enable_hotload' => false,
|
||||
'load_path' => $config['zm_data'] . 'modules',
|
||||
];
|
||||
|
||||
return $config;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
______
|
||||
|__ / |__ __ _ _ __ ___ __ _ ___
|
||||
/ /| '_ \ / _` | '_ ` _ \ / _` |/ _ \
|
||||
/ /_| | | | (_| | | | | | | (_| | (_) |
|
||||
/____|_| |_|\__,_|_| |_| |_|\__,_|\___/
|
||||
______
|
||||
|__ / |__ __ _ _ __ ___ __ _ ___
|
||||
/ /| '_ \ / _` | '_ ` _ \ / _` |/ _ \
|
||||
/ /_| | | | (_| | | | | | | (_| | (_) |
|
||||
/____|_| |_|\__,_|_| |_| |_|\__,_|\___/
|
||||
|
||||
|
||||
1
docs/.vuepress/api.js
Normal file
1
docs/.vuepress/api.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = [{"title":"ZM","collapsable":true,"children":["ZM/ZMServer"]},{"title":"ZM/API","collapsable":true,"children":["ZM/API/CQ","ZM/API/ZMRobot","ZM/API/TuringAPI","ZM/API/GoCqhttpAPIV11","ZM/API/OneBotV11"]},{"title":"ZM/API/Proxies/Bot","collapsable":true,"children":["ZM/API/Proxies/Bot/AllGroupsProxy","ZM/API/Proxies/Bot/AbstractBotProxy","ZM/API/Proxies/Bot/AllBotsProxy"]},{"title":"ZM/Annotation/Swoole","collapsable":true,"children":["ZM/Annotation/Swoole/OnSwooleEventBase"]},{"title":"ZM/Command","collapsable":true,"children":["ZM/Command/CheckConfigCommand"]},{"title":"ZM/Command/Module","collapsable":true,"children":["ZM/Command/Module/ModulePackCommand","ZM/Command/Module/ModuleListCommand"]},{"title":"ZM/Container","collapsable":true,"children":["ZM/Container/BoundMethod","ZM/Container/WorkerContainer","ZM/Container/Container"]},{"title":"ZM/DB","collapsable":true,"children":["ZM/DB/UpdateBody","ZM/DB/DB","ZM/DB/InsertBody","ZM/DB/DeleteBody","ZM/DB/Table","ZM/DB/SelectBody"]},{"title":"ZM/Event","collapsable":true,"children":["ZM/Event/EventDispatcher","ZM/Event/EventTracer","ZM/Event/EventManager"]},{"title":"ZM/Event/SwooleEvent","collapsable":true,"children":["ZM/Event/SwooleEvent/OnMessage","ZM/Event/SwooleEvent/OnTask"]},{"title":"ZM/Http","collapsable":true,"children":["ZM/Http/Response"]},{"title":"ZM/Module","collapsable":true,"children":["ZM/Module/ModuleUnpacker","ZM/Module/ModuleBase","ZM/Module/ModulePacker"]},{"title":"ZM/MySQL","collapsable":true,"children":["ZM/MySQL/MySQLPool","ZM/MySQL/MySQLWrapper","ZM/MySQL/MySQLStatementWrapper","ZM/MySQL/MySQLQueryBuilder","ZM/MySQL/MySQLConnection","ZM/MySQL/MySQLStatement"]},{"title":"ZM/Store","collapsable":true,"children":["ZM/Store/LightCacheInside","ZM/Store/ZMAtomic","ZM/Store/LightCache"]},{"title":"ZM/Store/Redis","collapsable":true,"children":["ZM/Store/Redis/ZMRedis"]},{"title":"ZM/Utils","collapsable":true,"children":["ZM/Utils/CommandInfoUtil","ZM/Utils/Terminal","ZM/Utils/DataProvider","ZM/Utils/SignalListener","ZM/Utils/CoMessage","ZM/Utils/ReflectionUtil","ZM/Utils/MessageUtil","ZM/Utils/ZMUtil","ZM/Utils/HttpUtil"]},{"title":"ZM/Utils/Manager","collapsable":true,"children":["ZM/Utils/Manager/ModuleManager","ZM/Utils/Manager/WorkerManager","ZM/Utils/Manager/CronManager"]}]
|
||||
141
docs/.vuepress/components/ChatBox.vue
Normal file
141
docs/.vuepress/components/ChatBox.vue
Normal file
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div class="doc-chat-container">
|
||||
<div class="doc-chat-content">
|
||||
<div v-for="i in chat" v-bind="i">
|
||||
<div class="doc-chat-row" v-if="i.type === 0">
|
||||
<div class="doc-chat-box">{{ i.content }}</div>
|
||||
<img class="doc-chat-avatar" src="https://api.btstu.cn/sjtx/api.php" alt=""/>
|
||||
</div>
|
||||
<div class="doc-chat-row doc-chat-row-robot" v-else-if="i.type === 1">
|
||||
<img class="doc-chat-avatar" src="https://docs-v1.zhamao.xin/logo.png" alt=""/>
|
||||
<div class="doc-chat-box doc-chat-box-robot">
|
||||
<span v-for="(p,index) in i.content.split('\n')">{{p}}<br v-if="index !== i.content.length - 1"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="doc-chat-row doc-chat-banner" v-else-if="i.type === 2">
|
||||
{{ i.content }}
|
||||
</div>
|
||||
<div class="doc-chat-row doc-chat-row-robot" v-else-if="i.type === 3">
|
||||
<img class="doc-chat-avatar" src="https://docs-v1.zhamao.xin/logo.png" alt=""/>
|
||||
<div class="doc-chat-box doc-chat-box-robot">
|
||||
<img :src="i.content" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!--
|
||||
type:
|
||||
0: 我方发送消息
|
||||
1: 机器人回复消息
|
||||
2: 显示一个横幅系统消息
|
||||
3: 机器人回复一个图片
|
||||
-->
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ChatBox",
|
||||
props: ['myChats'],
|
||||
data() {
|
||||
return {
|
||||
chat: this.myChats,
|
||||
multiline: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.doc-chat-content {
|
||||
padding: 12px;
|
||||
}
|
||||
.doc-chat-container {
|
||||
border-radius: 6px;
|
||||
max-width: 550px;
|
||||
min-height: 30px;
|
||||
/*noinspection CssUnresolvedCustomProperty*/
|
||||
background-color: #f2f4f5;
|
||||
|
||||
margin-bottom: 1em;
|
||||
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
}
|
||||
|
||||
.doc-chat-row {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1 1 auto;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.doc-chat-banner {
|
||||
justify-content: center;
|
||||
background: rgba(0,0,0,0.1);
|
||||
width: max-content;
|
||||
margin: 8px auto;
|
||||
padding: 4px 14px;
|
||||
border-radius: 8px;
|
||||
color: gray;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.doc-chat-row-robot {
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
|
||||
.doc-chat-box {
|
||||
color: #000000de;
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
max-width: 55%;
|
||||
border-radius: .5rem;
|
||||
padding: .4rem .6rem;
|
||||
margin: .4rem .8rem;
|
||||
background-color: #fff;
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
outline: none;
|
||||
overflow-wrap: break-word;
|
||||
white-space: normal;
|
||||
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
.doc-chat-box:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: auto;
|
||||
top: 0;
|
||||
width: 8px;
|
||||
height: 12px;
|
||||
color: #fff;
|
||||
border: 0 solid transparent;
|
||||
border-bottom: 7px solid;
|
||||
border-radius: 0 0 8px 0;
|
||||
left: calc(100% - 4px);
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
.doc-chat-box-robot:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: calc(100% - 4px);
|
||||
top: 0;
|
||||
width: 8px;
|
||||
height: 12px;
|
||||
color: #fff;
|
||||
border: 0 solid transparent;
|
||||
border-bottom: 7px solid;
|
||||
border-radius: 0 0 0 8px;
|
||||
left: auto;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
.doc-chat-avatar {
|
||||
background-color: aquamarine;
|
||||
width: 36px !important;
|
||||
height: 36px !important;
|
||||
border-radius: 18px;
|
||||
}
|
||||
</style>
|
||||
192
docs/.vuepress/config.js
Normal file
192
docs/.vuepress/config.js
Normal file
@@ -0,0 +1,192 @@
|
||||
const apiConfig = require('./api')
|
||||
|
||||
module.exports = {
|
||||
title: '炸毛框架(v2 旧版)',
|
||||
description: '一个高性能聊天机器人 + Web 框架',
|
||||
theme: 'antdocs',
|
||||
markdown: {
|
||||
lineNumbers: true
|
||||
},
|
||||
head: [
|
||||
['link', { rel: 'icon', href: '/logo_trans.png' }],
|
||||
['script', {}, `
|
||||
var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?f0f276cefa10aa31a20ae3815a50b795";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
`]
|
||||
],
|
||||
themeConfig: {
|
||||
repo: 'zhamao-robot/zhamao-framework',
|
||||
logo: '/logo_trans.png',
|
||||
docsDir: 'docs',
|
||||
editLinks: true,
|
||||
lastUpdated: '上次更新',
|
||||
activeHeaderLinks: false,
|
||||
nav: [
|
||||
{ text: '指南', link: '/guide/' },
|
||||
{ text: '事件和注解', link: '/event/' },
|
||||
{ text: '组件', link: '/component/' },
|
||||
{ text: '进阶', link: '/advanced/' },
|
||||
{ text: 'API', link: '/api/' },
|
||||
{ text: 'FAQ', link: '/faq/' },
|
||||
{ text: '更新日志', link: '/update/v2/' },
|
||||
{ text: '炸毛框架 v3(最新版)', link: 'https://framework.zhamao.xin/' }
|
||||
],
|
||||
sidebar: {
|
||||
'/guide/': [
|
||||
{
|
||||
title: '指南',
|
||||
collapsable: false,
|
||||
sidebarDepth: 1,
|
||||
children: [
|
||||
'',
|
||||
'installation',
|
||||
'quickstart-robot',
|
||||
'quickstart-http',
|
||||
'onebot-choose',
|
||||
'basic-config',
|
||||
'write-module',
|
||||
'register-event',
|
||||
'upgrade',
|
||||
'errcode'
|
||||
]
|
||||
}
|
||||
],
|
||||
'/event/': [
|
||||
{
|
||||
title: '事件和注解',
|
||||
collapsable: false,
|
||||
sidebarDepth: 1,
|
||||
children: [
|
||||
'',
|
||||
'robot-annotations',
|
||||
'route-annotations',
|
||||
'framework-annotations',
|
||||
'middleware',
|
||||
'custom-annotations',
|
||||
'event-dispatcher'
|
||||
]
|
||||
}
|
||||
],
|
||||
'/component/': [
|
||||
'',
|
||||
{
|
||||
title: '聊天机器人组件',
|
||||
collapsable: true,
|
||||
sidebarDepth: 2,
|
||||
children: [
|
||||
'bot/robot-api-12',
|
||||
'bot/robot-api',
|
||||
'bot/cqcode',
|
||||
'bot/message-util',
|
||||
'bot/access-token',
|
||||
'bot/turing-api',
|
||||
'bot/help-generator.md',
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '存储组件',
|
||||
collapsable: true,
|
||||
sidebarDepth: 2,
|
||||
children: [
|
||||
'store/light-cache',
|
||||
'store/mysql',
|
||||
'store/mysql-db',
|
||||
'store/redis',
|
||||
'store/atomics',
|
||||
'store/spin-lock',
|
||||
'store/data-provider'
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '通用组件',
|
||||
collapsable: true,
|
||||
sidebarDepth: 2,
|
||||
children: [
|
||||
'common/context',
|
||||
'common/coroutine-pool',
|
||||
'common/singleton-trait',
|
||||
'common/zmutil',
|
||||
'common/global-functions',
|
||||
'common/console',
|
||||
'common/task-worker',
|
||||
'common/remote-terminal',
|
||||
'common/event-tracer'
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'HTTP 组件',
|
||||
collapsable: true,
|
||||
sidebarDepth: 2,
|
||||
children: [
|
||||
'http/zmrequest',
|
||||
'http/route-manager'
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '模块/插件管理',
|
||||
collapsable: true,
|
||||
sidebarDepth: 2,
|
||||
children: [
|
||||
'module/module-pack',
|
||||
'module/module-unpack'
|
||||
]
|
||||
}
|
||||
],
|
||||
'/advanced/': [
|
||||
'',
|
||||
{
|
||||
title: '框架高级开发',
|
||||
collapsable: true,
|
||||
sidebarDepth: 2,
|
||||
children: [
|
||||
'framework-structure',
|
||||
'custom-start',
|
||||
'manually-install',
|
||||
'inside-class',
|
||||
'multi-process',
|
||||
'task-worker'
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '开发实战教程',
|
||||
collapsable: true,
|
||||
sidebarDepth: 2,
|
||||
children: [
|
||||
'connect-ws-client',
|
||||
'example/admin',
|
||||
'example/integrate-qingyunke-chatbot',
|
||||
'example/weather-bot'
|
||||
]
|
||||
},
|
||||
],
|
||||
'/api/': apiConfig,
|
||||
'/faq/': [
|
||||
'',
|
||||
'to-v2',
|
||||
'usual-question',
|
||||
'address-already-in-use',
|
||||
'display-deadlock',
|
||||
'light-cache-wrong',
|
||||
'wait-message-cqbefore'
|
||||
],
|
||||
'/update/': [
|
||||
{
|
||||
title: '更新日志',
|
||||
collapsable: true,
|
||||
sidebarDepth: 0,
|
||||
children: [
|
||||
'v2',
|
||||
'v1',
|
||||
'build-update'
|
||||
]
|
||||
},
|
||||
'config'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1
docs/.vuepress/public/CNAME
Normal file
1
docs/.vuepress/public/CNAME
Normal file
@@ -0,0 +1 @@
|
||||
docs-v2.zhamao.me
|
||||
BIN
docs/.vuepress/public/index_demo.png
Normal file
BIN
docs/.vuepress/public/index_demo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 449 KiB |
BIN
docs/.vuepress/public/logo_trans.png
Normal file
BIN
docs/.vuepress/public/logo_trans.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
1
docs/.vuepress/public/robots.txt
Normal file
1
docs/.vuepress/public/robots.txt
Normal file
@@ -0,0 +1 @@
|
||||
User-agent: *
|
||||
1
docs/.vuepress/styles/palette.less
Normal file
1
docs/.vuepress/styles/palette.less
Normal file
@@ -0,0 +1 @@
|
||||
@accentColor: #3665aa;
|
||||
@@ -1 +0,0 @@
|
||||
# FAQ
|
||||
38
docs/README.md
Normal file
38
docs/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
home: true
|
||||
heroImage: ./logo_trans.png
|
||||
actions:
|
||||
- theme: brand
|
||||
text: 快速上手
|
||||
link: /guide/
|
||||
features:
|
||||
- title: 高性能
|
||||
details: 基于 PHP 的 Swoole 高性能扩展,利用 WebSocket 进行与 OneBot 协议兼容的聊天机器人软件的通信,还有数据库连接池、内存缓存、多任务进程等特色,大幅增强性能。
|
||||
- title: 易于开发
|
||||
details: 所有功能采用模块化设计,除特殊情况外几乎所有功能都不需要修改框架内任意代码,框架采用灵活的注解进行各类事件绑定,同时支持下断点调试。
|
||||
- title: 接口直观
|
||||
details: 支持命令、普通文本、正则匹配、自然语言处理等多种对话解析方式,利用协程巧妙实现了直观的交互式会话模式,同时支持多种富文本的处理。
|
||||
footer: |
|
||||
Apache-2.0 Licensed | Copyright © 2019-2022 Zhamao Developer Team | <a href="http://beian.miit.gov.cn">沪ICP备2021010446号-1</a>
|
||||
---
|
||||
|
||||
# 快速上手
|
||||
|
||||
## 安装框架和环境
|
||||
|
||||
此命令可一键以模板安装框架!(仅限 Linux 和 macOS)
|
||||
|
||||
```bash
|
||||
bash <(curl -fsSL https://zhamao.xin/go.sh)
|
||||
```
|
||||
|
||||
## 运行框架
|
||||
|
||||
```bash
|
||||
cd zhamao-app/
|
||||
./zhamao server
|
||||
```
|
||||
|
||||
## 效果图
|
||||
|
||||

|
||||
4
docs/advanced/README.md
Normal file
4
docs/advanced/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# 进阶开发
|
||||
在本章,下面的部分将详细说明一些具体的案例和自定义框架的操作。
|
||||
|
||||
> 更多进阶教程敬请期待....(或者你可以选择提 Issue 到框架 GitHub,有需求就写入文档)
|
||||
@@ -11,9 +11,11 @@
|
||||
|
||||
以上两种方式,`Header` 方式比 `GET` 方式优先级要高,如果两者均没有指定,框架会将此连接当作 `default` 类型接入。
|
||||
|
||||
!!! note "提示"
|
||||
::: tip 提示
|
||||
|
||||
对于对接 OneBot 标准的机器人客户端,只要符合 OneBot 标准,即 `X-Client-Role` 会自动带上 `universal`、`qq` 等字样,就会自动标记为 `qq` 类型。
|
||||
对于对接 OneBot 标准的机器人客户端,只要符合 OneBot 标准,即 `X-Client-Role` 会自动带上 `universal`、`qq` 等字样,就会自动标记为 `qq` 类型。
|
||||
|
||||
:::
|
||||
|
||||
## 逻辑编写
|
||||
|
||||
@@ -140,4 +142,3 @@ public function onMessage() {
|
||||
```php
|
||||
server()->close($conn->getFd());
|
||||
```
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
从前面的几章中,我们了解到框架有多种下载到本地的方式。
|
||||
|
||||
- Composer 依赖模式
|
||||
- Starter 从模板创建模式
|
||||
- Starter 从模板创建模式(等同于 Composer 模式)
|
||||
- 源码模式
|
||||
- Phar Composer 依赖模式
|
||||
- Phar 源码模式
|
||||
|
||||
### Composer 依赖模式
|
||||
|
||||
@@ -85,17 +87,20 @@ bin/start server # 通过源码模式启动框架
|
||||
- `--debug-mode`:启用调试模式,调试模式的作用是关闭一键协程化和终端交互,减少 Swoole 本身对代码逻辑的干扰(比如执行 `shell_exec()` 报错的话可以开启这个进行调试)。
|
||||
- `--log-{mode}`:设置 log 等级。支持 `--log-debug`,`--log-verbose`,`--log-info`,`--log-warning`,`--log-error`。
|
||||
- `--log-theme`:设置终端信息的主题。这个选项适用于多种终端信息显示的兼容,例如白色终端和不支持颜色的终端。详见 [Console - 主题设置](/component/console/#_2)。
|
||||
- `--disable-console-input`:关闭终端交互,如果你使用的不是 tmux、screen 而是直接将进程使用 systemd 等方式运行到 init 守护进程下,则需要关闭终端交互输入,关闭后不可以使用 `stop, reload, logtest` 等交互命令。
|
||||
- `--disable-coroutine`:关闭一键协程化。
|
||||
- `--remote-terminal`:开启 nc 远程终端,配置文件使用全局中的 `remote_terminal` 项。也可以在全局配置中常开启(status 设置为 true)。
|
||||
- `--daemon`:以守护进程方式运行框架,此参数将直接在输出 motd 后将进程挂到 init 下运行,后台常驻。
|
||||
- `--watch`:监控 `src/` 目录下的文件变化,有变化则自动重新载入代码。开启监控需要安装 PHP 扩展:inotify。使用 pecl 就可以安装:`pecl install inotify`。
|
||||
- `--watch`:监控 `src/` 目录下的文件变化,有变化则自动重新载入代码。开启监控需要安装 PHP 扩展:inotify。使用 pecl 就可以安装:`pecl install inotify`。(注:不支持 WSL 和 macOS)
|
||||
- `--env`:设置运行环境,设置运行环境后将优先加载指定环境的配置文件,支持 `--env=production`,`--env=staging`,`--env=development`,见 [基本配置](/guide/basic-config/#_2)。
|
||||
- `--worker-num`:指定运行的工作进程数量(并不是越多越好,框架默认为 CPU 核心数),例如 `--worker-num=8`。
|
||||
- `--task-worker-num`:启用 TaskWorker 进程并指定数量。
|
||||
- `--show-php-ver`:在启动时显示 Swoole 和 PHP 的版本。
|
||||
|
||||
## 守护进程操作命令
|
||||
|
||||
守护进程在 2.2.0 版本开始,可以使用命令行快速操作,如重启、停止、查看状态等。
|
||||
|
||||
注意,这里的守护进程操作命令是指 **使用 `--daemon` 方式启动的框架**,如使用 Docker、screen、tmux 等方式挂后台跑则此命令不可用!
|
||||
注意,这里的守护进程操作命令是指 **使用 `--daemon` 方式启动的框架**,如使用 Docker、screen、tmux、systemd 等方式挂后台跑则此命令不可用!
|
||||
|
||||
```bash
|
||||
vendor/bin/start daemon:status # 查看守护进程的状态
|
||||
@@ -116,4 +121,16 @@ vendor/bin/start simple-http-server your-web-dir/ --host=0.0.0.0 --port=8080
|
||||
```
|
||||
|
||||
- `your-web-dir` 是必填的参数。
|
||||
- `--host` 和 `--port` 是可选参数,如果不填,则默认使用 `global.php` 配置文件中的配置。
|
||||
- `--host` 和 `--port` 是可选参数,如果不填,则默认使用 `global.php` 配置文件中的配置。
|
||||
|
||||
### 检查配置是否更新
|
||||
|
||||
默认情况下(非源码模式),你可以使用命令 `vendor/bin/start check:config` 来检查你的配置文件是否需要更新部分段落。
|
||||
|
||||
### systemd 配置文件生成器
|
||||
|
||||
框架支持生成 systemd 配置文件 `zhamao.service`,生成后将文件放入 `/etc/systemd/system` 后输入 `systemctl enable zhamao.service` 即可。
|
||||
|
||||
命令:`vendor/bin/start systemd:generate`
|
||||
|
||||
注意,systemd 启动的守护进程模式和使用参数 `--daemon` 不一样,请勿同时混用,直接使用上述命令生成的配置文件即可正常使用!
|
||||
|
||||
@@ -87,14 +87,13 @@ class AdminMiddleware implements MiddlewareInterface
|
||||
*/
|
||||
```
|
||||
|
||||
<chat-box>
|
||||
^ 假设我是管理员
|
||||
) 禁言 1234567 600
|
||||
( 禁言成功!
|
||||
^ 假设我不在管理员名单里
|
||||
) 禁言 1234567 900
|
||||
^ 机器人没有回复,因为中间件返回了 false,不继续执行
|
||||
</chat-box>
|
||||
<chat-box :my-chats="[
|
||||
{type:0,content:'禁言 1234567 600'},
|
||||
{type:1,content:'禁言成功!'},
|
||||
{type:2,content:'假设我不在管理员名单里'},
|
||||
{type:0,content:'禁言 1234567 900'},
|
||||
{type:2,content:'机器人没有回复,因为中间件返回了 false,不继续执行'},
|
||||
]"></chat-box>
|
||||
|
||||
而这时候有朋友又要问了,如果我有一系列管理员命令,假设都在一个叫 `AdminFunc.php` 的模块类里,我是不是还得一个一个地给注解事件写 `@Middleware("admin")` 呢?当然不需要!如果你这个类所有的注解事件都是机器人的聊天事件(`@CQCommand`,`@CQMessage`)的话,可以直接给类注解这个中间件,效果等同于给每一个函数写一次中间件注解。
|
||||
|
||||
@@ -120,112 +119,111 @@ class AdminFunc
|
||||
|
||||
上面我们讲到了,中间件里面使用了 `LightCache` 轻量缓存来储存临时的管理员列表,那么我们将这部分的代码完善吧!
|
||||
|
||||
=== "src/Module/Example/AdminFunc.php"
|
||||
**src/Module/Example/AdminFunc.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Module\Example;
|
||||
namespace Module\Example;
|
||||
|
||||
use ZM\Annotation\CQ\CQCommand;
|
||||
use ZM\Annotation\Http\Middleware;
|
||||
use ZM\API\CQ;
|
||||
use ZM\Annotation\CQ\CQCommand;
|
||||
use ZM\Annotation\Http\Middleware;
|
||||
use ZM\API\CQ;
|
||||
|
||||
/**
|
||||
* Class AdminFunc
|
||||
* @package Module\Example
|
||||
* @Middleware("admin")
|
||||
*/
|
||||
class AdminFunc
|
||||
{
|
||||
/**
|
||||
* @CQCommand(match="禁言",message_type="group")
|
||||
*/
|
||||
public function banSomeone() {
|
||||
$r1 = ctx()->getNextArg("请输入禁言的人或at他");
|
||||
$r2 = ctx()->getFullArg("请输入禁言的时间(秒)");
|
||||
$cq = CQ::getCQ($r1);
|
||||
if ($cq !== null) {
|
||||
if ($cq["type"] != "at") return "请at或者输入正确的QQ号!";
|
||||
$r1 = $cq["params"]["qq"];
|
||||
}
|
||||
// 群内禁言用户
|
||||
ctx()->getRobot()->setGroupBan(ctx()->getGroupId(), $r1, $r2);
|
||||
return "禁言成功!";
|
||||
}
|
||||
|
||||
/**
|
||||
* Class AdminFunc
|
||||
* @package Module\Example
|
||||
* @CQCommand(match="解除禁言",message_type="group")
|
||||
*/
|
||||
public function unbanSomeone() {
|
||||
$r1 = ctx()->getNextArg("请输入禁言的人或at他");
|
||||
$cq = CQ::getCQ($r1);
|
||||
if ($cq !== null) {
|
||||
if ($cq["type"] != "at") return "请at或者输入正确的QQ号!";
|
||||
$r1 = $cq["params"]["qq"];
|
||||
}
|
||||
// 群内禁言用户
|
||||
ctx()->getRobot()->setGroupBan(ctx()->getGroupId(), $r1, 0);
|
||||
return "解除禁言成功!";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**src/Module/Example/AdminManager.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Module\Example;
|
||||
|
||||
use ZM\Annotation\CQ\CQCommand;
|
||||
use ZM\Annotation\Http\Middleware;
|
||||
use ZM\Annotation\Swoole\OnStart;
|
||||
use ZM\Store\LightCache;
|
||||
use ZM\Store\Lock\SpinLock;
|
||||
|
||||
class AdminManager
|
||||
{
|
||||
/**
|
||||
* @OnStart()
|
||||
*/
|
||||
public function onStart() {
|
||||
if (!LightCache::isset("admin_list")) { //一次性代码,首次执行才会执行if
|
||||
LightCache::set("admin_list", [ // 框架启动时初始化管理员列表
|
||||
"123456",
|
||||
"234567"
|
||||
], -2); // 这里用 -2 的原因是将这一列表持久化保存,避免关闭框架后丢失
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @CQCommand(match="添加管理员")
|
||||
* @Middleware("admin")
|
||||
*/
|
||||
class AdminFunc
|
||||
{
|
||||
/**
|
||||
* @CQCommand(match="禁言",message_type="group")
|
||||
*/
|
||||
public function banSomeone() {
|
||||
$r1 = ctx()->getNextArg("请输入禁言的人或at他");
|
||||
$r2 = ctx()->getFullArg("请输入禁言的时间(秒)");
|
||||
$cq = CQ::getCQ($r1);
|
||||
if ($cq !== null) {
|
||||
if ($cq["type"] != "at") return "请at或者输入正确的QQ号!";
|
||||
$r1 = $cq["params"]["qq"];
|
||||
}
|
||||
// 群内禁言用户
|
||||
ctx()->getRobot()->setGroupBan(ctx()->getGroupId(), $r1, $r2);
|
||||
return "禁言成功!";
|
||||
}
|
||||
|
||||
/**
|
||||
* @CQCommand(match="解除禁言",message_type="group")
|
||||
*/
|
||||
public function unbanSomeone() {
|
||||
$r1 = ctx()->getNextArg("请输入禁言的人或at他");
|
||||
$cq = CQ::getCQ($r1);
|
||||
if ($cq !== null) {
|
||||
if ($cq["type"] != "at") return "请at或者输入正确的QQ号!";
|
||||
$r1 = $cq["params"]["qq"];
|
||||
}
|
||||
// 群内禁言用户
|
||||
ctx()->getRobot()->setGroupBan(ctx()->getGroupId(), $r1, 0);
|
||||
return "解除禁言成功!";
|
||||
}
|
||||
public function addAdmin() { //只有管理员才能添加管理员
|
||||
$qq = ctx()->getNextArg("请输入要添加管理员的QQ(qq号码,不可at)");
|
||||
SpinLock::lock("admin_list"); //如果是多进程模式的话需要加锁
|
||||
$ls = LightCache::get("admin_list");
|
||||
if (!in_array($qq, $ls)) $ls[] = $qq;
|
||||
LightCache::set("admin_list", $ls, -2);
|
||||
SpinLock::unlock("admin_list"); //如果是多进程模式的话需要加锁
|
||||
return "成功添加 $qq 到管理员列表!";
|
||||
}
|
||||
```
|
||||
|
||||
=== "src/Module/Example/AdminManager.php"
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Module\Example;
|
||||
|
||||
use ZM\Annotation\CQ\CQCommand;
|
||||
use ZM\Annotation\Http\Middleware;
|
||||
use ZM\Annotation\Swoole\OnStart;
|
||||
use ZM\Store\LightCache;
|
||||
use ZM\Store\Lock\SpinLock;
|
||||
|
||||
class AdminManager
|
||||
{
|
||||
/**
|
||||
* @OnStart()
|
||||
*/
|
||||
public function onStart() {
|
||||
if (!LightCache::isset("admin_list")) { //一次性代码,首次执行才会执行if
|
||||
LightCache::set("admin_list", [ // 框架启动时初始化管理员列表
|
||||
"123456",
|
||||
"234567"
|
||||
], -2); // 这里用 -2 的原因是将这一列表持久化保存,避免关闭框架后丢失
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @CQCommand(match="添加管理员")
|
||||
* @Middleware("admin")
|
||||
*/
|
||||
public function addAdmin() { //只有管理员才能添加管理员
|
||||
$qq = ctx()->getNextArg("请输入要添加管理员的QQ(qq号码,不可at)");
|
||||
SpinLock::lock("admin_list"); //如果是多进程模式的话需要加锁
|
||||
$ls = LightCache::get("admin_list");
|
||||
if (!in_array($qq, $ls)) $ls[] = $qq;
|
||||
LightCache::set("admin_list", $ls, -2);
|
||||
SpinLock::unlock("admin_list"); //如果是多进程模式的话需要加锁
|
||||
return "成功添加 $qq 到管理员列表!";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<chat-box>
|
||||
^ 现在我是 123456
|
||||
) 禁言 13579 60
|
||||
( 禁言成功!
|
||||
) 解除禁言 13579
|
||||
( 解除禁言成功!
|
||||
) 添加管理员 98765
|
||||
( 成功添加 98765 到管理员列表!
|
||||
^ 现在我是98765
|
||||
) 禁言 13579
|
||||
( 请输入禁言的时间(秒)
|
||||
) 120
|
||||
( 禁言成功!
|
||||
</chat-box>
|
||||
}
|
||||
```
|
||||
|
||||
<chat-box :my-chats="[
|
||||
{type:2,content:'现在我是 123456'},
|
||||
{type:0,content:'禁言 13579 60'},
|
||||
{type:1,content:'禁言成功!'},
|
||||
{type:0,content:'解除禁言 13579'},
|
||||
{type:1,content:'解除禁言成功!'},
|
||||
{type:0,content:'添加管理员 98765'},
|
||||
{type:1,content:'成功添加 98765 到管理员列表!'},
|
||||
{type:2,content:'现在我是98765'},
|
||||
{type:0,content:'禁言 13579'},
|
||||
{type:1,content:'请输入禁言的时间(秒)'},
|
||||
{type:0,content:'120'},
|
||||
{type:1,content:'禁言成功!'},
|
||||
]"></chat-box>
|
||||
|
||||
85
docs/advanced/example/integrate-qingyunke-chatbot.md
Normal file
85
docs/advanced/example/integrate-qingyunke-chatbot.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# 接入青云客智能聊天机器人API
|
||||
|
||||
作为一个群聊机器人,懂得聊天会让机器人增色不少,在大数据和 AI 热潮下,不少厂商都研发了自己的智能聊天 API,例如图灵机器人、腾讯智能闲聊等,大厂开发的 API 自然有着他人无可比拟的健壮性和可靠性,但是随之而来不菲的价格显然并不适合大众开发者。这时候一个免费、可用的智能聊天 API 便非常重要了,其中,青云客是少有的完全免费、无需注册的智能聊天 API,提供了包括智能聊天、歌词、天气查询、笑话等多种有用功能,且接入简单,非常适合新手开发者尝试。
|
||||
|
||||
## 结果演示
|
||||
|
||||

|
||||
|
||||
## 阅读接入指南
|
||||
|
||||
不管接入何种服务,阅读接入指南永远都是最优先、最重要的一步,所幸青云客的接入指南十分简单,简单来说归纳为以下:
|
||||
* 请求:GET https://api.qingyunke.com/api.php
|
||||
* 参数:
|
||||
* * `key` 目前固定为 `free`
|
||||
* * `appid` 目前固定为 `0`
|
||||
* * `msg` 关键词,需要经过 `urlencode`
|
||||
* 注意:返回结果中 `{br}` 代表换行
|
||||
|
||||
## 逻辑编写
|
||||
|
||||
阅读过后,我们便可以进行主要的编写工作了。
|
||||
|
||||
首先,为了机器人的性能考虑,也为了避免过分打扰群聊的聊天,我们希望机器人只有在主动触发(@AT 或者 关键词等)时才会进行智能聊天。
|
||||
|
||||
对于关键词匹配,我们可以使用 `@CQCommand`:
|
||||
|
||||
```php
|
||||
/**
|
||||
* 智能聊天
|
||||
*
|
||||
* @CQCommand(start_with="机器人")
|
||||
*/
|
||||
public function chat()
|
||||
{
|
||||
// 替换掉机器人前缀,并获取消息内容
|
||||
$msg = ctx()->getMessage();
|
||||
$msg = str_replace('机器人', '', $msg);
|
||||
if (empty(trim($msg))) {
|
||||
$msg = ctx()->getFullArg('怎么了?');
|
||||
}
|
||||
|
||||
Console::info('正在获取智能聊天回复:' . $msg);
|
||||
// 请求 API 获取回复
|
||||
$raw_data = file_get_contents('https://api.qingyunke.com/api.php?key=free&appid=0&msg=' . urlencode($msg));
|
||||
try {
|
||||
$data = json_decode($raw_data, true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (\Exception $e) {
|
||||
$data = ['content' => '机器人解析异常,请稍后再试'];
|
||||
Console::warning('无法获取智能聊天回复:' . $e->getMessage());
|
||||
}
|
||||
if ($data['result'] !== 0) {
|
||||
$data = ['content' => '机器人服务异常,请稍后再试'];
|
||||
Console::warning('无法获取智能聊天回复:' . $raw_data);
|
||||
}
|
||||
Console::info('获取智能聊天回复完成:' . $data['content']);
|
||||
// 将 {br} 替换为换行
|
||||
$data['content'] = strtr($data['content'], ['{br}' => "\n"]);
|
||||
return $data['content'];
|
||||
}
|
||||
```
|
||||
|
||||
这样我们的命令便只会在用户发送以`机器人`开头的消息时才会触发。
|
||||
|
||||
同时,我们也希望在 @AT 机器人时也进行回复,此时可以使用 `@CQBefore` 方法进行折中:
|
||||
|
||||
```php
|
||||
/**
|
||||
* 将 AT 机器人的消息交由智能聊天处理
|
||||
*
|
||||
* @CQBefore("message")
|
||||
*/
|
||||
public function changeAt(): bool
|
||||
{
|
||||
// 判断此条消息是否 AT 了机器人
|
||||
if (MessageUtil::isAtMe(ctx()->getMessage(), ctx()->getRobotId())) {
|
||||
// 将 AT 本身从消息中去掉
|
||||
$msg = str_replace(CQ::at(ctx()->getRobotId()), '', ctx()->getMessage());
|
||||
ctx()->setMessage('机器人' . trim($msg));
|
||||
// 调用智能聊天
|
||||
ctx()->reply($this->chat());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
113
docs/advanced/example/weather-bot.md
Normal file
113
docs/advanced/example/weather-bot.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# 基于词性分析和魅族天气的天气查询机器人
|
||||
|
||||
本文将基于 [`jieba-php`](https://github.com/fukuball/jieba-php) 中文分词库以及 [魅族天气 API](https://github.com/shichunlei/-Api/blob/master/MeizuWeather.md) 开发一个天气查询机器人。
|
||||
|
||||
## 结果演示
|
||||
|
||||

|
||||
尾部的随机表情并非本教程的一部分。
|
||||
|
||||
## 逻辑编写
|
||||
|
||||
[jieba-php](https://github.com/fukuball/jieba-php) 是目前比较好用的中文分词库,虽然最近的维护并不活跃,但已足够我们的需求:
|
||||
|
||||
```shell
|
||||
composer require fukuball/jieba-php:dev-master
|
||||
```
|
||||
|
||||
以下代码使用了本文作者自行编写的天气查询库,需要进行引入:
|
||||
|
||||
```shell
|
||||
composer require sunxyw/weather
|
||||
```
|
||||
|
||||
您也可以将以下代码自行改写为直接调用魅族天气 API,详情请参阅[魅族天气 API 文档](https://github.com/shichunlei/-Api/blob/master/MeizuWeather.md)。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Bot\Module\SmartChat;
|
||||
|
||||
use Fukuball\Jieba\Jieba;
|
||||
use Fukuball\Jieba\Posseg;
|
||||
use Sunxyw\Weather\Weather;
|
||||
use ZM\Annotation\CQ\CQCommand;
|
||||
use ZM\Console\Console;
|
||||
|
||||
class WeatherReport
|
||||
{
|
||||
/**
|
||||
* 加载字典
|
||||
*
|
||||
* @OnStart(worker_id=-1)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initDictionary(): void
|
||||
{
|
||||
// 分词以及词性分析需要载入字典到内存
|
||||
ini_set('memory_limit', '600M');
|
||||
Jieba::init(['dict' => 'small']);
|
||||
Posseg::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询天气
|
||||
*
|
||||
* @CQCommand(keyword="天气")
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function cmdQueryWeather(): string
|
||||
{
|
||||
// 分词并进行词性分析
|
||||
$seg_list = Posseg::cut(ctx()->getMessage());
|
||||
$tags = array_column($seg_list, 'tag');
|
||||
// 找出词性为 ns(地名)的单词
|
||||
$location_index = array_search('ns', $tags, true);
|
||||
$location = $seg_list[$location_index]['word'];
|
||||
|
||||
// 此处引入了本文作者自己写的天气库
|
||||
$w = new Weather();
|
||||
try {
|
||||
$report = $w->getWeather($location);
|
||||
} catch (\InvalidArgumentException) {
|
||||
return '城市输入错误';
|
||||
} catch (\JsonException $e) {
|
||||
Console::warning("天气查询失败:{$e->getMessage()}");
|
||||
return '天气查询失败';
|
||||
}
|
||||
|
||||
$template = <<<EOF
|
||||
%s天气:%s
|
||||
温度:%s℃
|
||||
湿度:%s%%
|
||||
风向:%s %s
|
||||
空气质量:%s
|
||||
------------------------------
|
||||
未来三天天气:
|
||||
%s:%s,日间%s℃,夜间%s℃,吹%s %s
|
||||
%s:%s,日间%s℃,夜间%s℃,吹%s %s
|
||||
%s:%s,日间%s℃,夜间%s℃,吹%s %s
|
||||
EOF;
|
||||
$args = [
|
||||
$report->getCity(),
|
||||
$report->getRealtime()['weather'],
|
||||
$report->getRealtime()['temperature'],
|
||||
$report->getRealtime()['humidity'],
|
||||
$report->getRealtime()['wind_direction'],
|
||||
$report->getRealtime()['wind_speed'],
|
||||
$report->getRealtime()['air_quality'],
|
||||
];
|
||||
foreach (array_slice($report->getForecastDaily(), 0, 3) as $forecast) {
|
||||
$args[] = $forecast['date'];
|
||||
$args[] = $forecast['weather'];
|
||||
$args[] = $forecast['temperature']['day'];
|
||||
$args[] = $forecast['temperature']['night'];
|
||||
$args[] = $forecast['wind_direction'];
|
||||
$args[] = $forecast['wind_speed'];
|
||||
}
|
||||
return vsprintf($template, ...$args);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -2,5 +2,4 @@
|
||||
|
||||
## 框架运行总结构图
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# 进阶开发
|
||||
在本章,下面的部分将详细说明一些具体的案例和自定义框架的操作。
|
||||
|
||||
- 如何自定义修改框架本身?- [框架启动方式](/advanced/custom-start/)
|
||||
- 如何接入一个自己的 WebSocket 客户端?- [接入 WebSocket 客户端](/advanced/connect-ws-client/)
|
||||
- 框架到底是怎么工作的?- [框架结构剖析](/advanced/framework-structure/)
|
||||
|
||||
> 更多进阶教程敬请期待....(或者你可以选择提 Issue 到框架 GitHub,有需求就写入文档)
|
||||
|
||||
@@ -27,3 +27,41 @@
|
||||
TODO:先放一放。
|
||||
```
|
||||
|
||||
## ZM\Entity\MatchObject
|
||||
|
||||
此类是调用方法 `MessageUtil::matchCommand()` 返回的对象体,含有匹配成功与否和匹配到的注解相关的信息。
|
||||
|
||||
### 属性
|
||||
|
||||
- `$match`:`bool` 类型,返回匹配是否成功
|
||||
- `$object`:`CQCommand` 注解类,如果匹配成功则返回对应的 `@CQCommand` 信息
|
||||
- `match`:`array` 类型,如果匹配成功则返回匹配到的参数
|
||||
|
||||
```php
|
||||
// 假设我有一个注解事件 @CQCommand(match="你好"),绑定的函数是 \Module\Example\Hello 下的 hello123()
|
||||
|
||||
$obj = MessageUtil::matchCommand("你好 我叫顺溜 我今年二十八", ctx()->getData());
|
||||
/* 以下是返回信息,仅供参考
|
||||
$obj->match ==> true
|
||||
$obj->object ==> \ZM\Annotation\CQ\CQCommand: (
|
||||
match: "你好",
|
||||
pattern: "",
|
||||
regex: "",
|
||||
start_with: "",
|
||||
end_with: "",
|
||||
keyword: "",
|
||||
alias: [],
|
||||
message_type: "",
|
||||
user_id: 0,
|
||||
group_id: 0,
|
||||
discuss_id: 0,
|
||||
level: 20,
|
||||
method: "hello123",
|
||||
class: \Module\Example\Hello::class
|
||||
)
|
||||
$obj->match ==> [
|
||||
"我叫顺溜",
|
||||
"我今年二十八"
|
||||
]
|
||||
*/
|
||||
```
|
||||
|
||||
3
docs/advanced/manually-install.md
Normal file
3
docs/advanced/manually-install.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 手动部署环境教程
|
||||
|
||||
TODO: 还没写
|
||||
@@ -16,13 +16,13 @@ PHP 也是如此,框架的多进程又是怎么一回事呢?为什么要采
|
||||
|
||||
**但是**,CPU 密集型的应用怎么办呢?假设我的 Web 应用有大量的排序、md5 运算怎么办呢?这样的阻塞,假设是一个超级大的 for 循环或者是要执行很长时间的 while 循环,CPU 一直在被占用。多进程就是针对 CPU 密集型的应用说 yes 的一个方案。
|
||||
|
||||

|
||||

|
||||
|
||||
我们假设现在有 3 个请求同时访问,也就是说上面的流程需要执行 3 遍。而如果我们只有一个进程的话,最后一个请求需要等待的时间为 `2*3+5*3=21` 秒,非常耗时。
|
||||
|
||||
而如果有两个进程处理 3 个请求,则最后一个完成的请求就缩短了,`2+5+2+5=14` 秒。
|
||||
|
||||
.png)
|
||||

|
||||
|
||||
所以如果要充分利用你的服务器或者个人电脑的多核 CPU 资源,就要设置多个进程来处理。一个进程只能在一个 CPU 上运行,而设置了多进程后,就可以让多核 CPU 充分运行多个进程,所以我们给框架设置多进程的推荐数值为等同于 CPU 的核心数。
|
||||
|
||||
@@ -32,7 +32,7 @@ PHP 也是如此,框架的多进程又是怎么一回事呢?为什么要采
|
||||
|
||||
## 框架进程模型
|
||||
|
||||
.png)
|
||||

|
||||
|
||||
上图中,横向的时间片可以理解为并行执行,这些操作在多个 CPU 内可能同时在执行。
|
||||
|
||||
@@ -40,7 +40,7 @@ PHP 也是如此,框架的多进程又是怎么一回事呢?为什么要采
|
||||
|
||||
众所周知,进程是程序在操作系统中的一个边界,和自己有关的一切变量、内容和代码都在自己的进程内,不同进程之间如果不使用管道等方式,是不可以互相访问的。而加上开始描述的,创建子进程是一个复制自身的过程,所以也就会有如下图的情况:
|
||||
|
||||
.png)
|
||||

|
||||
|
||||
我们以静态类为例,设置一个进程中的全局变量。这里就会出现,同一个静态变量在多个进程中完全不同的值的结果。此后,我们将会在 Worker 进程中执行用户的代码,如果设置 Worker 数量仅为 1 的话,那么就简单许多了,你还是可以使用全局变量或静态类来存储你想要的内容而不用担心这种多个进程变量隔离的情况(因为用户的 Web 请求处理的代码只会在一个 Worker 进程中执行)。如果像上图一样设置了多个 Worker,则用户过来的比如 HTTP 请求就有可能出现在不同的 Worker 进程中,给全局变量设值就一定会造成不同步的问题。这时我们就不可以使用全局变量做数据同步(注意,我说的是数据同步)。
|
||||
|
||||
@@ -63,8 +63,10 @@ PHP 也是如此,框架的多进程又是怎么一回事呢?为什么要采
|
||||
| LightCache | 框架封装的跨进程的 key-value 存储模型 | 性能强悍,无 I/O 和网络通信 | 需要提前分配最大内存大小,最大单个值长度大小,不灵活 |
|
||||
| WorkerCache | 框架封装的基于进程的 key-value 存储模型,类似 Redis | 无需提前分配最大内存大小,受限于 PHP memory_limit | 见 WorkerCache 的说明 |
|
||||
|
||||
!!! note "WorkerCache 的说明"
|
||||
对于 WorkerCache 来说,其实是比较特殊的进程间通信。具体来说就是,WorkerCache 的原理就是将变量指定的存到一个进程中,如果是本进程读写的话直接相当于改一下全局变量,如果是其他进程读写的话,则依靠进程间通信。
|
||||
|
||||
所以缺点也显而易见,如果使用过程中不是命中了 WorkerCache 存储所在的进程的话,则一直会使用进程间通信,影响一定的效率。
|
||||
::: tip WorkerCache 的说明
|
||||
|
||||
对于 WorkerCache 来说,其实是比较特殊的进程间通信。具体来说就是,WorkerCache 的原理就是将变量指定的存到一个进程中,如果是本进程读写的话直接相当于改一下全局变量,如果是其他进程读写的话,则依靠进程间通信。
|
||||
|
||||
所以缺点也显而易见,如果使用过程中不是命中了 WorkerCache 存储所在的进程的话,则一直会使用进程间通信,影响一定的效率。
|
||||
|
||||
:::
|
||||
|
||||
3
docs/advanced/php-env.md
Normal file
3
docs/advanced/php-env.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# PHP 环境高级部署方式
|
||||
|
||||
TODO: 留个坑。
|
||||
3
docs/advanced/task-worker.md
Normal file
3
docs/advanced/task-worker.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 使用 TaskWorker 进程处理密集运算
|
||||
|
||||
> TODO: 新开个坑,有时间补上。(__填坑标记__)
|
||||
618
docs/api/ZM/API/CQ.md
Normal file
618
docs/api/ZM/API/CQ.md
Normal file
@@ -0,0 +1,618 @@
|
||||
# ZM\API\CQ
|
||||
|
||||
## at
|
||||
|
||||
```php
|
||||
public function at(int|string $qq): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
at一下QQ用户(仅在QQ群支持at全体)
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| qq | int|string | 用户QQ号/ID号 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## face
|
||||
|
||||
```php
|
||||
public function face(int|string $id): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送QQ原生表情
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| id | int|string | 表情ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## image
|
||||
|
||||
```php
|
||||
public function image(string $file, bool $cache, bool $flash, bool $proxy, int $timeout): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送图片
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| file | string | 文件的路径、URL或者base64编码的图片数据 |
|
||||
| cache | bool | 是否缓存(默认为true) |
|
||||
| flash | bool | 是否闪照(默认为false) |
|
||||
| proxy | bool | 是否使用代理(默认为true) |
|
||||
| timeout | int | 超时时间(默认不超时) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## record
|
||||
|
||||
```php
|
||||
public function record(string $file, bool $magic, bool $cache, bool $proxy, int $timeout): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送语音
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| file | string | 文件的路径、URL或者base64编码的语音数据 |
|
||||
| magic | bool | 是否加特技(默认为false) |
|
||||
| cache | bool | 是否缓存(默认为true) |
|
||||
| proxy | bool | 是否使用代理(默认为true) |
|
||||
| timeout | int | 超时时间(默认不超时) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## video
|
||||
|
||||
```php
|
||||
public function video(string $file, bool $cache, bool $proxy, int $timeout): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送短视频
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| file | string | 文件的路径、URL或者base64编码的短视频数据 |
|
||||
| cache | bool | 是否缓存(默认为true) |
|
||||
| proxy | bool | 是否使用代理(默认为true) |
|
||||
| timeout | int | 超时时间(默认不超时) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## rps
|
||||
|
||||
```php
|
||||
public function rps(): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送投掷骰子(只能在单条回复中单独使用)
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## dice
|
||||
|
||||
```php
|
||||
public function dice(): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送掷骰子表情(只能在单条回复中单独使用)
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## shake
|
||||
|
||||
```php
|
||||
public function shake(): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
戳一戳(原窗口抖动,仅支持好友消息使用)
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## poke
|
||||
|
||||
```php
|
||||
public function poke(int|string $type, int|string $id, string $name): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送新的戳一戳
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| type | int|string | 焯一戳类型 |
|
||||
| id | int|string | 戳一戳ID号 |
|
||||
| name | string | 戳一戳名称(可选) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## anonymous
|
||||
|
||||
```php
|
||||
public function anonymous(int $ignore): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送匿名消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| ignore | int | 是否忽略错误(默认为1,0表示不忽略错误) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## share
|
||||
|
||||
```php
|
||||
public function share(string $url, string $title, null|string $content, null|string $image): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送链接分享(只能在单条回复中单独使用)
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| url | string | 分享地址 |
|
||||
| title | string | 标题 |
|
||||
| content | null|string | 卡片内容(可选) |
|
||||
| image | null|string | 卡片图片(可选) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## contact
|
||||
|
||||
```php
|
||||
public function contact(int|string $type, int|string $id): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送好友或群推荐名片
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| type | int|string | 名片类型 |
|
||||
| id | int|string | 好友或群ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## location
|
||||
|
||||
```php
|
||||
public function location(float|string $lat, float|string $lon, string $title, string $content): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送位置
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| lat | float|string | 纬度 |
|
||||
| lon | float|string | 经度 |
|
||||
| title | string | 标题(可选) |
|
||||
| content | string | 卡片内容(可选) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## music
|
||||
|
||||
```php
|
||||
public function music(string $type, int|string $id_or_url, null|string $audio, null|string $title, null|string $content, null|string $image): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送音乐分享(只能在单条回复中单独使用)
|
||||
qq、163、xiami为内置分享,需要先通过搜索功能获取id后使用
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| type | string | 分享类型(仅限 `qq`、`163`、`xiami` 或 `custom`) |
|
||||
| id_or_url | int|string | 当分享类型不是 `custom` 时,表示的是分享音乐的ID(需要先通过搜索功能获取id后使用),反之表示的是音乐卡片点入的链接 |
|
||||
| audio | null|string | 当分享类型是 `custom` 时,表示为音乐(如mp3文件)的HTTP链接地址(不可为空) |
|
||||
| title | null|string | 当分享类型是 `custom` 时,表示为音乐卡片的标题,建议12字以内(不可为空) |
|
||||
| content | null|string | 当分享类型是 `custom` 时,表示为音乐卡片的简介(可忽略) |
|
||||
| image | null|string | 当分享类型是 `custom` 时,表示为音乐卡片的图片链接地址(可忽略) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## forward
|
||||
|
||||
```php
|
||||
public function forward(int|string $id): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
合并转发消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| id | int|string | 合并转发ID, 需要通过 `/get_forward_msg` API获取转发的具体内容 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## node
|
||||
|
||||
```php
|
||||
public function node(int|string $user_id, string $nickname, string $content): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
合并转发消息节点
|
||||
特殊说明: 需要使用单独的API /send_group_forward_msg 发送, 并且由于消息段较为复杂, 仅支持Array形式入参。
|
||||
如果引用消息和自定义消息同时出现, 实际查看顺序将取消息段顺序。
|
||||
另外按 CQHTTP 文档说明, data 应全为字符串, 但由于需要接收message 类型的消息, 所以 仅限此Type的content字段 支持Array套娃
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| user_id | int|string | 转发消息id |
|
||||
| nickname | string | 发送者显示名字 |
|
||||
| content | string | 具体消息 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## xml
|
||||
|
||||
```php
|
||||
public function xml(string $data): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
XML消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| data | string | xml内容, xml中的value部分 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## json
|
||||
|
||||
```php
|
||||
public function json(string $data, int $resid): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
JSON消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| data | string | json内容 |
|
||||
| resid | int | 0为走小程序通道,其他值为富文本通道(默认为0) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## _custom
|
||||
|
||||
```php
|
||||
public function _custom(string $type_name, array $params): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
返回一个自定义扩展的CQ码(支持自定义类型和参数)
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| type_name | string | CQ码类型名称 |
|
||||
| params | array | 参数 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | CQ码 |
|
||||
|
||||
|
||||
## decode
|
||||
|
||||
```php
|
||||
public function decode(int|string|Stringable $msg, bool $is_content): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
反转义字符串中的CQ码敏感符号
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| msg | int|string|Stringable | 字符串 |
|
||||
| is_content | bool | 如果是解码CQ码本体内容,则为false(默认),如果是参数内的字符串,则为true |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | 转义后的CQ码 |
|
||||
|
||||
|
||||
## replace
|
||||
|
||||
```php
|
||||
public function replace(int|string|Stringable $str): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
简单反转义替换CQ码的方括号
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| str | int|string|Stringable | 字符串 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | 字符串 |
|
||||
|
||||
|
||||
## escape
|
||||
|
||||
```php
|
||||
public function escape(int|string|Stringable $msg, bool $is_content): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
转义CQ码的特殊字符,同encode
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| msg | int|string|Stringable | 字符串 |
|
||||
| is_content | bool | 如果是转义CQ码本体内容,则为false(默认),如果是参数内的字符串,则为true |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | 转义后的CQ码 |
|
||||
|
||||
|
||||
## encode
|
||||
|
||||
```php
|
||||
public function encode(int|string|Stringable $msg, bool $is_content): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
转义CQ码的特殊字符
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| msg | int|string|Stringable | 字符串 |
|
||||
| is_content | bool | 如果是转义CQ码本体内容,则为false(默认),如果是参数内的字符串,则为true |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | 转义后的CQ码 |
|
||||
|
||||
|
||||
## removeCQ
|
||||
|
||||
```php
|
||||
public function removeCQ(string $msg): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
移除消息中所有的CQ码并返回移除CQ码后的消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| msg | string | 消息 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | 消息内容 |
|
||||
|
||||
|
||||
## getCQ
|
||||
|
||||
```php
|
||||
public function getCQ(string $msg, bool $is_object): null|array|CQObject
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取消息中第一个CQ码
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| msg | string | 消息内容 |
|
||||
| is_object | bool | 是否以对象形式返回,如果为False的话,返回数组形式(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| null|array|CQObject | 返回的CQ码(数组或对象) |
|
||||
|
||||
|
||||
## getAllCQ
|
||||
|
||||
```php
|
||||
public function getAllCQ(string $msg, bool $is_object): array|CQObject[]
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取消息中所有的CQ码
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| msg | string | 消息内容 |
|
||||
| is_object | bool | 是否以对象形式返回,如果为False的话,返回数组形式(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|CQObject[] | 返回的CQ码们(数组或对象) |
|
||||
130
docs/api/ZM/API/GoCqhttpAPIV11.md
Normal file
130
docs/api/ZM/API/GoCqhttpAPIV11.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# ZM\API\GoCqhttpAPIV11
|
||||
|
||||
## getGuildServiceProfile
|
||||
|
||||
```php
|
||||
public function getGuildServiceProfile(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取频道系统内BOT的资料
|
||||
响应字段:nickname, tiny_id, avatar_url
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGuildList
|
||||
|
||||
```php
|
||||
public function getGuildList(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取频道列表
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGuildMetaByGuest
|
||||
|
||||
```php
|
||||
public function getGuildMetaByGuest(int|string $guild_id): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
通过访客获取频道元数据
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| guild_id | int|string | 频道ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGuildChannelList
|
||||
|
||||
```php
|
||||
public function getGuildChannelList(int|string $guild_id, false $no_cache): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取子频道列表
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| guild_id | int|string | 频道ID |
|
||||
| no_cache | false | 禁用缓存(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGuildMembers
|
||||
|
||||
```php
|
||||
public function getGuildMembers(int|string $guild_id): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取频道成员列表
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| guild_id | int|string | 频道ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## sendGuildChannelMsg
|
||||
|
||||
```php
|
||||
public function sendGuildChannelMsg(int|string $guild_id, int|string $channel_id, string $message): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送信息到子频道
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| guild_id | int|string | 频道ID |
|
||||
| channel_id | int|string | 子频道ID |
|
||||
| message | string | 信息内容 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
984
docs/api/ZM/API/OneBotV11.md
Normal file
984
docs/api/ZM/API/OneBotV11.md
Normal file
@@ -0,0 +1,984 @@
|
||||
# ZM\API\OneBotV11
|
||||
|
||||
## get
|
||||
|
||||
```php
|
||||
public function get(int|string $robot_id): ZMRobot
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取机器人Action/API实例
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| robot_id | int|string | 机器人ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| ZMRobot | 机器人实例 |
|
||||
|
||||
|
||||
## getRandom
|
||||
|
||||
```php
|
||||
public function getRandom(): ZMRobot
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
随机获取一个连接到框架的机器人实例
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| ZMRobot | 机器人实例 |
|
||||
|
||||
|
||||
## getAllRobot
|
||||
|
||||
```php
|
||||
public function getAllRobot(): ZMRobot[]
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取所有机器人实例
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| ZMRobot[] | 机器人实例们 |
|
||||
|
||||
|
||||
## setCallback
|
||||
|
||||
```php
|
||||
public function setCallback(bool|Closure $callback): OneBotV11
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
设置回调或启用协程等待API回包
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| callback | bool|Closure | 是否开启协程或设置异步回调函数,如果为true,则协程等待结果,如果为false,则异步执行并不等待结果,如果为回调函数,则异步执行且调用回调 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| OneBotV11 | 返回本身 |
|
||||
|
||||
|
||||
## setPrefix
|
||||
|
||||
```php
|
||||
public function setPrefix(int $prefix): OneBotV11
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
设置API调用类型后缀
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| prefix | int | 设置后缀类型,API_NORMAL为不加后缀,API_ASYNC为异步调用,API_RATE_LIMITED为加后缀并且限制调用频率 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| OneBotV11 | 返回本身 |
|
||||
|
||||
|
||||
## sendPrivateMsg
|
||||
|
||||
```php
|
||||
public function sendPrivateMsg(int|string $user_id, string $message, bool $auto_escape): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送私聊消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| user_id | int|string | 用户ID |
|
||||
| message | string | 消息内容 |
|
||||
| auto_escape | bool | 是否自动转义(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## sendGroupMsg
|
||||
|
||||
```php
|
||||
public function sendGroupMsg(int|string $group_id, string $message, bool $auto_escape): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送群消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群组ID |
|
||||
| message | string | 消息内容 |
|
||||
| auto_escape | bool | 是否自动转义(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## sendMsg
|
||||
|
||||
```php
|
||||
public function sendMsg(string $message_type, int|string $target_id, string $message, bool $auto_escape): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| message_type | string | 消息类型 |
|
||||
| target_id | int|string | 目标ID |
|
||||
| message | string | 消息内容 |
|
||||
| auto_escape | bool | 是否自动转义(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## deleteMsg
|
||||
|
||||
```php
|
||||
public function deleteMsg(int|string $message_id): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
撤回消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| message_id | int|string | 消息ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getMsg
|
||||
|
||||
```php
|
||||
public function getMsg(int|string $message_id): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| message_id | int|string | 消息ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getForwardMsg
|
||||
|
||||
```php
|
||||
public function getForwardMsg(int|string $id): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取合并转发消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| id | int|string | ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## sendLike
|
||||
|
||||
```php
|
||||
public function sendLike(int|string $user_id, int $times): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
发送好友赞
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| user_id | int|string | 用户ID |
|
||||
| times | int | 时间 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupKick
|
||||
|
||||
```php
|
||||
public function setGroupKick(int|string $group_id, int|string $user_id, bool $reject_add_request): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
群组踢人
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| user_id | int|string | 用户ID |
|
||||
| reject_add_request | bool | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupBan
|
||||
|
||||
```php
|
||||
public function setGroupBan(int|string $group_id, int|string $user_id, int $duration): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
群组单人禁言
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| user_id | int|string | 用户ID |
|
||||
| duration | int | 禁言时长 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupAnonymousBan
|
||||
|
||||
```php
|
||||
public function setGroupAnonymousBan(int|string $group_id, array|int|string $anonymous_or_flag, int $duration): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
群组匿名用户禁言
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| anonymous_or_flag | array|int|string | 匿名禁言Flag或匿名用户对象 |
|
||||
| duration | int | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupWholeBan
|
||||
|
||||
```php
|
||||
public function setGroupWholeBan(int|string $group_id, bool $enable): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
群组全员禁言
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| enable | bool | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupAdmin
|
||||
|
||||
```php
|
||||
public function setGroupAdmin(int|string $group_id, int|string $user_id, bool $enable): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
群组设置管理员
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| user_id | int|string | 用户ID |
|
||||
| enable | bool | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupAnonymous
|
||||
|
||||
```php
|
||||
public function setGroupAnonymous(int|string $group_id, bool $enable): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
群组匿名
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| enable | bool | 是否启用(默认为true) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupCard
|
||||
|
||||
```php
|
||||
public function setGroupCard(int|string $group_id, int|string $user_id, string $card): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
设置群名片(群备注)
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| user_id | int|string | 用户ID |
|
||||
| card | string | 名片内容(默认为空) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupName
|
||||
|
||||
```php
|
||||
public function setGroupName(int|string $group_id, string $group_name): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
设置群名
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| group_name | string | 群名 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupLeave
|
||||
|
||||
```php
|
||||
public function setGroupLeave(int|string $group_id, bool $is_dismiss): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
退出群组
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| is_dismiss | bool | 是否解散(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupSpecialTitle
|
||||
|
||||
```php
|
||||
public function setGroupSpecialTitle(int|string $group_id, int|string $user_id, string $special_title, int $duration): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
设置群组专属头衔
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| user_id | int|string | 用户ID |
|
||||
| special_title | string | 专属头衔内容 |
|
||||
| duration | int | 持续时间(默认为-1,永久) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setFriendAddRequest
|
||||
|
||||
```php
|
||||
public function setFriendAddRequest(array|int|string $flag, bool $approve, string $remark): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
处理加好友请求
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| flag | array|int|string | 处理加好友请求的flag |
|
||||
| approve | bool | 是否同意(默认为true) |
|
||||
| remark | string | 设置昵称(默认不设置) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setGroupAddRequest
|
||||
|
||||
```php
|
||||
public function setGroupAddRequest(array|int|string $flag, string $sub_type, bool $approve, string $reason): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
处理加群请求/邀请
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| flag | array|int|string | 处理加群请求的flag |
|
||||
| sub_type | string | 处理请求类型(包含add和invite) |
|
||||
| approve | bool | 是否同意(默认为true) |
|
||||
| reason | string | 拒绝理由(仅在拒绝时有效,默认为空) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getLoginInfo
|
||||
|
||||
```php
|
||||
public function getLoginInfo(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取登录号信息
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getStrangerInfo
|
||||
|
||||
```php
|
||||
public function getStrangerInfo(int|string $user_id, bool $no_cache): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取陌生人信息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| user_id | int|string | 用户ID |
|
||||
| no_cache | bool | 是否不使用缓存(默认为false) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getFriendList
|
||||
|
||||
```php
|
||||
public function getFriendList(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取好友列表
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGroupInfo
|
||||
|
||||
```php
|
||||
public function getGroupInfo(int|string $group_id, bool $no_cache): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取群信息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| no_cache | bool | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGroupList
|
||||
|
||||
```php
|
||||
public function getGroupList(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取群列表
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGroupMemberInfo
|
||||
|
||||
```php
|
||||
public function getGroupMemberInfo(int|string $group_id, int|string $user_id, bool $no_cache): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取群成员信息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| user_id | int|string | 用户ID |
|
||||
| no_cache | bool | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGroupMemberList
|
||||
|
||||
```php
|
||||
public function getGroupMemberList(int|string $group_id): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取群成员列表
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getGroupHonorInfo
|
||||
|
||||
```php
|
||||
public function getGroupHonorInfo(int|string $group_id, string $type): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取群荣誉信息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| group_id | int|string | 群ID |
|
||||
| type | string | 荣誉类型 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getCsrfToken
|
||||
|
||||
```php
|
||||
public function getCsrfToken(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取 CSRF Token
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getCredentials
|
||||
|
||||
```php
|
||||
public function getCredentials(string $domain): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取 QQ 相关接口凭证
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| domain | string | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getRecord
|
||||
|
||||
```php
|
||||
public function getRecord(string $file, string $out_format): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取语音
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| file | string | 文件 |
|
||||
| out_format | string | 输出格式 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getImage
|
||||
|
||||
```php
|
||||
public function getImage(string $file): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取图片
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| file | string | 文件 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## canSendImage
|
||||
|
||||
```php
|
||||
public function canSendImage(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
检查是否可以发送图片
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## canSendRecord
|
||||
|
||||
```php
|
||||
public function canSendRecord(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
检查是否可以发送语音
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getStatus
|
||||
|
||||
```php
|
||||
public function getStatus(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取运行状态
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getVersionInfo
|
||||
|
||||
```php
|
||||
public function getVersionInfo(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取版本信息
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## setRestart
|
||||
|
||||
```php
|
||||
public function setRestart(int $delay): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
重启 OneBot 实现
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| delay | int | 延迟时间(毫秒,默认为0) |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## cleanCache
|
||||
|
||||
```php
|
||||
public function cleanCache(): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
清理缓存
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
|
||||
|
||||
## getExtendedAPI
|
||||
|
||||
```php
|
||||
public function getExtendedAPI(string $package_name): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取内置支持的扩展API对象
|
||||
现支持 go-cqhttp 的扩展API
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| package_name | string | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | 返回包的操作对象 |
|
||||
|
||||
|
||||
## callExtendedAPI
|
||||
|
||||
```php
|
||||
public function callExtendedAPI(string $action, array $params): array|bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| action | string | 动作(API)名称 |
|
||||
| params | array | 参数 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array|bool | 返回API调用结果(数组)或异步API调用状态(bool) |
|
||||
117
docs/api/ZM/API/Proxies/Bot/AbstractBotProxy.md
Normal file
117
docs/api/ZM/API/Proxies/Bot/AbstractBotProxy.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# ZM\API\Proxies\Bot\AbstractBotProxy
|
||||
|
||||
## __construct
|
||||
|
||||
```php
|
||||
public function __construct(AbstractBotProxy|ZMRobot $bot): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
构造函数
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| bot | AbstractBotProxy|ZMRobot | 调用此代理的机器人实例 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## __call
|
||||
|
||||
```php
|
||||
public function __call(string $name, array $arguments): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
在传入的机器人实例上调用方法
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| name | string | 方法名 |
|
||||
| arguments | array | 参数 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## __get
|
||||
|
||||
```php
|
||||
public function __get(string $name): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取传入的机器人实例的属性
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| name | string | 属性名 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## __set
|
||||
|
||||
```php
|
||||
public function __set(string $name, mixed $value): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
设置传入的机器人实例的属性
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| name | string | 属性名 |
|
||||
| value | mixed | 属性值 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## __isset
|
||||
|
||||
```php
|
||||
public function __isset(string $name): bool
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
判断传入的机器人实例的属性是否存在
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| name | string | 属性名 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| bool | |
|
||||
24
docs/api/ZM/API/Proxies/Bot/AllBotsProxy.md
Normal file
24
docs/api/ZM/API/Proxies/Bot/AllBotsProxy.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# ZM\API\Proxies\Bot\AllBotsProxy
|
||||
|
||||
## __call
|
||||
|
||||
```php
|
||||
public function __call(string $name, array $arguments): array<mixed>
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
在所有机器人实例上调用方法
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| name | string | 方法名 |
|
||||
| arguments | array | 参数 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array<mixed> | 返回一个包含所有执行结果的数组,键名为机器人ID |
|
||||
24
docs/api/ZM/API/Proxies/Bot/AllGroupsProxy.md
Normal file
24
docs/api/ZM/API/Proxies/Bot/AllGroupsProxy.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# ZM\API\Proxies\Bot\AllGroupsProxy
|
||||
|
||||
## __call
|
||||
|
||||
```php
|
||||
public function __call(string $name, array $arguments): array<mixed>
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
在传入的机器人实例上调用方法
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| name | string | 方法名 |
|
||||
| arguments | array | 参数 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array<mixed> | 返回一个包含所有执行结果的数组,键名为群号 |
|
||||
48
docs/api/ZM/API/TuringAPI.md
Normal file
48
docs/api/ZM/API/TuringAPI.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# ZM\API\TuringAPI
|
||||
|
||||
## getTuringMsg
|
||||
|
||||
```php
|
||||
public function getTuringMsg(string $msg, int|string $user_id, string $api): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
请求图灵API,返回图灵的消息
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| msg | string | 消息 |
|
||||
| user_id | int|string | 用户ID |
|
||||
| api | string | API Key |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | 图灵的回复 |
|
||||
|
||||
|
||||
## getResultStatus
|
||||
|
||||
```php
|
||||
public function getResultStatus(array $r): bool|string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| r | array | 数据API回包 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| bool|string | 错误消息或成功鸥鸟 |
|
||||
46
docs/api/ZM/API/ZMRobot.md
Normal file
46
docs/api/ZM/API/ZMRobot.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# ZM\API\ZMRobot
|
||||
|
||||
## all
|
||||
|
||||
```php
|
||||
public function all(ZM\API\Proxies\Bot\AbstractBotProxy $proxy): ZM\API\Proxies\Bot\AllBotsProxy
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取一个会在所有机器人实例上执行的代理
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| proxy | ZM\API\Proxies\Bot\AbstractBotProxy | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| ZM\API\Proxies\Bot\AllBotsProxy | |
|
||||
|
||||
|
||||
## allGroups
|
||||
|
||||
```php
|
||||
public function allGroups(ZM\API\Proxies\Bot\AbstractBotProxy $proxy): ZM\API\Proxies\Bot\AllGroupsProxy
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取一个会在所有群上执行的代理
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| proxy | ZM\API\Proxies\Bot\AbstractBotProxy | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| ZM\API\Proxies\Bot\AllGroupsProxy | |
|
||||
1
docs/api/ZM/Annotation/AnnotationBase.md
Normal file
1
docs/api/ZM/Annotation/AnnotationBase.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\AnnotationBase
|
||||
100
docs/api/ZM/Annotation/AnnotationParser.md
Normal file
100
docs/api/ZM/Annotation/AnnotationParser.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# ZM\Annotation\AnnotationParser
|
||||
|
||||
## __construct
|
||||
|
||||
```php
|
||||
public function __construct(): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
AnnotationParser constructor.
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## registerMods
|
||||
|
||||
```php
|
||||
public function registerMods(): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
注册各个模块类的注解和模块level的排序
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## addRegisterPath
|
||||
|
||||
```php
|
||||
public function addRegisterPath(string $path, string $indoor_name): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| path | string | 注册解析注解的路径 |
|
||||
| indoor_name | string | 起始命名空间的名称 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## sortByLevel
|
||||
|
||||
```php
|
||||
public function sortByLevel(array $events, string $class_name, string $prefix): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| events | array | 需要排序的 |
|
||||
| class_name | string | 排序的类名 |
|
||||
| prefix | string | 前缀 |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## verifyMiddlewares
|
||||
|
||||
```php
|
||||
public function verifyMiddlewares(): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
1
docs/api/ZM/Annotation/CQ/CQAPIResponse.md
Normal file
1
docs/api/ZM/Annotation/CQ/CQAPIResponse.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\CQ\CQAPIResponse
|
||||
39
docs/api/ZM/Annotation/CQ/CQAfter.md
Normal file
39
docs/api/ZM/Annotation/CQ/CQAfter.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# ZM\Annotation\CQ\CQAfter
|
||||
|
||||
## getLevel
|
||||
|
||||
```php
|
||||
public function getLevel(): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## setLevel
|
||||
|
||||
```php
|
||||
public function setLevel(mixed $level): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| level | mixed | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
39
docs/api/ZM/Annotation/CQ/CQBefore.md
Normal file
39
docs/api/ZM/Annotation/CQ/CQBefore.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# ZM\Annotation\CQ\CQBefore
|
||||
|
||||
## getLevel
|
||||
|
||||
```php
|
||||
public function getLevel(): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## setLevel
|
||||
|
||||
```php
|
||||
public function setLevel(mixed $level): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| level | mixed | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
22
docs/api/ZM/Annotation/CQ/CQCommand.md
Normal file
22
docs/api/ZM/Annotation/CQ/CQCommand.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# ZM\Annotation\CQ\CQCommand
|
||||
|
||||
## setLevel
|
||||
|
||||
```php
|
||||
public function setLevel(int $level): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| level | int | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
1
docs/api/ZM/Annotation/CQ/CQMessage.md
Normal file
1
docs/api/ZM/Annotation/CQ/CQMessage.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\CQ\CQMessage
|
||||
39
docs/api/ZM/Annotation/CQ/CQMetaEvent.md
Normal file
39
docs/api/ZM/Annotation/CQ/CQMetaEvent.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# ZM\Annotation\CQ\CQMetaEvent
|
||||
|
||||
## getLevel
|
||||
|
||||
```php
|
||||
public function getLevel(): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
|
||||
|
||||
## setLevel
|
||||
|
||||
```php
|
||||
public function setLevel(int $level): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| level | int | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
22
docs/api/ZM/Annotation/CQ/CQNotice.md
Normal file
22
docs/api/ZM/Annotation/CQ/CQNotice.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# ZM\Annotation\CQ\CQNotice
|
||||
|
||||
## setLevel
|
||||
|
||||
```php
|
||||
public function setLevel(int $level): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| level | int | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
22
docs/api/ZM/Annotation/CQ/CQRequest.md
Normal file
22
docs/api/ZM/Annotation/CQ/CQRequest.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# ZM\Annotation\CQ\CQRequest
|
||||
|
||||
## setLevel
|
||||
|
||||
```php
|
||||
public function setLevel(int $level): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| level | int | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
1
docs/api/ZM/Annotation/Command/TerminalCommand.md
Normal file
1
docs/api/ZM/Annotation/Command/TerminalCommand.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Command\TerminalCommand
|
||||
61
docs/api/ZM/Annotation/Cron/Cron.md
Normal file
61
docs/api/ZM/Annotation/Cron/Cron.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# ZM\Annotation\Cron\Cron
|
||||
|
||||
## setStatus
|
||||
|
||||
```php
|
||||
public function setStatus(int $status): void
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| status | int | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| void | |
|
||||
|
||||
|
||||
## getRecordNextTime
|
||||
|
||||
```php
|
||||
public function getRecordNextTime(): int
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| int | |
|
||||
|
||||
|
||||
## setRecordNextTime
|
||||
|
||||
```php
|
||||
public function setRecordNextTime(int $record_next_time): void
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| record_next_time | int | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| void | |
|
||||
1
docs/api/ZM/Annotation/Http/Controller.md
Normal file
1
docs/api/ZM/Annotation/Http/Controller.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\Controller
|
||||
1
docs/api/ZM/Annotation/Http/HandleAfter.md
Normal file
1
docs/api/ZM/Annotation/Http/HandleAfter.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\HandleAfter
|
||||
1
docs/api/ZM/Annotation/Http/HandleBefore.md
Normal file
1
docs/api/ZM/Annotation/Http/HandleBefore.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\HandleBefore
|
||||
1
docs/api/ZM/Annotation/Http/HandleException.md
Normal file
1
docs/api/ZM/Annotation/Http/HandleException.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\HandleException
|
||||
1
docs/api/ZM/Annotation/Http/Middleware.md
Normal file
1
docs/api/ZM/Annotation/Http/Middleware.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\Middleware
|
||||
1
docs/api/ZM/Annotation/Http/MiddlewareClass.md
Normal file
1
docs/api/ZM/Annotation/Http/MiddlewareClass.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\MiddlewareClass
|
||||
1
docs/api/ZM/Annotation/Http/RequestMapping.md
Normal file
1
docs/api/ZM/Annotation/Http/RequestMapping.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\RequestMapping
|
||||
1
docs/api/ZM/Annotation/Http/RequestMethod.md
Normal file
1
docs/api/ZM/Annotation/Http/RequestMethod.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Http\RequestMethod
|
||||
1
docs/api/ZM/Annotation/Module/Closed.md
Normal file
1
docs/api/ZM/Annotation/Module/Closed.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Module\Closed
|
||||
1
docs/api/ZM/Annotation/Swoole/OnCloseEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnCloseEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnCloseEvent
|
||||
1
docs/api/ZM/Annotation/Swoole/OnManagerStartEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnManagerStartEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnManagerStartEvent
|
||||
1
docs/api/ZM/Annotation/Swoole/OnMessageEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnMessageEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnMessageEvent
|
||||
1
docs/api/ZM/Annotation/Swoole/OnOpenEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnOpenEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnOpenEvent
|
||||
1
docs/api/ZM/Annotation/Swoole/OnPipeMessageEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnPipeMessageEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnPipeMessageEvent
|
||||
1
docs/api/ZM/Annotation/Swoole/OnRequestEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnRequestEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnRequestEvent
|
||||
1
docs/api/ZM/Annotation/Swoole/OnSave.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnSave.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnSave
|
||||
1
docs/api/ZM/Annotation/Swoole/OnSetup.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnSetup.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnSetup
|
||||
1
docs/api/ZM/Annotation/Swoole/OnStart.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnStart.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnStart
|
||||
1
docs/api/ZM/Annotation/Swoole/OnSwooleEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnSwooleEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnSwooleEvent
|
||||
23
docs/api/ZM/Annotation/Swoole/OnSwooleEventBase.md
Normal file
23
docs/api/ZM/Annotation/Swoole/OnSwooleEventBase.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# ZM\Annotation\Swoole\OnSwooleEventBase
|
||||
|
||||
## setLevel
|
||||
|
||||
```php
|
||||
public function setLevel(int $level): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| level | int | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
17
docs/api/ZM/Annotation/Swoole/OnTask.md
Normal file
17
docs/api/ZM/Annotation/Swoole/OnTask.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# ZM\Annotation\Swoole\OnTask
|
||||
|
||||
## getRule
|
||||
|
||||
```php
|
||||
public function getRule(): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
1
docs/api/ZM/Annotation/Swoole/OnTaskEvent.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnTaskEvent.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnTaskEvent
|
||||
1
docs/api/ZM/Annotation/Swoole/OnTick.md
Normal file
1
docs/api/ZM/Annotation/Swoole/OnTick.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\OnTick
|
||||
1
docs/api/ZM/Annotation/Swoole/SwooleHandler.md
Normal file
1
docs/api/ZM/Annotation/Swoole/SwooleHandler.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Annotation\Swoole\SwooleHandler
|
||||
1
docs/api/ZM/Command/BuildCommand.md
Normal file
1
docs/api/ZM/Command/BuildCommand.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Command\BuildCommand
|
||||
25
docs/api/ZM/Command/CheckConfigCommand.md
Normal file
25
docs/api/ZM/Command/CheckConfigCommand.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# ZM\Command\CheckConfigCommand
|
||||
|
||||
## check
|
||||
|
||||
```php
|
||||
public function check(mixed $remote, mixed $local, Symfony\Component\Console\Output\OutputInterface $out): mixed
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
作者很懒,什么也没有说
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| remote | mixed | |
|
||||
| local | mixed | |
|
||||
| out | Symfony\Component\Console\Output\OutputInterface | |
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| mixed | |
|
||||
1
docs/api/ZM/Command/Daemon/DaemonCommand.md
Normal file
1
docs/api/ZM/Command/Daemon/DaemonCommand.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Command\Daemon\DaemonCommand
|
||||
1
docs/api/ZM/Command/Daemon/DaemonReloadCommand.md
Normal file
1
docs/api/ZM/Command/Daemon/DaemonReloadCommand.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Command\Daemon\DaemonReloadCommand
|
||||
1
docs/api/ZM/Command/Daemon/DaemonStatusCommand.md
Normal file
1
docs/api/ZM/Command/Daemon/DaemonStatusCommand.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Command\Daemon\DaemonStatusCommand
|
||||
1
docs/api/ZM/Command/Daemon/DaemonStopCommand.md
Normal file
1
docs/api/ZM/Command/Daemon/DaemonStopCommand.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Command\Daemon\DaemonStopCommand
|
||||
91
docs/api/ZM/Command/Generate/APIDocsGenerateCommand.md
Normal file
91
docs/api/ZM/Command/Generate/APIDocsGenerateCommand.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# ZM\Command\Generate\APIDocsGenerateCommand
|
||||
|
||||
## configure
|
||||
|
||||
```php
|
||||
public function configure(): void
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
Configures the current command.
|
||||
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| void | |
|
||||
|
||||
|
||||
## execute
|
||||
|
||||
```php
|
||||
public function execute(Symfony\Component\Console\Input\InputInterface $input, Symfony\Component\Console\Output\OutputInterface $output): int
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
Executes the current command.
|
||||
This method is not abstract because you can use this class
|
||||
as a concrete class. In this case, instead of defining the
|
||||
execute() method, you set the code to execute by passing
|
||||
a Closure to the setCode() method.
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| input | Symfony\Component\Console\Input\InputInterface | |
|
||||
| output | Symfony\Component\Console\Output\OutputInterface | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| int | 0 if everything went fine, or an exit code * |
|
||||
|
||||
|
||||
## getClassMetas
|
||||
|
||||
```php
|
||||
public function getClassMetas(string $class_name, Jasny\PhpdocParser\PhpdocParser $parser): array
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
获取类的元数据
|
||||
包括类的注释、方法的注释、参数、返回值等
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| class_name | string | |
|
||||
| parser | Jasny\PhpdocParser\PhpdocParser | |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| array | |
|
||||
|
||||
|
||||
## convertMetaToMarkdown
|
||||
|
||||
```php
|
||||
public function convertMetaToMarkdown(string $method, array $meta): string
|
||||
```
|
||||
|
||||
### 描述
|
||||
|
||||
将方法的元数据转换为 Markdown 格式
|
||||
|
||||
### 参数
|
||||
|
||||
| 名称 | 类型 | 描述 |
|
||||
| -------- | ---- | ----------- |
|
||||
| method | string | 方法名 |
|
||||
| meta | array | 元数据 |
|
||||
### 返回
|
||||
|
||||
| 类型 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| string | |
|
||||
1
docs/api/ZM/Command/Generate/SystemdGenerateCommand.md
Normal file
1
docs/api/ZM/Command/Generate/SystemdGenerateCommand.md
Normal file
@@ -0,0 +1 @@
|
||||
# ZM\Command\Generate\SystemdGenerateCommand
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user