Compare commits

...

137 Commits

Author SHA1 Message Date
as2252258 22560d77d6 Revert "改名"
This reverts commit fdf58326
2022-01-10 11:39:56 +08:00
as2252258 483c898f51 1 2022-01-10 02:13:11 +08:00
as2252258 1fa651c587 1 2022-01-10 02:10:37 +08:00
as2252258 f7ca56a9b0 1 2022-01-09 17:56:47 +08:00
as2252258 4fa5c23c10 1 2022-01-09 16:07:58 +08:00
as2252258 f46af653f2 1 2022-01-09 14:33:33 +08:00
as2252258 5e02a79bf0 e 2022-01-09 03:50:38 +08:00
as2252258 08dc3e262b 1 2022-01-09 03:46:42 +08:00
as2252258 8c5e52940f 1 2022-01-09 02:44:09 +08:00
as2252258 4dbcacdd1f Revert "改名"
This reverts commit fdf58326
2022-01-08 19:11:23 +08:00
as2252258 97cd1a0ebf Revert "改名"
This reverts commit fdf58326
2022-01-08 18:49:08 +08:00
as2252258 7165a67294 Revert "改名"
This reverts commit fdf58326
2022-01-08 18:10:52 +08:00
as2252258 4bc7451424 Revert "改名"
This reverts commit fdf58326
2022-01-08 18:10:41 +08:00
as2252258 d7d0f685dc Revert "改名"
This reverts commit fdf58326
2022-01-08 10:07:19 +08:00
as2252258 8ee7d30d6a Revert "改名"
This reverts commit fdf58326
2022-01-07 19:01:00 +08:00
as2252258 224009e7e6 Revert "改名"
This reverts commit fdf58326
2022-01-07 19:00:45 +08:00
as2252258 b4551ae2fd Revert "改名"
This reverts commit fdf58326
2022-01-07 18:16:30 +08:00
as2252258 5ca94925e3 Revert "改名"
This reverts commit fdf58326
2022-01-07 18:05:17 +08:00
as2252258 0afa8fc400 Revert "改名"
This reverts commit fdf58326
2022-01-07 17:59:37 +08:00
as2252258 842220e4de Revert "改名"
This reverts commit fdf58326
2022-01-07 17:57:27 +08:00
as2252258 c9726e5778 Revert "改名"
This reverts commit fdf58326
2022-01-07 14:38:36 +08:00
as2252258 f867f4be9e Revert "改名"
This reverts commit fdf58326
2022-01-06 19:05:15 +08:00
as2252258 45319c3733 Revert "改名"
This reverts commit fdf58326
2022-01-04 17:27:37 +08:00
as2252258 06c9459f14 Revert "改名"
This reverts commit fdf58326
2022-01-04 16:25:03 +08:00
as2252258 5fd2abcb69 Revert "改名"
This reverts commit fdf58326
2022-01-04 16:22:37 +08:00
as2252258 58a3d91df3 Merge remote-tracking branch 'origin/master' 2022-01-04 16:05:08 +08:00
as2252258 c61842402a Revert "改名"
This reverts commit fdf58326
2022-01-04 16:04:22 +08:00
as2252258 623bae9e97 1 2022-01-04 00:07:26 +08:00
as2252258 12610c218c 1 2022-01-04 00:07:14 +08:00
as2252258 c3ca24884e Revert "改名"
This reverts commit fdf58326
2021-12-31 16:47:17 +08:00
as2252258 02c14874a2 Revert "改名"
This reverts commit fdf58326
2021-12-31 16:46:13 +08:00
as2252258 6eff48e22f Revert "改名"
This reverts commit fdf58326
2021-12-30 18:10:51 +08:00
as2252258 6c46a54d4b Revert "改名"
This reverts commit fdf58326
2021-12-28 17:54:51 +08:00
as2252258 03287cfd65 Revert "改名"
This reverts commit fdf58326
2021-12-28 14:16:45 +08:00
as2252258 93ce4c16b6 Revert "改名"
This reverts commit fdf58326
2021-12-27 15:24:29 +08:00
as2252258 4b92edd40f 1 2021-12-24 01:19:43 +08:00
as2252258 a76c81df8e 改名 2021-12-23 18:36:14 +08:00
as2252258 aa59caad07 改名 2021-12-23 18:22:27 +08:00
as2252258 6fd8a5dd34 1 2021-12-22 03:29:27 +08:00
as2252258 9ca53a73ce 1 2021-12-22 03:29:14 +08:00
as2252258 d904e78864 1 2021-12-18 03:27:14 +08:00
as2252258 0d64ef7ac4 1 2021-12-17 04:57:46 +08:00
as2252258 154d9d74d6 1 2021-12-17 04:43:20 +08:00
as2252258 2c61abff01 1 2021-12-17 04:41:00 +08:00
as2252258 b4ce762cf3 1 2021-12-17 04:26:54 +08:00
as2252258 4b3c2234af 1 2021-12-17 04:24:40 +08:00
as2252258 7ee78a9642 1 2021-12-17 04:24:01 +08:00
as2252258 f9838f781d 1 2021-12-17 04:23:12 +08:00
as2252258 848416af4f 1 2021-12-17 04:22:13 +08:00
as2252258 0216e761be 1 2021-12-17 04:17:53 +08:00
as2252258 acf6631c5c 1 2021-12-17 04:15:59 +08:00
as2252258 64e4307a57 1 2021-12-12 06:37:52 +08:00
as2252258 ab672127e6 1 2021-12-12 02:46:30 +08:00
as2252258 6e5b545a1e 1 2021-12-12 02:45:39 +08:00
as2252258 8229395e6d 1 2021-12-12 02:41:31 +08:00
as2252258 d5d2b04321 1 2021-12-11 17:56:35 +08:00
as2252258 ce9c184c83 1 2021-12-11 17:40:16 +08:00
as2252258 620de34559 1 2021-12-11 17:38:53 +08:00
as2252258 b01c71ea5e 1 2021-12-11 17:38:15 +08:00
as2252258 90e1f7eb29 1 2021-12-11 17:35:44 +08:00
as2252258 f3ad09ef66 1 2021-12-11 17:34:05 +08:00
as2252258 dfccb8816c 1 2021-12-11 17:32:28 +08:00
as2252258 1670ff3fef 1 2021-12-11 05:33:46 +08:00
as2252258 8870a7ca27 1 2021-12-11 05:33:00 +08:00
as2252258 ebb7ac9673 改名 2021-12-09 17:01:18 +08:00
as2252258 5aad8d2001 改名 2021-12-08 11:45:19 +08:00
as2252258 80713788c9 改名 2021-12-08 11:39:57 +08:00
as2252258 9f36acbbca 改名 2021-12-08 11:32:32 +08:00
as2252258 044d213a69 改名 2021-12-07 16:44:12 +08:00
as2252258 e5fe525f82 改名 2021-12-07 16:02:07 +08:00
as2252258 39e4e52908 改名 2021-12-07 16:00:52 +08:00
as2252258 f62014ff34 改名 2021-12-07 15:59:13 +08:00
as2252258 7935e6a6a3 改名 2021-12-07 15:53:56 +08:00
as2252258 d2acd50352 改名 2021-12-06 18:07:33 +08:00
as2252258 d02337ec22 改名 2021-12-06 17:58:11 +08:00
as2252258 57f12b6701 改名 2021-12-06 17:22:26 +08:00
as2252258 d500fd21ce 改名 2021-12-06 16:14:48 +08:00
as2252258 30d7b8684e 改名 2021-12-06 16:13:52 +08:00
as2252258 d8eb4d4e45 改名 2021-12-06 16:03:39 +08:00
as2252258 7004c5c0f8 改名 2021-12-06 15:54:31 +08:00
as2252258 81e55ecdf1 改名 2021-12-06 15:52:05 +08:00
as2252258 20adc186d4 改名 2021-12-06 15:51:29 +08:00
as2252258 8c16d9f4b3 改名 2021-12-06 15:48:57 +08:00
as2252258 b3e06a680a 改名 2021-12-06 15:47:12 +08:00
as2252258 3176443e5c 改名 2021-12-06 15:39:35 +08:00
as2252258 83962fa3ba 改名 2021-12-06 14:49:47 +08:00
as2252258 5475f2cd51 改名 2021-12-06 14:45:12 +08:00
as2252258 30212c0b86 改名 2021-12-06 14:44:18 +08:00
as2252258 4731463897 改名 2021-12-06 14:43:46 +08:00
as2252258 87e901f5b1 改名 2021-12-06 14:42:54 +08:00
as2252258 66f87b6da4 改名 2021-12-06 14:41:05 +08:00
as2252258 0007242b70 改名 2021-12-06 14:40:18 +08:00
as2252258 8653e6914b 改名 2021-12-06 14:39:03 +08:00
as2252258 816fec8ef4 改名 2021-12-06 14:38:17 +08:00
as2252258 b0ef09fd35 改名 2021-12-06 14:38:06 +08:00
as2252258 f7a2d6f30e 改名 2021-12-06 14:32:04 +08:00
as2252258 2950ba8fd5 改名 2021-12-06 14:24:41 +08:00
as2252258 2de5c82a73 改名 2021-12-06 14:22:08 +08:00
as2252258 758c4e7d5b 改名 2021-12-06 14:12:03 +08:00
as2252258 33f045aec7 改名 2021-12-06 13:49:01 +08:00
as2252258 35189de442 改名 2021-12-06 11:44:01 +08:00
as2252258 34e7fc0392 改名 2021-12-03 18:40:27 +08:00
as2252258 a3ce9f52ba 改名 2021-12-03 18:22:26 +08:00
as2252258 6e7da1b0ed 改名 2021-12-03 17:40:21 +08:00
as2252258 a6e0b5c1a2 改名 2021-12-03 16:24:44 +08:00
as2252258 13ab14f965 改名 2021-12-03 15:42:05 +08:00
as2252258 6729094f63 改名 2021-12-03 15:35:16 +08:00
as2252258 e1aeb17a5a 改名 2021-12-03 14:46:38 +08:00
as2252258 b9e20051ef 改名 2021-12-02 14:06:57 +08:00
as2252258 4ab6332176 改名 2021-12-01 19:05:10 +08:00
as2252258 abe2dad521 改名 2021-12-01 19:05:00 +08:00
as2252258 b0f70a13da 改名 2021-12-01 15:16:08 +08:00
as2252258 1e8aca91dd 改名 2021-12-01 14:08:09 +08:00
as2252258 b4ac5c4758 改名 2021-11-30 19:04:29 +08:00
as2252258 d161477957 改名 2021-11-30 19:04:16 +08:00
as2252258 a26b99dd1e 改名 2021-11-30 18:33:22 +08:00
as2252258 86e4a92ab0 改名 2021-11-30 18:31:41 +08:00
as2252258 ea425bb82d 改名 2021-11-30 18:30:15 +08:00
as2252258 ad0154d319 改名 2021-11-30 18:29:10 +08:00
as2252258 edb70d2b9b 改名 2021-11-30 18:26:23 +08:00
as2252258 9f3355cab4 改名 2021-11-30 18:23:56 +08:00
as2252258 4107b5bb07 改名 2021-11-30 15:48:18 +08:00
as2252258 048960c572 改名 2021-11-30 15:14:42 +08:00
as2252258 b826e1f594 改名 2021-11-30 15:10:01 +08:00
as2252258 e5b57cbcdb 改名 2021-11-30 14:59:51 +08:00
as2252258 2870a64792 改名 2021-11-30 14:32:56 +08:00
as2252258 4d1587bc8d 改名 2021-11-29 14:35:09 +08:00
as2252258 24b69507b2 改名 2021-11-29 11:44:03 +08:00
as2252258 8b45c90a04 1 2021-11-28 19:37:07 +08:00
as2252258 95ae1fe999 1 2021-11-27 17:58:17 +08:00
as2252258 9668830ee2 1 2021-11-27 17:45:39 +08:00
as2252258 f26539c41f 1 2021-11-27 17:43:29 +08:00
as2252258 3ead688d5f Merge remote-tracking branch 'origin/master' 2021-11-26 11:28:37 +08:00
as2252258 157c233ed6 改名 2021-11-26 11:27:55 +08:00
as2252258 40b4c2a4c9 1 2021-11-24 23:46:26 +08:00
as2252258 a7db58d7e4 改名 2021-11-24 17:07:35 +08:00
as2252258 87e4bfdbec 改名 2021-11-24 17:07:13 +08:00
119 changed files with 12703 additions and 12342 deletions
+9 -9
View File
@@ -1,9 +1,9 @@
### 該問題是如何引起的? ### 該問題是如何引起的?
### 重現步驟 ### 重現步驟
### 報錯信息 ### 報錯信息
+12 -12
View File
@@ -1,12 +1,12 @@
### 該Pull Request關聯的Issue ### 該Pull Request關聯的Issue
### 修改描述 ### 修改描述
### 測試用例 ### 測試用例
### 修復效果的截屏 ### 修復效果的截屏
+37 -37
View File
@@ -1,37 +1,37 @@
# Created by .ignore support plugin (hsz.mobi) # Created by .ignore support plugin (hsz.mobi)
### Yii template ### Yii template
assets/* assets/*
!assets/.gitignore !assets/.gitignore
protected/runtime/* protected/runtime/*
!protected/runtime/.gitignore !protected/runtime/.gitignore
protected/data/*.db protected/data/*.db
themes/classic/views/ themes/classic/views/
### Example user template template ### Example user template template
### Example user template ### Example user template
# IntelliJ project files # IntelliJ project files
.idea .idea
*.iml *.iml
out out
gen gen
db/ db/
async-queue/ async-queue/
composer.lock composer.lock
*.log *.log
commands/result commands/result
config/setting.php config/setting.php
tests/ tests/
vendor/ vendor/
runtime/ runtime/
*.xml *.xml
*.lock *.lock
oot oot
d d
composer.lock composer.lock
+18 -15
View File
@@ -1,15 +1,18 @@
<?php <?php
namespace PHPSTORM_META { namespace PHPSTORM_META {
// Reflect // Reflect
use Kiri\Di\Container; use Kiri\Di\Container;
use Psr\Container\ContainerInterface;
override(Container::get(0), map('@'));
override(Container::create(0), map('@')); override(ContainerInterface::get(0), map('@'));
// override(\Hyperf\Utils\Context::get(0), map('@')); override(Container::get(0), map('@'));
// override(\make(0), map('@')); override(Container::make(0), map('@'));
override(\di(0), map('@')); override(Container::create(0), map('@'));
override(\duplicate(0), map('@')); // override(\Hyperf\Utils\Context::get(0), map('@'));
// override(\make(0), map('@'));
} override(\di(0), map('@'));
override(\duplicate(0), map('@'));
}
+21 -21
View File
@@ -1,21 +1,21 @@
MIT License MIT License
Copyright (c) 2020 向林 Copyright (c) 2020 向林
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
+23 -23
View File
@@ -1,23 +1,23 @@
<?php <?php
function version($oldVersion, $newVersion): bool function version($oldVersion, $newVersion): bool
{ {
$first = explode('.', $oldVersion); $first = explode('.', $oldVersion);
$end = explode('.', $newVersion); $end = explode('.', $newVersion);
while (count($first) > 0) { while (count($first) > 0) {
$shift = (int)array_shift($first); $shift = (int)array_shift($first);
$endShift = (int)array_shift($end); $endShift = (int)array_shift($end);
if ($endShift == $shift) { if ($endShift == $shift) {
continue; continue;
} }
if ($endShift < $shift) { if ($endShift < $shift) {
return true; return TRUE;
} else { } else {
return false; return FALSE;
} }
} }
return false; return FALSE;
} }
var_dump(version('1.4.4','1.4.3')); var_dump(version('1.4.4', '1.4.3'));
+46 -46
View File
@@ -1,46 +1,46 @@
{ {
"name": "game-worker/kiri-core", "name": "game-worker/kiri-core",
"description": "test framework", "description": "test framework",
"authors": [ "authors": [
{ {
"name": "XiangLin", "name": "XiangLin",
"email": "as2252258@163.com" "email": "as2252258@163.com"
} }
], ],
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": ">=8.0", "php": ">=8.1",
"ext-json": "*", "ext-json": "*",
"ext-fileinfo": "*", "ext-fileinfo": "*",
"ext-pdo": "*", "ext-pdo": "*",
"ext-redis": "*", "ext-redis": "*",
"ext-simplexml": "*", "ext-simplexml": "*",
"ext-libxml": "*", "ext-libxml": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-xml": "*", "ext-xml": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-openssl": "*", "ext-openssl": "*",
"symfony/console": "^v5.3", "symfony/console": "~v5.3.10",
"psr/log": "1.*", "psr/log": "1.*",
"ext-sockets": "*", "composer-runtime-api": "^2.0",
"ext-pcntl": "*", "psr/container": "^2.0",
"ext-posix": "*", "psr/http-server-middleware": "1.0.1",
"composer-runtime-api": "^2.0", "game-worker/kiri-event": "~v2.0",
"swiftmailer/swiftmailer": "^6.0", "ext-inotify": "*"
"psr/container": "^2.0", },
"psr/http-server-middleware": "^1.0", "autoload": {
"game-worker/kiri-event": "v1.0" "psr-4": {
}, "Kiri\\": "kiri-engine/",
"autoload": { "Kiri\\Gateway\\": "kiri-gateway/",
"psr-4": { "Kiri\\Websocket\\": "kiri-websocket-server/",
"Kiri\\": "kiri-engine/", "Gii\\": "kiri-gii/",
"Gii\\": "kiri-gii/", "Kiri\\Annotation\\": "kiri-annotation/",
"Annotation\\": "kiri-note/" "Kiri\\Task\\": "kiri-task/"
}, },
"files": [ "files": [
"error.php", "error.php",
"function.php" "function.php"
] ]
} }
} }
+31 -31
View File
@@ -1,31 +1,31 @@
<?php <?php
define('SUCCESS', 0); define('SUCCESS', 0);
define('NO_AUTH', 401); define('NO_AUTH', 401);
define('ERROR_MESSAGES', [ define('ERROR_MESSAGES', [
SUCCESS => 'ok', SUCCESS => 'ok',
NO_AUTH => '' NO_AUTH => ''
]); ]);
if (!function_exists('message')) { if (!function_exists('message')) {
/** /**
* @param $code * @param $code
* @param $replace * @param $replace
* @param string $default * @param string $default
* @return mixed|string * @return mixed|string
*/ */
function message($code, $replace, $default = '') function message($code, $replace, $default = '')
{ {
if (!isset(ERROR_MESSAGES[$code])) { if (!isset(ERROR_MESSAGES[$code])) {
if (!empty($default)) { if (!empty($default)) {
return $default; return $default;
} }
return 'unknown error'; return 'unknown error';
} }
return sprintf(ERROR_MESSAGES[$code], $replace); return sprintf(ERROR_MESSAGES[$code], $replace);
} }
} }
+1234 -1155
View File
File diff suppressed because it is too large Load Diff
@@ -1,86 +1,86 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use DirectoryIterator; use DirectoryIterator;
use Exception; use Exception;
use ReflectionException; use ReflectionException;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
/** /**
* Class Annotation * Class Annotation
* @package Annotation * @package Annotation
*/ */
class Annotation extends Component class Annotation extends Component
{ {
private Loader $_loader; private Loader $_loader;
/** /**
* *
*/ */
public function init(): void public function init(): void
{ {
$this->_loader = new Loader(); $this->_loader = new Loader();
} }
/** /**
* @return Loader * @return Loader
*/ */
public function getLoader(): Loader public function getLoader(): Loader
{ {
return $this->_loader; return $this->_loader;
} }
/** /**
* @param Loader $loader * @param Loader $loader
* @return Loader * @return Loader
*/ */
public function setLoader(Loader $loader): Loader public function setLoader(Loader $loader): Loader
{ {
return $this->_loader = $loader; return $this->_loader = $loader;
} }
/** /**
* @param object $class * @param object $class
* @throws ReflectionException * @throws ReflectionException
*/ */
public function injectProperty(object $class) public function injectProperty(object $class)
{ {
$this->_loader->injectProperty($class::class, $class); $this->_loader->injectProperty($class::class, $class);
} }
/** /**
* @param string $path * @param string $path
* @param string $namespace * @param string $namespace
* @param array $exclude * @param array $exclude
* @return static * @return static
* @throws Exception * @throws Exception
*/ */
public function read(string $path, string $namespace = 'App', array $exclude = []): static public function read(string $path, string $namespace = 'App', array $exclude = []): static
{ {
$this->_loader->_scanDir(new DirectoryIterator($path), $namespace, $exclude); $this->_loader->_scanDir(new DirectoryIterator($path), $namespace, $exclude);
return $this; return $this;
} }
/** /**
* @param string $dir * @param string $dir
* @param array $exclude * @param array $exclude
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function runtime(string $dir, array $exclude = []): array public function runtime(string $dir, array $exclude = []): array
{ {
return $this->_loader->loadByDirectory($dir, $exclude); return $this->_loader->loadByDirectory($dir, $exclude);
} }
} }
@@ -1,37 +1,37 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement '); defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement ');
/** /**
* Class Aspect * Class Aspect
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends Attribute
{ {
/** /**
* Aspect constructor. * Aspect constructor.
* @param string $aspect * @param string $aspect
*/ */
public function __construct(public string $aspect) public function __construct(public string $aspect)
{ {
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = ''): bool public function execute(mixed $class, mixed $method = ''): bool
{ {
return true; return true;
} }
} }
@@ -1,26 +1,27 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
/** /**
* Class Attribute * Class Attribute
* @package Annotation * @package Annotation
*/ */
abstract class Attribute implements IAnnotation abstract class Attribute implements IAnnotation
{ {
/** /**
* @param static $class * @param static $class
* @param mixed|string $method * @param mixed|string $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed #[\ReturnTypeWillChange]
{ public function execute(mixed $class, mixed $method = ''): mixed
// TODO: Implement execute() method. {
return true; // TODO: Implement execute() method.
} return true;
}
}
}
@@ -1,46 +1,46 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Kiri; use Kiri\Kiri;
/** /**
* Class Event * Class Event
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Event extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Event extends Attribute
{ {
/** /**
* Event constructor. * Event constructor.
* @param string $name * @param string $name
* @param array $params * @param array $params
*/ */
public function __construct(public string $name, public array $params = []) public function __construct(public string $name, public array $params = [])
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
$pro = Kiri::getDi()->get(EventProvider::class); $pro = Kiri::getDi()->get(EventProvider::class);
if (is_string($class)) { if (is_string($class)) {
$class = Kiri::getDi()->get($class); $class = Kiri::getDi()->get($class);
} }
$pro->on($this->name, [$class, $method]); $pro->on($this->name, [$class, $method]);
return true; return true;
} }
} }
@@ -1,19 +1,19 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
interface IAnnotation interface IAnnotation
{ {
/** /**
* @param mixed $class * @param mixed $class
* @param mixed $method * @param mixed $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed; public function execute(mixed $class, mixed $method = ''): mixed;
} }
@@ -1,105 +1,104 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Core\Str; use Kiri\Core\Str;
use Kiri\Kiri; use Kiri\Kiri;
use ReflectionException; use ReflectionException;
use ReflectionProperty; use ReflectionProperty;
/** /**
* Class Inject * Class Inject
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_PROPERTY)] class Inject extends Attribute #[\Attribute(\Attribute::TARGET_PROPERTY)] class Inject extends Attribute
{ {
/** /**
* Inject constructor. * Inject constructor.
* @param string $value * @param string $value
* @param array $construct * @param array $construct
*/ */
public function __construct(public string $value, public array $construct = []) public function __construct(public string $value, public array $construct = [])
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws ReflectionException * @throws ReflectionException
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
if (!($method = $this->getProperty($class, $method))) { if (!($method = $this->getProperty($class, $method))) {
return false; return false;
} }
/** @var ReflectionProperty $class */ /** @var ReflectionProperty $class */
$injectValue = static::parseInjectValue(); $injectValue = static::parseInjectValue();
if ($method->isPrivate() || $method->isProtected()) { if ($method->isPrivate() || $method->isProtected()) {
$this->setter($class, $method, $injectValue); $this->setter($class, $method, $injectValue);
} else { } else {
$class->{$method->getName()} = $injectValue; $class->{$method->getName()} = $injectValue;
} }
return true; return true;
} }
/** /**
* @param $class * @param $class
* @param $method * @param $method
* @param $injectValue * @param $injectValue
*/ */
private function setter($class, $method, $injectValue) private function setter($class, $method, $injectValue)
{ {
$method = 'set' . ucfirst(Str::convertUnderline($method->getName())); $method = 'set' . ucfirst(Str::convertUnderline($method->getName()));
if (!method_exists($class, $method)) { if (!method_exists($class, $method)) {
return; return;
} }
$class->$method($injectValue); $class->$method($injectValue);
} }
/** /**
* @param $class * @param $class
* @param $method * @param $method
* @return ReflectionProperty|bool * @return ReflectionProperty|bool
* @throws ReflectionException */
*/ private function getProperty($class, $method): ReflectionProperty|bool
private function getProperty($class, $method): ReflectionProperty|bool {
{ if ($method instanceof ReflectionProperty && !$method->isStatic()) {
if ($method instanceof ReflectionProperty && !$method->isStatic()) { return $method;
return $method; }
} if (is_object($class)) $class = $class::class;
if (is_object($class)) $class = $class::class; $method = Kiri::getDi()->getClassReflectionProperty($class, $method);
$method = Kiri::getDi()->getClassReflectionProperty($class, $method); if (!$method || $method->isStatic()) {
if (!$method || $method->isStatic()) { return false;
return false; }
} return $method;
return $method; }
}
/**
/** * @return mixed
* @return mixed * @throws Exception
* @throws Exception */
*/ private function parseInjectValue(): mixed
private function parseInjectValue(): mixed {
{ if (!Kiri::app()->has($this->value)) {
if (!Kiri::app()->has($this->value)) { if (!empty($this->construct)) {
if (!empty($this->construct)) { return Kiri::getDi()->create($this->value, $this->construct);
return Kiri::getDi()->create($this->value, $this->construct); }
} return Kiri::getDi()->get($this->value);
return Kiri::getDi()->get($this->value); } else {
} else { return Kiri::app()->get($this->value);
return Kiri::app()->get($this->value); }
} }
}
}
}
@@ -1,243 +1,225 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use DirectoryIterator; use DirectoryIterator;
use Exception; use Exception;
use Kiri\Abstracts\BaseObject; use Kiri\Abstracts\Component;
use Kiri\Kiri; use Kiri\Kiri;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
use Throwable; use Throwable;
/** /**
* Class Loader * Class Loader
* @package Annotation * @package Annotation
*/ */
class Loader extends BaseObject class Loader extends Component
{ {
private array $_classes = []; private array $_directory = [];
private array $_directory = []; private array $_methods = [];
private array $_property = []; /**
* @param $path
* @param $namespace
private array $_methods = []; * @throws Exception
*/
public function loader($path, $namespace)
/** {
* @param $path $this->_scanDir(new DirectoryIterator($path), $namespace);
* @param $namespace }
* @throws Exception
*/
public function loader($path, $namespace) /**
{ * @param string $class
$this->_scanDir(new DirectoryIterator($path), $namespace); * @param object $handler
} * @return $this
* @throws ReflectionException
/** * @throws Exception
* @param string $class */
* @param string $property public function injectProperty(string $class, object $handler): static
* @return \ReflectionProperty|array|null {
* @throws ReflectionException $di = Kiri::getDi();
*/
public function getProperty(string $class, string $property = ''): \ReflectionProperty|array|null $reflect = $di->getReflect($class);
{
return Kiri::getDi()->getClassReflectionProperty($class, $property); $di->propertyInject($reflect, $handler);
}
return $this;
}
/**
* @param string $class
* @param object $handler /**
* @return $this * @param string $class
* @throws ReflectionException * @param string $method
* @throws Exception * @return mixed
*/ */
public function injectProperty(string $class, object $handler): static public function getMethod(string $class, string $method = ''): array
{ {
$di = Kiri::getDi(); if (!isset($this->_methods[$class])) {
return [];
$reflect = $di->getReflect($class); }
$properties = $this->_methods[$class];
$di->propertyInject($reflect, $handler); if (!empty($method) && isset($properties[$method])) {
return $properties[$method];
return $this; }
} return $properties;
}
/**
* @param string $class /**
* @param string $method * @param DirectoryIterator $paths
* @return mixed * @param $namespace
*/ * @param array $exclude
public function getMethod(string $class, string $method = ''): array * @throws Exception
{ */
if (!isset($this->_methods[$class])) { public function _scanDir(DirectoryIterator $paths, $namespace, array $exclude = [])
return []; {
} foreach ($paths as $path) {
$properties = $this->_methods[$class]; if ($path->isDot() || str_starts_with($path->getFilename(), '.')) {
if (!empty($method) && isset($properties[$method])) { continue;
return $properties[$method]; }
} if ($this->inExclude($exclude, $path->getRealPath())) {
return $properties; continue;
} }
if ($path->isDir()) {
$iterator = new DirectoryIterator($path->getRealPath());
/** $directory = rtrim($path->getRealPath(), '/');
* @param DirectoryIterator $paths if (!isset($this->_directory[$directory])) {
* @param $namespace $this->_directory[$directory] = [];
* @param array $exclude }
* @throws Exception $this->_scanDir($iterator, $namespace);
*/ } else {
public function _scanDir(DirectoryIterator $paths, $namespace, array $exclude = []) $this->readFile($path, $namespace);
{ }
foreach ($paths as $path) { }
if ($path->isDot() || str_starts_with($path->getFilename(), '.')) { }
continue;
}
if ($this->inExclude($exclude, $path->getRealPath())) { /**
continue; * @param DirectoryIterator $path
} * @param $namespace
if ($path->isDir()) { * @throws Exception
$iterator = new DirectoryIterator($path->getRealPath()); */
$directory = rtrim($path->getRealPath(), '/'); private function readFile(DirectoryIterator $path, $namespace)
if (!isset($this->_directory[$directory])) { {
$this->_directory[$directory] = []; try {
} if ($path->getExtension() !== 'php') {
$this->_scanDir($iterator, $namespace); return;
} else { }
$this->readFile($path, $namespace); $replace = $this->getReflect($path, $namespace);
} if (!$replace || !$replace->getAttributes(Target::class)) {
} return;
} }
$this->appendFileToDirectory($path->getRealPath(), $replace->getName());
} catch (Throwable $throwable) {
/** $this->error(jTraceEx($throwable), 'throwable');
* @param DirectoryIterator $path }
* @param $namespace }
* @throws Exception
*/
private function readFile(DirectoryIterator $path, $namespace) /**
{ * @param DirectoryIterator $path
try { * @param string $namespace
if ($path->getExtension() !== 'php') { * @return ReflectionClass|null
return; */
} private function getReflect(DirectoryIterator $path, string $namespace): ?ReflectionClass
$replace = $this->getReflect($path, $namespace); {
if (!$replace || !$replace->getAttributes(Target::class)) { $class = $this->explodeFileName($path, $namespace);
return; if (!class_exists($class)) {
} return null;
$this->appendFileToDirectory($path->getRealPath(), $replace->getName()); }
} catch (Throwable $throwable) { return Kiri::getDi()->getReflect($class);
$this->error(jTraceEx($throwable), 'throwable'); }
}
}
/**
* @param string $path
/** * @param array $exclude
* @param DirectoryIterator $path * @return array
* @param string $namespace * @throws Exception
* @return ReflectionClass|null */
* @throws ReflectionException public function loadByDirectory(string $path, array $exclude = []): array
*/ {
private function getReflect(DirectoryIterator $path, string $namespace): ?ReflectionClass try {
{ $path = '/' . trim($path, '/');
$class = $this->explodeFileName($path, $namespace); $paths = [];
if (!class_exists($class)) { foreach ($this->_directory as $key => $_path) {
return null; $key = '/' . trim($key, '/');
} if (!str_starts_with($key, $path) || $this->inExclude($exclude, $path)) {
return Kiri::getDi()->getReflect($class); continue;
} }
unset($this->_directory[$key]);
foreach ($_path as $item) {
/** $paths[] = $item;
* @param string $path }
* @param array $exclude }
* @return array return $paths;
* @throws Exception } catch (Throwable $exception) {
*/ $this->addError($exception, 'throwable');
public function loadByDirectory(string $path, array $exclude = []): array return [];
{ }
try { }
$path = '/' . trim($path, '/');
$paths = [];
foreach ($this->_directory as $key => $_path) { /**
$key = '/' . trim($key, '/'); * @param array $exclude
if (!str_starts_with($key, $path) || $this->inExclude($exclude, $path)) { * @param $path
continue; * @return bool
} */
unset($this->_directory[$key]); private function inExclude(array $exclude, $path): bool
foreach ($_path as $item) { {
$paths[] = $item; if (empty($exclude)) {
} return false;
} }
return $paths; foreach ($exclude as $value) {
} catch (Throwable $exception) { if (str_starts_with($path, $value)) {
$this->addError($exception, 'throwable'); return true;
return []; }
} }
} return false;
}
/**
* @param array $exclude /**
* @param $path * @param DirectoryIterator $path
* @return bool * @param string $namespace
*/ * @return string
private function inExclude(array $exclude, $path): bool */
{ private function explodeFileName(DirectoryIterator $path, string $namespace): string
if (empty($exclude)) { {
return false; $replace = str_replace(APP_PATH, '', $path->getRealPath());
}
foreach ($exclude as $value) { $replace = str_replace('.php', '', $replace);
if (str_starts_with($path, $value)) { $replace = str_replace(DIRECTORY_SEPARATOR, '\\', $replace);
return true; $explode = explode('\\', $replace);
} array_shift($explode);
}
return false; return $namespace . '\\' . implode('\\', $explode);
} }
/** /**
* @param DirectoryIterator $path * @param string $filePath
* @param string $namespace * @param string $className
* @return string */
*/ public function appendFileToDirectory(string $filePath, string $className)
private function explodeFileName(DirectoryIterator $path, string $namespace): string {
{ $array = explode('/', $filePath);
$replace = str_replace(APP_PATH, '', $path->getRealPath()); unset($array[count($array) - 1]);
$replace = str_replace('.php', '', $replace); $array = '/' . trim(implode('/', $array), '/');
$replace = str_replace(DIRECTORY_SEPARATOR, '\\', $replace);
$explode = explode('\\', $replace); $this->_directory[$array][] = $className;
array_shift($explode); }
return $namespace . '\\' . implode('\\', $explode);
} }
/**
* @param string $filePath
* @param string $className
*/
public function appendFileToDirectory(string $filePath, string $className)
{
$array = explode('/', $filePath);
unset($array[count($array) - 1]);
$array = '/' . trim(implode('/', $array), '/');
$this->_directory[$array][] = $className;
}
}
@@ -1,31 +1,31 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Kiri\Kiri; use Kiri\Kiri;
#[\Attribute(\Attribute::TARGET_CLASS)] class Mapping extends Attribute #[\Attribute(\Attribute::TARGET_CLASS)] class Mapping extends Attribute
{ {
/** /**
* @param string $class * @param string $class
*/ */
public function __construct(public string $class) public function __construct(public string $class)
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|string $method * @param mixed|string $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed public function execute(mixed $class, mixed $method = ''): mixed
{ {
Kiri::getDi()->mapping($this->class, $class); Kiri::getDi()->mapping($this->class, $class);
return parent::execute($class, $method); return parent::execute($class, $method);
} }
} }
@@ -1,34 +1,34 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Document * Class Document
* @package Annotation\Route * @package Annotation\Route
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Document extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Document extends Attribute
{ {
const INTEGER = 'int'; const INTEGER = 'int';
const STRING = 'string'; const STRING = 'string';
const BOOLEAN = 'bool'; const BOOLEAN = 'bool';
const FLOAT = 'float'; const FLOAT = 'float';
const ALIAS = [ const ALIAS = [
self::INTEGER => '整数', self::INTEGER => '整数',
self::STRING => '字符串', self::STRING => '字符串',
self::BOOLEAN => '布尔值', self::BOOLEAN => '布尔值',
self::FLOAT => '浮点', self::FLOAT => '浮点',
]; ];
public function __construct(array $request, array $response) public function __construct(array $request, array $response)
{ {
} }
} }
@@ -1,52 +1,53 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
use Http\Handler\Abstracts\MiddlewareManager; use Kiri\Message\Handler\Abstracts\MiddlewareManager;
use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\MiddlewareInterface;
/** /**
* Class Middleware * Class Middleware
* @package Annotation\Route * @package Annotation\Route
*/ */
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Middleware extends Attribute #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Middleware extends Attribute
{ {
/** /**
* Interceptor constructor. * Interceptor constructor.
* @param string|array $middleware * @param string|array $middleware
* @throws * @throws
*/ */
public function __construct(public string|array $middleware) public function __construct(public string|array $middleware)
{ {
if (is_string($this->middleware)) { if (is_string($this->middleware)) {
$this->middleware = [$this->middleware]; $this->middleware = [$this->middleware];
} }
$array = []; $array = [];
foreach ($this->middleware as $value) { foreach ($this->middleware as $value) {
if (!in_array(MiddlewareInterface::class, class_implements($value))) { if (!in_array(MiddlewareInterface::class, class_implements($value))) {
throw new \Exception('The middleware'); throw new \Exception('The middleware');
} }
$array[] = $value; $array[] = $value;
} }
$this->middleware = $array; $this->middleware = $array;
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return $this * @return $this
*/ * @throws \ReflectionException
public function execute(mixed $class, mixed $method = null): mixed */
{ public function execute(mixed $class, mixed $method = null): mixed
MiddlewareManager::add($class, $method, $this->middleware); {
return parent::execute($class, $method); MiddlewareManager::add($class, $method, $this->middleware);
} return parent::execute($class, $method);
}
}
}
@@ -1,41 +1,41 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
use Http\Handler\Router; use Kiri\Message\Handler\Router;
use Kiri\Kiri; use Kiri\Kiri;
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Route extends Attribute #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Route extends Attribute
{ {
/** /**
* Route constructor. * Route constructor.
* @param string $uri * @param string $uri
* @param string $method * @param string $method
* @param string $version * @param string $version
*/ */
public function __construct(public string $uri, public string $method, public string $version = 'v.1.0') public function __construct(public string $uri, public string $method, public string $version = 'v.1.0')
{ {
$this->uri = '/' . ltrim($this->uri, '/'); $this->uri = '/' . ltrim($this->uri, '/');
$this->method = strtoupper($this->method); $this->method = strtoupper($this->method);
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws \ReflectionException * @throws \ReflectionException
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
$di = Kiri::getDi()->get(Router::class); $di = Kiri::getDi()->get(Router::class);
$di->addRoute($this->method, $this->uri, $class . '@' . $method); $di->addRoute($this->method, $this->uri, $class . '@' . $method);
return parent::execute($class, $method); return parent::execute($class, $method);
} }
} }
@@ -1,31 +1,31 @@
<?php <?php
namespace Annotation\Route; namespace Kiri\Annotation\Route;
use Annotation\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Socket * Class Socket
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Socket extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Socket extends Attribute
{ {
const CLOSE = 'CLOSE'; const CLOSE = 'CLOSE';
const MESSAGE = 'MESSAGE'; const MESSAGE = 'MESSAGE';
const HANDSHAKE = 'HANDSHAKE'; const HANDSHAKE = 'HANDSHAKE';
/** /**
* Socket constructor. * Socket constructor.
* @param string $event * @param string $event
* @param string|null $uri * @param string|null $uri
* @param string $version * @param string $version
*/ */
public function __construct(string $event, ?string $uri = null, string $version = 'v.1.0') public function __construct(string $event, ?string $uri = null, string $version = 'v.1.0')
{ {
} }
} }
@@ -1,28 +1,28 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
/** /**
* Class Target * Class Target
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_CLASS)] class Target extends Attribute #[\Attribute(\Attribute::TARGET_CLASS)] class Target extends Attribute
{ {
const WORKER = 'worker'; const WORKER = 'worker';
const ALL = 'any'; const ALL = 'any';
const PROCESS = 'process'; const PROCESS = 'process';
const TASK = 'task'; const TASK = 'task';
/** /**
* @param string $only * @param string $only
*/ */
public function __construct(string $only = Target::ALL) public function __construct(string $only = Target::ALL)
{ {
} }
} }
@@ -1,43 +1,44 @@
<?php <?php
namespace Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Kiri; use Kiri\Kiri;
use Kiri\Server\Tasker\AsyncTaskExecute;
/**
* Class Asynchronous /**
* @package Annotation * Class Task
* Task任务 * @package Annotation
*/ * Task任务
#[\Attribute(\Attribute::TARGET_CLASS)] class Asynchronous extends Attribute */
{ #[\Attribute(\Attribute::TARGET_CLASS)] class Task extends Attribute
{
/**
* Asynchronous constructor. /**
* @param string $name * Task constructor.
*/ * @param string $name
public function __construct(public string $name) */
{ public function __construct(public string $name)
{
}
}
/**
* @param mixed $class /**
* @param mixed|null $method * @param mixed $class
* @return bool * @param mixed|null $method
* @throws Exception * @return bool
*/ * @throws Exception
public function execute(mixed $class, mixed $method = null): bool */
{ public function execute(mixed $class, mixed $method = null): bool
$async = Kiri::app()->getAsync(); {
$async->addAsync($this->name, $class); $task = Kiri::getDi()->get(AsyncTaskExecute::class);
return true; $task->reg($this->name, $class);
} return true;
}
}
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace Kiri\Abstracts;
abstract class AbstractServer extends Component
{
public string $name = 'http';
}
+451 -471
View File
@@ -1,471 +1,451 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/10/7 0007 * Date: 2018/10/7 0007
* Time: 2:13 * Time: 2:13
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Annotation\Annotation as SAnnotation; use Database\Connection;
use Database\Connection; use Exception;
use Exception; use Kiri\Message\Handler\Router;
use Http\Handler\Router; use Kafka\KafkaProvider;
use Kiri\Events\OnBeforeCommandExecute; use Kiri\{Async, Kiri};
use Server\Server; use Kiri\Annotation\Annotation as SAnnotation;
use Kafka\KafkaProvider; use Kiri\Cache\Redis;
use Kiri\Async; use Kiri\Di\LocalService;
use Kiri\Cache\Redis; use Kiri\Error\{ErrorHandler, Logger};
use Kiri\Di\LocalService; use Kiri\Exception\{InitException, NotFindClassException};
use Kiri\Error\ErrorHandler; use ReflectionException;
use Kiri\Error\Logger; use Kiri\Server\{Contract\OnTaskInterface, Server, ServerManager, Tasker\AsyncTaskExecute};
use Kiri\Events\EventProvider; use Swoole\Table;
use Kiri\Exception\InitException;
use Kiri\Exception\NotFindClassException; /**
use Kiri\Jwt\Jwt; * Class BaseApplication
use Kiri\Kiri; * @package Kiri\Kiri\Base
use ReflectionException; */
use Server\ServerManager; abstract class BaseApplication extends Component
use Server\Contract\OnTaskInterface; {
use Swoole\Table;
use TraitApplication;
/**
* Class BaseApplication
* @package Kiri\Kiri\Base /**
*/ * @var string
abstract class BaseApplication extends Component */
{ public string $storage = APP_PATH . 'storage';
use TraitApplication; public string $envPath = APP_PATH . '.env';
/**
/** * Init constructor.
* @var string *
*/ *
public string $storage = APP_PATH . 'storage'; * @throws
*/
public string $envPath = APP_PATH . '.env'; public function __construct()
{
/** Kiri::init($this);
* Init constructor.
* $config = sweep(APP_PATH . '/config');
*
* @throws $this->moreComponents();
*/ $this->parseInt($config);
public function __construct() $this->parseEvents($config);
{ $this->initErrorHandler();
Kiri::init($this); $this->enableEnvConfig();
$this->mapping($config['mapping'] ?? []);
$config = sweep(APP_PATH . '/config');
parent::__construct();
$this->moreComponents(); }
$this->parseInt($config);
$this->parseEvents($config);
$this->initErrorHandler(); /**
$this->enableEnvConfig(); * @param array $mapping
$this->mapping($config['mapping'] ?? []); */
public function mapping(array $mapping)
parent::__construct(); {
} $di = Kiri::getDi();
foreach ($mapping as $interface => $class) {
$di->mapping($interface, $class);
/** }
* @param array $mapping }
*/
public function mapping(array $mapping)
{ /**
$di = Kiri::getDi(); * @return array
foreach ($mapping as $interface => $class) { */
$di->mapping($interface, $class); public function enableEnvConfig(): array
} {
} if (!file_exists($this->envPath)) {
return [];
}
/** $lines = $this->readLinesFromFile($this->envPath);
* @return array foreach ($lines as $line) {
*/ if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
public function enableEnvConfig(): array [$key, $value] = explode('=', $line);
{ putenv(trim($key) . '=' . trim($value));
if (!file_exists($this->envPath)) { }
return []; }
} return $lines;
$lines = $this->readLinesFromFile($this->envPath); }
foreach ($lines as $line) {
if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
[$key, $value] = explode('=', $line); /**
putenv(trim($key) . '=' . trim($value)); * Read lines from the file, auto detecting line endings.
} *
} * @param string $filePath
return $lines; *
} * @return array
*/
protected function readLinesFromFile(string $filePath): array
/** {
* Read lines from the file, auto detecting line endings. // Read file into an array of lines with auto-detected line endings
* $autodetect = ini_get('auto_detect_line_endings');
* @param string $filePath ini_set('auto_detect_line_endings', '1');
* $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
* @return array ini_set('auto_detect_line_endings', $autodetect);
*/
protected function readLinesFromFile(string $filePath): array return $lines;
{ }
// Read file into an array of lines with auto-detected line endings
$autodetect = ini_get('auto_detect_line_endings'); /**
ini_set('auto_detect_line_endings', '1'); * Determine if the line in the file is a comment, e.g. begins with a #.
$lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); *
ini_set('auto_detect_line_endings', $autodetect); * @param string $line
*
return $lines; * @return bool
} */
protected function isComment(string $line): bool
/** {
* Determine if the line in the file is a comment, e.g. begins with a #. $line = ltrim($line);
*
* @param string $line return isset($line[0]) && $line[0] === '#';
* }
* @return bool
*/ /**
protected function isComment(string $line): bool * Determine if the given line looks like it's setting a variable.
{ *
$line = ltrim($line); * @param string $line
*
return isset($line[0]) && $line[0] === '#'; * @return bool
} */
protected function looksLikeSetter(string $line): bool
/** {
* Determine if the given line looks like it's setting a variable. return str_contains($line, '=');
* }
* @param string $line
*
* @return bool /**
*/ * @param $config
protected function looksLikeSetter(string $line): bool *
{ * @throws
return str_contains($line, '='); */
} public function parseInt($config)
{
Config::sets($config);
/** if ($storage = Config::get('storage', 'storage')) {
* @param $config if (!str_contains($storage, APP_PATH)) {
* $storage = APP_PATH . $storage . '/';
* @throws }
*/ if (!is_dir($storage)) {
public function parseInt($config) mkdir($storage);
{ }
Config::sets($config); if (!is_dir($storage) || !is_writeable($storage)) {
if ($storage = Config::get('storage', 'storage')) { throw new InitException("Directory {$storage} does not have write permission");
if (!str_contains($storage, APP_PATH)) { }
$storage = APP_PATH . $storage . '/'; }
} }
if (!is_dir($storage)) {
mkdir($storage);
} /**
if (!is_dir($storage) || !is_writeable($storage)) { * @param $name
throw new InitException("Directory {$storage} does not have write permission"); * @return mixed
} * @throws ReflectionException
} * @throws NotFindClassException
} * @throws Exception
*/
public function __get($name): mixed
/** {
* @param $name if ($this->has($name)) {
* @return mixed return $this->get($name);
* @throws ReflectionException }
* @throws NotFindClassException return parent::__get($name); // TODO: Change the autogenerated stub
* @throws Exception }
*/
public function __get($name): mixed
{ /**
if ($this->has($name)) { * @param $config
return $this->get($name); *
} * @throws
return parent::__get($name); // TODO: Change the autogenerated stub */
} public function parseEvents($config)
{
if (!isset($config['events']) || !is_array($config['events'])) {
/** return;
* @param $config }
* foreach ($config['events'] as $key => $value) {
* @throws if (is_string($value)) {
*/ $value = Kiri::createObject($value);
public function parseEvents($config) }
{ $this->addEvent($key, $value);
if (!isset($config['events']) || !is_array($config['events'])) { }
return; }
}
foreach ($config['events'] as $key => $value) {
if (is_string($value)) { /**
$value = Kiri::createObject($value); * @param OnTaskInterface $execute
} * @throws ReflectionException
$this->addEvent($key, $value); */
} public function task(OnTaskInterface $execute): void
} {
di(AsyncTaskExecute::class)->execute($execute);
}
/**
* @param OnTaskInterface $execute
* @throws ReflectionException /**
*/ * @param $key
public function task(OnTaskInterface $execute): void * @param $value
{ * @throws InitException
di(ServerManager::class)->task($execute); * @throws Exception
} */
private function addEvent($key, $value): void
{
/** if ($value instanceof \Closure || is_object($value)) {
* @param $key $this->eventProvider->on($key, $value, 0);
* @param $value return;
* @throws InitException }
* @throws Exception
*/
private function addEvent($key, $value): void if (is_array($value)) {
{ if (is_object($value[0]) && !($value[0] instanceof \Closure)) {
$eventProvider = di(EventProvider::class); $this->eventProvider->on($key, $value, 0);
if ($value instanceof \Closure || is_object($value)) { return;
$eventProvider->on($key, $value, 0); }
return;
} if (is_string($value[0])) {
$value[0] = Kiri::createObject($value[0]);
$this->eventProvider->on($key, $value, 0);
if (is_array($value)) { return;
if (is_object($value[0]) && !($value[0] instanceof \Closure)) { }
$eventProvider->on($key, $value, 0);
return;
} foreach ($value as $item) {
if (!is_callable($item, true)) {
if (is_string($value[0])) { throw new InitException("Class does not hav callback.");
$value[0] = Kiri::createObject($value[0]); }
$eventProvider->on($key, $value, 0); $this->eventProvider->on($key, $item, 0);
return; }
} }
}
foreach ($value as $item) {
if (!is_callable($item, true)) {
throw new InitException("Class does not hav callback."); /**
} * @param $name
$eventProvider->on($key, $item, 0); * @return mixed
} * @throws Exception
} */
public function clone($name): mixed
} {
return clone $this->get($name);
}
/**
* @param $name /**
* @return mixed *
* @throws Exception * @throws Exception
*/ */
public function clone($name): mixed public function initErrorHandler()
{ {
return clone $this->get($name); $this->get('error')->register();
} }
/**
* /**
* @throws Exception * @param $name
*/ * @return mixed
public function initErrorHandler() * @throws
{ */
$this->get('error')->register(); public function get($name): mixed
} {
return di(LocalService::class)->get($name);
}
/**
* @param $name
* @return mixed /**
* @throws * @return mixed
*/ */
public function get($name): mixed public function getLocalIps(): mixed
{ {
return di(LocalService::class)->get($name); return swoole_get_local_ip();
} }
/**
/** * @return mixed
* @return mixed */
*/ public function getFirstLocal(): mixed
public function getLocalIps(): mixed {
{ return current($this->getLocalIps());
return swoole_get_local_ip(); }
}
/** /**
* @return mixed * @return Logger
*/ * @throws
public function getFirstLocal(): mixed */
{ public function getLogger(): Logger
return current($this->getLocalIps()); {
} return $this->get('logger');
}
/**
* @return Logger /**
* @throws * @return \Redis|Redis
*/ * @throws
public function getLogger(): Logger */
{ public function getRedis(): Redis|\Redis
return $this->get('logger'); {
} return Kiri::getDi()->get(Redis::class);
}
/** /**
* @return \Redis|Redis * @param $ip
* @throws * @return bool
*/ */
public function getRedis(): Redis|\Redis public function isLocal($ip): bool
{ {
return Kiri::getDi()->get(Redis::class); return $this->getFirstLocal() == $ip;
} }
/**
* @param $ip /**
* @return bool * @return ErrorHandler
*/ * @throws
public function isLocal($ip): bool */
{ public function getError(): ErrorHandler
return $this->getFirstLocal() == $ip; {
} return $this->get('error');
}
/**
* @return ErrorHandler /**
* @throws * @param $name
*/ * @return Table
public function getError(): ErrorHandler * @throws
{ */
return $this->get('error'); public function getTable($name): Table
} {
return $this->get($name);
}
/**
* @param $name
* @return Table /**
* @throws * @return Config
*/ * @throws
public function getTable($name): Table */
{ public function getConfig(): Config
return $this->get($name); {
} return $this->get('config');
}
/**
* @return Config /**
* @throws * @return Router
*/ * @throws
public function getConfig(): Config */
{ public function getRouter(): Router
return $this->get('config'); {
} return Kiri::getDi()->get(Router::class);
}
/**
* @return Router /**
* @throws * @return Server
*/ * @throws
public function getRouter(): Router */
{ public function getServer(): Server
return Kiri::getDi()->get(Router::class); {
} return $this->get('server');
}
/**
* @return Jwt /**
* @throws * @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
*/ * @throws
public function getJwt(): Jwt */
{ public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
return $this->get('jwt'); {
} return di(ServerManager::class)->getServer();
}
/**
* @return Server /**
* @throws * @return SAnnotation
*/ * @throws
public function getServer(): Server */
{ public function getAnnotation(): SAnnotation
return $this->get('server'); {
} return $this->get('Annotation');
}
/**
* @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null /**
* @throws * @return Async
*/ * @throws
public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null */
{ public function getAsync(): Async
return di(ServerManager::class)->getServer(); {
} return $this->get('async');
}
/**
* @return SAnnotation /**
* @throws * @param $array
*/ */
public function getAnnotation(): SAnnotation private function setComponents($array): void
{ {
return $this->get('annotation'); di(LocalService::class)->setComponents($array);
} }
/** /**
* @return Async * @param $id
* @throws * @param $definition
*/ */
public function getAsync(): Async public function set($id, $definition): void
{ {
return $this->get('async'); di(LocalService::class)->set($id, $definition);
} }
/**
/** * @param $id
* @param $array * @return bool
*/ */
private function setComponents($array): void public function has($id): bool
{ {
di(LocalService::class)->setComponents($array); return di(LocalService::class)->has($id);
} }
/** /**
* @param $id * @throws Exception
* @param $definition */
*/ protected function moreComponents(): void
public function set($id, $definition): void {
{ $this->setComponents([
di(LocalService::class)->set($id, $definition); 'error' => ['class' => ErrorHandler::class],
} 'config' => ['class' => Config::class],
'logger' => ['class' => Logger::class],
'Annotation' => ['class' => SAnnotation::class],
/** 'databases' => ['class' => Connection::class],
* @param $id 'jwt' => ['class' => Jwt::class],
* @return bool 'async' => ['class' => Async::class],
*/ 'kafka-container' => ['class' => KafkaProvider::class],
public function has($id): bool ]);
{ }
return di(LocalService::class)->has($id); }
}
/**
* @throws Exception
*/
protected function moreComponents(): void
{
$this->setComponents([
'error' => ['class' => ErrorHandler::class],
'config' => ['class' => Config::class],
'logger' => ['class' => Logger::class],
'annotation' => ['class' => SAnnotation::class],
'databases' => ['class' => Connection::class],
'jwt' => ['class' => Jwt::class],
'async' => ['class' => Async::class],
'kafka-container' => ['class' => KafkaProvider::class],
]);
}
}
+13 -13
View File
@@ -1,13 +1,13 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Swoole\Coroutine; use Swoole\Coroutine;
abstract class BaseContext abstract class BaseContext
{ {
protected static array $pool = []; protected static array $pool = [];
} }
+28 -28
View File
@@ -1,28 +1,28 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
use Kiri\Core\Json; use Kiri\Core\Json;
/** /**
* Class BaseGoto * Class BaseGoto
* @package Kiri\Abstracts * @package Kiri\Abstracts
*/ */
class BaseGoto extends Component class BaseGoto extends Component
{ {
/** /**
* @param string $message * @param string $message
* @param int $statusCode * @param int $statusCode
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function end(string $message, int $statusCode = 200): mixed public function end(string $message, int $statusCode = 200): mixed
{ {
throw new Exception(Json::to(12350, $message), $statusCode); throw new Exception(Json::to(12350, $message), $statusCode);
} }
} }
-243
View File
@@ -1,243 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: whwyy
* Date: 2018/3/30 0030
* Time: 14:10
*/
declare(strict_types=1);
namespace Kiri\Abstracts;
use Exception;
use JetBrains\PhpStorm\Pure;
use Kiri\Kiri;
use Swoole\Coroutine;
/**
* Class BaseObject
* @package Kiri\Kiri\Base
*/
class BaseObject implements Configure
{
/**
* BaseAbstract constructor.
*
* @param array $config
* @throws Exception
*/
public function __construct(array $config = [])
{
if (!empty($config) && is_array($config)) {
Kiri::configure($this, $config);
}
}
/**
* @throws Exception
*/
public function init()
{
}
/**
* @param array|callable $callback
* @param object $scope
*/
public function async_create(array|callable $callback, object $scope)
{
Coroutine::create($callback, $scope);
}
/**
* @return string
*/
#[Pure] public static function className(): string
{
return static::class;
}
/**
* @param $name
* @param $value
*
* @throws Exception
*/
public function __set($name, $value)
{
$method = 'set' . ucfirst($name);
if (method_exists($this, $method)) {
$this->{$method}($value);
} else {
throw new Exception('The set name ' . $name . ' not find in class ' . static::class);
}
}
/**
* @param $name
*
* @return mixed
* @throws Exception
*/
public function __get($name): mixed
{
$method = 'get' . ucfirst($name);
if (method_exists($this, $method)) {
return $this->$method();
} else {
throw new Exception('The get name ' . $name . ' not find in class ' . static::class);
}
}
/**
* @param $message
* @param string $model
* @return bool
* @throws Exception
*/
public function addError($message, string $model = 'app'): bool
{
if ($message instanceof \Throwable) {
$this->error(jTraceEx($message));
} else {
if (!is_string($message)) {
$message = json_encode($message, JSON_UNESCAPED_UNICODE);
}
$this->error($message);
}
return FALSE;
}
/**
* @return Logger
* @throws Exception
*/
private function logger(): Logger
{
return Kiri::getDi()->get(Logger::class);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function debug(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[35m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->debug($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function info(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[34m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->info($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function success(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[36m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->notice($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function warning(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$message = "\033[33m" . $message . "\033[0m";
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->critical($message, $context);
}
/**
* @param mixed $message
* @param null $method
* @param null $file
* @throws Exception
*/
public function error(mixed $message, $method = null, $file = null)
{
if ($message instanceof \Throwable) {
$message = $message->getMessage() . " on line " . $message->getLine() . " at file " . $message->getFile();
}
$content = (empty($method) ? '' : $method . ': ') . $message;
$message = "\033[41;37m" . $content . "\033[0m";
if (!empty($file)) {
$message .= PHP_EOL . "\03341;37m[" . $file . "\033[0m";
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->error($message, $context);
}
}
+10 -10
View File
@@ -1,10 +1,10 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
abstract class Command extends Component abstract class Command extends Component
{ {
} }
+260 -55
View File
@@ -1,55 +1,260 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/3/30 0030 * Date: 2018/3/30 0030
* Time: 14:28 * Time: 14:28
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
use JetBrains\PhpStorm\Pure;
use JetBrains\PhpStorm\Pure; use Kiri\Di\Container;
use Kiri\Exception\ComponentException; use Kiri\Events\EventDispatch;
use Kiri\Kiri; use Kiri\Events\EventProvider;
use Kiri\Kiri;
/** use Psr\Container\ContainerExceptionInterface;
* Class Component use Psr\Container\ContainerInterface;
* @package Kiri\Kiri\Base use Psr\Container\NotFoundExceptionInterface;
*/
class Component extends BaseObject /**
{ * Class Component
* @package Kiri\Kiri\Base
* @property ContainerInterface|Container $container
/** * @property EventProvider $eventProvider
* @param $name * @property EventDispatch $eventDispatch
* @param $value */
* @throws Exception class Component implements Configure
*/ {
public function __set($name, $value)
{
if (property_exists($this, $name)) { /**
$this->$name = $value; * BaseAbstract constructor.
} else { *
parent::__set($name, $value); * @param array $config
} * @throws Exception
} */
public function __construct(array $config = [])
{
/** if (!empty($config) && is_array($config)) {
* @param $name Kiri::configure($this, $config);
* @return mixed }
* @throws Exception }
*/
public function __get($name): mixed
{ /**
if (property_exists($this, $name)) { * @return Container|ContainerInterface
return $this->$name ?? null; */
} else { #[Pure] public function getContainer(): ContainerInterface|Container
return parent::__get($name); {
} return Kiri::getDi();
} }
}
/**
* @return EventProvider
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getEventProvider(): EventProvider
{
return $this->getContainer()->get(EventProvider::class);
}
/**
* @return EventDispatch
*/
protected function getEventDispatch(): EventDispatch
{
return Kiri::getDi()->get(EventDispatch::class);
}
/**
* @throws Exception
*/
public function init()
{
}
/**
* @return string
*/
#[Pure] public static function className(): string
{
return static::class;
}
/**
* @param $name
* @param $value
*
* @throws Exception
*/
public function __set($name, $value)
{
$method = 'set' . ucfirst($name);
if (method_exists($this, $method)) {
$this->{$method}($value);
} else {
throw new Exception('The set name ' . $name . ' not find in class ' . static::class);
}
}
/**
* @param $name
*
* @return mixed
* @throws Exception
*/
public function __get($name): mixed
{
$method = 'get' . ucfirst($name);
if (method_exists($this, $method)) {
return $this->$method();
} else {
throw new Exception('The get name ' . $name . ' not find in class ' . static::class);
}
}
/**
* @param $message
* @param string $model
* @return bool
* @throws Exception
*/
public function addError($message, string $model = 'app'): bool
{
if ($message instanceof \Throwable) {
$this->error($message = jTraceEx($message));
} else {
if (!is_string($message)) {
$message = json_encode($message, JSON_UNESCAPED_UNICODE);
}
$this->error($message);
}
Kiri::app()->getLogger()->fail($message, $model);
return FALSE;
}
/**
* @return Logger
* @throws Exception
*/
private function logger(): Logger
{
return Kiri::getDi()->get(Logger::class);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function debug(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->debug($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function info(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->info($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function success(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->notice($message, $context);
}
/**
* @param mixed $message
* @param string $method
* @param string $file
* @throws Exception
*/
public function warning(mixed $message, string $method = '', string $file = '')
{
if (!is_string($message)) {
$message = print_r($message, true);
}
$context = [];
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->critical($message, $context);
}
/**
* @param mixed $message
* @param null $method
* @param null $file
* @throws Exception
*/
public function error(mixed $message, $method = null, $file = null)
{
if ($message instanceof \Throwable) {
$message = $message->getMessage() . " on line " . $message->getLine() . " at file " . $message->getFile();
}
$context = [];
if (is_string($method)) {
$message = (empty($method) ? '' : $method . ': ') . $message;
} else {
if (is_null($method)) {
$method = [];
}
$context = $method;
}
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->error($message, $context);
}
}
+128 -124
View File
@@ -1,124 +1,128 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/5/24 0024 * Date: 2018/5/24 0024
* Time: 11:50 * Time: 11:50
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Kiri\Exception\ConfigException;
use Kiri\Exception\ConfigException;
use Kiri\Kiri;
/**
* Class Config
/** * @package Kiri\Kiri\Base
* Class Config */
* @package Kiri\Kiri\Base class Config extends Component
*/ {
class Config extends Component
{ const ERROR_MESSAGE = 'The not find %s in app configs.';
const ERROR_MESSAGE = 'The not find %s in app configs.'; protected static mixed $data = [];
protected mixed $data = [];
/**
* @return mixed
/** */
* @return mixed public static function getData(): mixed
*/ {
public function getData(): mixed return static::$data;
{ }
return $this->data;
}
/**
* @param $key
/** * @param $value
* @param $key * @return mixed
* @param $value */
* @return mixed public static function setData($key, $value): mixed
*/ {
public function setData($key, $value): mixed return static::$data[$key] = $value;
{ }
return $this->data[$key] = $value;
}
/**
* @param array $configs
/** */
* @param array $configs public static function sets(array $configs)
* @throws Exception {
*/ if (empty($configs)) {
public static function sets(array $configs) return;
{ }
$config = Kiri::app()->getConfig(); static::$data = $configs;
if (empty($configs)) { }
return;
} /**
$config->data = $configs; * @param $key
} * @param bool $try
* @param mixed|null $default
/** * @return mixed
* @param $key * @throws ConfigException
* @param bool $try */
* @param mixed|null $default public static function get($key, mixed $default = null, bool $try = FALSE): mixed
* @return mixed {
* @throws $instance = static::$data;
*/ if (!str_contains($key, '.')) {
public static function get($key, mixed $default = null, bool $try = FALSE): mixed return $instance[$key] ?? $default;
{ }
$instance = Kiri::app()->getConfig()->getData(); foreach (explode('.', $key) as $value) {
if (!str_contains($key, '.')) { if (empty($value)) {
return $instance[$key] ?? $default; continue;
} }
foreach (explode('.', $key) as $value) { if (!isset($instance[$value])) {
if (empty($value)) { if ($try) {
continue; throw new ConfigException(sprintf(self::ERROR_MESSAGE, $key));
} }
if (!isset($instance[$value])) { return $default;
if ($try) { }
throw new ConfigException(sprintf(self::ERROR_MESSAGE, $key)); if (!is_array($instance[$value])) {
} return $instance[$value];
return $default; }
} $instance = $instance[$value];
if (!is_array($instance[$value])) { }
return $instance[$value]; return empty($instance) ? $default : $instance;
} }
$instance = $instance[$value];
} /**
return empty($instance) ? $default : $instance; * @param $key
} * @param $value
* @return mixed
/** */
* @param $key public static function set($key, $value): mixed
* @param $value {
* @return mixed $explode = explode('.', $key);
* @throws Exception $parent = &static::$data;
*/ foreach ($explode as $item) {
public static function set($key, $value): mixed if (!isset($parent[$item])) {
{ $parent[$item] = [];
$config = Kiri::app()->getConfig(); }
return $config->setData($key, $value); $parent = &$parent[$item];
} }
$parent = $value;
/**
* @param $key unset($parent);
* @param bool $must_not_null
* @return bool return static::$data;
* @throws Exception }
*/
public static function has($key, bool $must_not_null = false): bool /**
{ * @param $key
$config = Kiri::app()->getConfig(); * @param bool $must_not_null
if (!isset($config->data[$key])) { * @return bool
return false; */
} public static function has($key, bool $must_not_null = false): bool
$config = $config->data[$key]; {
if ($must_not_null === false) { if (!isset(static::$data[$key])) {
return true; return false;
} }
return !empty($config); $config = static::$data[$key];
} if ($must_not_null === false) {
return true;
} }
return !empty($config);
}
}
+18 -18
View File
@@ -1,18 +1,18 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/3/30 0030 * Date: 2018/3/30 0030
* Time: 14:11 * Time: 14:11
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
/** /**
* Interface Configure * Interface Configure
* @package Kiri\Kiri\Base * @package Kiri\Kiri\Base
*/ */
interface Configure interface Configure
{ {
} }
+26 -26
View File
@@ -1,26 +1,26 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Kiri\Core\Dtl; use Kiri\Core\Dtl;
/** /**
* Interface IListener * Interface IListener
* @package Kiri\Abstracts * @package Kiri\Abstracts
*/ */
interface IListener interface IListener
{ {
/** /**
* @param Dtl $dtl * @param Dtl $dtl
* @return mixed * @return mixed
*/ */
public function execute(Dtl $dtl): mixed; public function execute(Dtl $dtl): mixed;
} }
+111 -111
View File
@@ -1,111 +1,111 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
class Input class Input
{ {
private array $_argv = []; private array $_argv = [];
private string $_command = ''; private string $_command = '';
/** /**
* Input constructor. * Input constructor.
* @param $argv * @param $argv
* @throws * @throws
*/ */
public function __construct($argv) public function __construct($argv)
{ {
$this->_argv = $this->resolve($argv); $this->_argv = $this->resolve($argv);
} }
/** /**
* @return string * @return string
*/ */
public function getCommandName(): string public function getCommandName(): string
{ {
return $this->_command; return $this->_command;
} }
/** /**
* @param $key * @param $key
* @param null $default * @param null $default
* @return mixed * @return mixed
*/ */
public function get($key, $default = null): mixed public function get($key, $default = null): mixed
{ {
return $this->_argv[$key] ?? $default; return $this->_argv[$key] ?? $default;
} }
/** /**
* @param $key * @param $key
* @return bool * @return bool
*/ */
public function exists($key): bool public function exists($key): bool
{ {
return isset($this->_argv[$key]); return isset($this->_argv[$key]);
} }
/** /**
* @param $key * @param $key
* @param $value * @param $value
* @return $this * @return $this
*/ */
public function set($key, $value): static public function set($key, $value): static
{ {
$this->_argv[$key] = $value; $this->_argv[$key] = $value;
return $this; return $this;
} }
/** /**
* @return false|string * @return false|string
*/ */
public function toJson(): bool|string public function toJson(): bool|string
{ {
return json_encode($this->_argv, JSON_UNESCAPED_UNICODE); return json_encode($this->_argv, JSON_UNESCAPED_UNICODE);
} }
/** /**
* @param $parameters * @param $parameters
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function resolve($parameters): array public function resolve($parameters): array
{ {
$arrays = []; $arrays = [];
$parameters = array_slice($parameters, 1); $parameters = array_slice($parameters, 1);
if (empty($parameters)) { if (empty($parameters)) {
return $arrays; return $arrays;
} }
$this->_command = array_shift($parameters); $this->_command = array_shift($parameters);
foreach ($parameters as $parameter) { foreach ($parameters as $parameter) {
$explode = explode('=', $parameter); $explode = explode('=', $parameter);
if (count($explode) < 2) { if (count($explode) < 2) {
continue; continue;
} }
$arrays[array_shift($explode)] = current($explode); $arrays[array_shift($explode)] = current($explode);
} }
return $arrays; return $arrays;
} }
/** /**
* @return string * @return string
*/ */
public function getCommand(): string public function getCommand(): string
{ {
return $this->_command; return $this->_command;
} }
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
interface Kernel interface Kernel
{ {
/** /**
* @return array * @return array
*/ */
public function getCommands(): array; public function getCommands(): array;
} }
+18 -18
View File
@@ -1,18 +1,18 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Exception; use Exception;
/** /**
* Class Listener * Class Listener
* @package Kiri\Abstracts * @package Kiri\Abstracts
* 监听的名称 * 监听的名称
*/ */
abstract class Listener extends Component implements IListener abstract class Listener extends Component implements IListener
{ {
} }
+229 -201
View File
@@ -1,201 +1,229 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Annotation\Inject; use DirectoryIterator;
use Exception; use Exception;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Psr\Log\LoggerInterface; use Kiri\Kiri;
use Server\Events\OnWorkerStop; use Psr\Log\LoggerInterface;
use ReflectionException;
use Kiri\Server\Events\OnWorkerStop;
/**
*
*/ /**
class Logger implements LoggerInterface *
{ */
class Logger implements LoggerInterface
const EMERGENCY = 'emergency'; {
const ALERT = 'alert';
const CRITICAL = 'critical'; const EMERGENCY = 'emergency';
const ERROR = 'error'; const ALERT = 'alert';
const WARNING = 'warning'; const CRITICAL = 'critical';
const NOTICE = 'notice'; const ERROR = 'error';
const INFO = 'info'; const WARNING = 'warning';
const DEBUG = 'debug'; const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
/**
* @var EventProvider
*/ private array $_loggers = [];
#[Inject(EventProvider::class)]
public EventProvider $eventProvider;
const LOGGER_LEVELS = [Logger::EMERGENCY, Logger::ALERT, Logger::CRITICAL, Logger::ERROR, Logger::WARNING, Logger::NOTICE, Logger::INFO, Logger::DEBUG];
private array $_loggers = [];
/**
const LOGGER_LEVELS = [Logger::EMERGENCY, Logger::ALERT, Logger::CRITICAL, Logger::ERROR, Logger::WARNING, Logger::NOTICE, Logger::INFO, Logger::DEBUG]; * @return void
* @throws ReflectionException
*/
/** public function init()
* 监听事件 {
*/ Kiri::getDi()->get(EventProvider::class)->on(OnWorkerStop::class, [$this, 'onAfterRequest']);
public function init() }
{
$this->eventProvider->on(OnWorkerStop::class, [$this, 'onAfterRequest']);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message *
* @param array $context * 紧急情况
* @throws ConfigException */
* public function emergency($message, array $context = [])
* 紧急情况 {
*/ // TODO: Implement emergency() method.
public function emergency($message, array $context = []) $this->log(Logger::EMERGENCY, $message, $context);
{ }
// TODO: Implement emergency() method.
$this->log(Logger::EMERGENCY, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message *
* @param array $context * 应该警惕的
* @throws ConfigException */
* public function alert($message, array $context = [])
* 应该警惕的 {
*/ // TODO: Implement alert() method.
public function alert($message, array $context = []) $this->log(Logger::ALERT, $message, $context);
{ }
// TODO: Implement alert() method.
$this->log(Logger::ALERT, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message *
* @param array $context * 关键性的日志
* @throws ConfigException */
* public function critical($message, array $context = [])
* 关键性的日志 {
*/ // TODO: Implement critical() method.
public function critical($message, array $context = []) $this->log(Logger::CRITICAL, $message, $context);
{ }
// TODO: Implement critical() method.
$this->log(Logger::CRITICAL, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function error($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement error() method.
public function error($message, array $context = []) $this->log(Logger::ERROR, $message, $context);
{ }
// TODO: Implement error() method.
$this->log(Logger::ERROR, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function warning($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement warning() method.
public function warning($message, array $context = []) $this->log(Logger::WARNING, $message, $context);
{ }
// TODO: Implement warning() method.
$this->log(Logger::WARNING, $message, $context); /**
} * @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function notice($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement notice() method.
public function notice($message, array $context = []) $this->log(Logger::NOTICE, $message, $context);
{ }
// TODO: Implement notice() method.
$this->log(Logger::NOTICE, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function info($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement info() method.
public function info($message, array $context = []) $this->log(Logger::INFO, $message, $context);
{ }
// TODO: Implement info() method.
$this->log(Logger::INFO, $message, $context);
} /**
* @param string $message
* @param array $context
/** * @throws ConfigException
* @param string $message */
* @param array $context public function debug($message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement debug() method.
public function debug($message, array $context = []) $this->log(Logger::DEBUG, $message, $context);
{ }
// TODO: Implement debug() method.
$this->log(Logger::DEBUG, $message, $context);
} /**
* @param mixed $level
* @param string $message
/** * @param array $context
* @param mixed $level * @throws ConfigException
* @param string $message */
* @param array $context public function log($level, $message, array $context = [])
* @throws ConfigException {
*/ // TODO: Implement log() method.
public function log($level, $message, array $context = []) $levels = Config::get('log.level', Logger::LOGGER_LEVELS);
{ if (!in_array($level, $levels) || str_contains($message, 'Event::rshutdown')) {
// TODO: Implement log() method. return;
$levels = Config::get('log.level', Logger::LOGGER_LEVELS); }
if (!in_array($level, $levels)) {
return; $_string = '[' . now() . '] production.' . $level . ': ' . $this->_string($message, $context);
}
file_put_contents('php://output', $_string);
$_string = '[' . now() . '] production.' . $level . ': ' . $this->_string($message, $context);
$this->_loggers[] = $_string;
file_put_contents('php://output', $_string); }
$this->_loggers[] = $_string;
} /**
* @param OnWorkerStop $param
* @throws Exception
/** */
* @param OnWorkerStop $param public function onAfterRequest(OnWorkerStop $param)
* @throws Exception {
*/ $loggers = implode(PHP_EOL, $this->_loggers);
public function onAfterRequest(OnWorkerStop $param) $this->_loggers = [];
{ if (!empty($loggers)) {
$loggers = implode(PHP_EOL, $this->_loggers); $filename = storage('log-' . date('Y-m-d') . '.log', 'log/');
$this->_loggers = [];
if (!empty($loggers)) { file_put_contents($filename, $loggers);
$filename = storage('log-' . date('Y-m-d') . '.log', 'logs/'); }
}
file_put_contents($filename, $loggers);
}
} /**
* @return void
* @throws Exception
/** */
* @param $message public function flush()
* @param $context {
* @return string $this->removeFile(storage());
*/ }
private function _string($message, $context): string
{
if (!empty($context)) { /**
return $message . ' ' . print_r($context, true) . PHP_EOL; * @param string $dirname
} * @return void
return $message . PHP_EOL; */
} private function removeFile(string $dirname)
} {
$paths = new DirectoryIterator($dirname);
/** @var DirectoryIterator $path */
foreach ($paths as $path) {
if ($path->isDot() || str_starts_with($path->getFilename(), '.')) {
continue;
}
if ($path->isDir()) {
$directory = rtrim($path->getRealPath(), '/');
$this->removeFile($directory);
}
@unlink($path->getRealPath());
}
}
/**
* @param $message
* @param $context
* @return string
*/
private function _string($message, $context): string
{
if (!empty($context)) {
return $message . ' ' . PHP_EOL . print_r($context, TRUE) . PHP_EOL;
}
return $message . PHP_EOL;
}
}
+14 -14
View File
@@ -1,14 +1,14 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Kiri\Application; use Kiri\Application;
interface Provider interface Provider
{ {
public function onImport(Application $application); public function onImport(Application $application);
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
/** /**
* Class Providers * Class Providers
* @package Kiri\Abstracts * @package Kiri\Abstracts
*/ */
abstract class Providers extends Component implements Provider abstract class Providers extends Component implements Provider
{ {
} }
+32 -37
View File
@@ -1,37 +1,32 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Annotation\Annotation as SAnnotation; use Kiri\Annotation\Annotation as SAnnotation;
use Database\Connection; use Database\Connection;
use Database\DatabasesProviders; use Database\DatabasesProviders;
use Http\Handler\Client\Client; use Kiri\Message\Handler\Router;
use Http\Handler\Client\Curl; use Kiri\Server\Server;
use Http\Handler\Router; use Kiri\Async;
use Server\Server; use Kiri\Error\Logger;
use Kiri\Crontab\Producer; use Kiri\Jwt\JWTAuth;
use Kiri\Async;
use Kiri\Error\Logger; /**
use Kiri\Jwt\Jwt; * Trait TraitApplication
* @package Kiri\Abstracts
/** * @property Router $router
* Trait TraitApplication * @property Server $server
* @package Kiri\Abstracts * @property DatabasesProviders $db
* @property Router $router * @property Async $async
* @property Server $server * @property Logger $logger
* @property DatabasesProviders $db * @property JWTAuth $jwt
* @property Async $async * @property SAnnotation $annotation
* @property Logger $logger * @property BaseGoto $goto
* @property Jwt $jwt * @property Connection $databases
* @property SAnnotation $annotation */
* @property BaseGoto $goto trait TraitApplication
* @property Client $client {
* @property Connection $databases
* @property Curl $curl }
*/
trait TraitApplication
{
}
+253 -256
View File
@@ -1,256 +1,253 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/25 0025 * Date: 2018/4/25 0025
* Time: 18:38 * Time: 18:38
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri; namespace Kiri;
use Closure; use Closure;
use Database\DatabasesProviders; use Database\DatabasesProviders;
use Exception; use Exception;
use Kiri\Abstracts\BaseApplication; use Kiri\Abstracts\{BaseApplication, Config, Kernel};
use Kiri\Abstracts\Config; use Kiri\Crontab\CrontabProviders;
use Kiri\Abstracts\Kernel; use Kiri\Events\{OnAfterCommandExecute, OnBeforeCommandExecute};
use Kiri\Crontab\CrontabProviders; use Kiri\FileListen\HotReload;
use Kiri\Events\OnAfterCommandExecute; use ReflectionException;
use Kiri\Events\OnBeforeCommandExecute; use Kiri\Server\ServerProviders;
use Kiri\Exception\NotFindClassException; use stdClass;
use Kiri\FileListen\HotReload; use Swoole\Process;
use ReflectionException; use Swoole\Timer;
use Server\ServerProviders; use Symfony\Component\Console\{Application as ConsoleApplication,
use stdClass; Command\Command,
use Swoole\Process; Input\ArgvInput,
use Swoole\Timer; Input\InputInterface,
use Symfony\Component\Console\Application as ConsoleApplication; Output\ConsoleOutput,
use Symfony\Component\Console\Command\Command; Output\OutputInterface
use Symfony\Component\Console\Input\ArgvInput; };
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput; /**
* Class Init
/** *
* Class Init * @package Kiri
* *
* @package Kiri * @property-read Config $config
* */
* @property-read Config $config class Application extends BaseApplication
*/ {
class Application extends BaseApplication
{ /**
* @var string
/** */
* @var string public string $id = 'uniqueId';
*/
public string $id = 'uniqueId';
public string $state = '';
public string $state = '';
/** @var array<array<Process>> */
private array $_process = [];
/** @var array<array<Process>> */
private array $_process = [];
/**
*/
/** public function init()
*/ {
public function init() $this->import(ServerProviders::class);
{
$this->import(ServerProviders::class); $this->register(Runtime::class);
}
$this->register(Runtime::class);
}
/**
* @throws
/** */
* @throws public function withDatabase()
*/ {
public function withDatabase() $this->import(DatabasesProviders::class);
{ }
$this->import(DatabasesProviders::class);
}
/**
* @throws
/** */
* @throws public function withCrontab()
*/ {
public function withCrontab() $this->import(CrontabProviders::class);
{ }
$this->import(CrontabProviders::class);
}
/**
* @param string $class
/** * @param Process $process
* @param string $class */
* @param Process $process public function addProcess(string $class, Process $process)
*/ {
public function addProcess(string $class, Process $process) }
{
}
/**
* @return Process[]
/** */
* @return Process[] public function getProcess(): array
*/ {
public function getProcess(): array return $this->_process;
{ }
return $this->_process;
}
/**
* @param string $class
/** * @return Process|null
* @param string $class */
* @return Process|null public function getProcessName(string $class): ?Process
*/ {
public function getProcessName(string $class): ?Process return $this->_process[$class] ?? null;
{ }
return $this->_process[$class] ?? null;
}
/**
* @throws
/** */
* @throws public function withFileChangeListen()
*/ {
public function withFileChangeListen() $container = Kiri::getDi();
{
$container = Kiri::getDi(); $console = $container->get(ConsoleApplication::class);
$console->add($container->get(HotReload::class));
$console = $container->get(ConsoleApplication::class); }
$console->add($container->get(HotReload::class));
}
/**
* @param Closure|array $closure
/** * @return $this
* @param Closure|array $closure * @throws Exception
* @return $this */
* @throws Exception public function middleware(Closure|array $closure): static
*/ {
public function middleware(Closure|array $closure): static return $this;
{ }
return $this;
}
/**
* @param bool $useTree
/** * @return $this
* @param bool $useTree * @throws Exception
* @return $this */
* @throws Exception public function setUseTree(bool $useTree): static
*/ {
public function setUseTree(bool $useTree): static return $this;
{ }
return $this;
}
/**
* @param string $service
/** * @return $this
* @param string $service * @throws
* @return $this */
* @throws public function import(string $service): static
*/ {
public function import(string $service): static if (!class_exists($service)) {
{ return $this;
if (!class_exists($service)) { }
return $this; $class = Kiri::getDi()->get($service);
} if (method_exists($class, 'onImport')) {
$class = Kiri::getDi()->get($service); $class->onImport($this);
if (method_exists($class, 'onImport')) { }
$class->onImport($this); return $this;
} }
return $this;
}
/**
* @param Kernel $kernel
/** * @return $this
* @param Kernel $kernel */
* @return $this public function commands(Kernel $kernel): static
*/ {
public function commands(Kernel $kernel): static foreach ($kernel->getCommands() as $command) {
{ $this->register($command);
foreach ($kernel->getCommands() as $command) { }
$this->register($command); return $this;
} }
return $this;
}
/**
* @param string $command
/** * @throws
* @param string $command */
* @throws public function register(string $command)
*/ {
public function register(string $command) di(ConsoleApplication::class)->add(di($command));
{ }
di(ConsoleApplication::class)->add(di($command));
}
/**
* @param array $argv
/** * @return void
* @param array $argv */
* @return void public function execute(array $argv): void
*/ {
public function execute(array $argv): void ini_set('swoole.enable_preemptive_scheduler', 'On');
{ ini_set('swoole.enable_library', 'On');
/** @var InputInterface $input */ [$input, $output] = $this->argument($argv);
[$input, $output] = $this->argument($argv); try {
try { $console = di(ConsoleApplication::class);
$console = di(ConsoleApplication::class); $command = $input->getFirstArgument();
$command = $input->getFirstArgument(); if (empty($command)) {
if (empty($command)) { $command = 'sw:server';
$command = 'sw:server'; }
} $command = $console->find($command);
$command = $console->find($command); if ($command instanceof Command) {
if ($command instanceof Command) { $this->enableFileChange($command, $input, $output);
$this->enableFileChange($command, $input, $output); }
} } catch (\Throwable $exception) {
} catch (\Throwable $exception) { $output->writeln(jTraceEx($exception));
$output->writeln(jTraceEx($exception)); } finally {
} finally { Timer::clearAll();
Timer::clearAll(); }
} }
}
/**
* @param $argv
/** * @return array
* @param $argv */
* @return array private function argument($argv): array
*/ {
private function argument($argv): array return [new ArgvInput($argv), new ConsoleOutput()];
{ }
return [new ArgvInput($argv), new ConsoleOutput()];
}
/**
* @throws ReflectionException
* @throws Exception
/** */
* @throws NotFindClassException private function enableFileChange(Command $class, $input, $output): void
* @throws ReflectionException {
* @throws Exception fire(new OnBeforeCommandExecute());
*/ if (!($class instanceof HotReload)) {
private function enableFileChange(Command $class, $input, $output): void scan_directory(directory('app'), 'App');
{ }
fire(new OnBeforeCommandExecute());
if (!($class instanceof HotReload)) { $this->container->setBindings(OutputInterface::class, $output);
scan_directory(directory('app'), 'App');
} $class->run($input, $output);
$class->run($input, $output); fire(new OnAfterCommandExecute());
fire(new OnAfterCommandExecute()); $output->writeln('ok' . PHP_EOL);
$output->writeln('ok' . PHP_EOL); }
}
/**
* @param $className
* @param null $abstracts
/** * @return stdClass
* @param $className * @throws Exception
* @param null $abstracts */
* @return stdClass public function make($className, $abstracts = null): stdClass
* @throws Exception {
*/ return make($className, $abstracts);
public function make($className, $abstracts = null): stdClass }
{ }
return make($className, $abstracts);
}
}
+44 -43
View File
@@ -1,43 +1,44 @@
<?php <?php
namespace Kiri; namespace Kiri;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Server\ServerManager; use Kiri\Server\ServerManager;
use Kiri\Server\Tasker\AsyncTaskExecute;
/**
* Class Async /**
* @package Kiri * Class Async
*/ * @package Kiri
class Async extends Component */
{ class Async extends Component
{
private static array $_absences = [];
private static array $_absences = [];
/**
* @param string $name /**
* @param string $handler * @param string $name
*/ * @param string $handler
public function addAsync(string $name, string $handler) */
{ public function addAsync(string $name, string $handler)
static::$_absences[$name] = $handler; {
} static::$_absences[$name] = $handler;
}
/**
* @param string $name /**
* @param array $params * @param string $name
* @throws Exception * @param array $params
*/ * @throws Exception
public function dispatch(string $name, array $params = []) */
{ public function dispatch(string $name, array $params = [])
$context = di(ServerManager::class); {
$context->task(static::$_absences[$name], $params); $context = di(AsyncTaskExecute::class);
} $context->execute(static::$_absences[$name], $params);
}
}
}
+171 -152
View File
@@ -1,152 +1,171 @@
<?php <?php
namespace Kiri\Cache\Base; namespace Kiri\Cache\Base;
use Kiri\Abstracts\Logger; use Exception;
use Kiri\Exception\RedisConnectException; use Kiri\Abstracts\Logger;
use Kiri\Kiri; use Kiri\Exception\RedisConnectException;
use Kiri\Pool\StopHeartbeatCheck; use Kiri\Kiri;
use RedisException; use Kiri\Pool\StopHeartbeatCheck;
use Kiri\Context; use RedisException;
use Swoole\Timer; use Swoole\Timer;
/** /**
* *
*/ */
class Redis implements StopHeartbeatCheck class Redis implements StopHeartbeatCheck
{ {
const DB_ERROR_MESSAGE = 'The system is busy, please try again later.'; const DB_ERROR_MESSAGE = 'The system is busy, please try again later.';
private ?\Redis $pdo = null; private ?\Redis $pdo = null;
public string $host;
private int $_transaction = 0;
public int $port;
private int $_timer = -1; public int $database = 0;
private int $_last = 0; public string $auth = '';
public string $prefix = '';
/**
* @param string $host public int $timeout = 30;
* @param int $port
* @param int $database public int $read_timeout = 30;
* @param string $auth
* @param string $prefix public array $pool = [];
* @param int $timeout
* @param int $read_timeout private int $_timer = -1;
*/
public function __construct(public string $host, public int $port, public int $database = 0, private int $_last = 0;
public string $auth = '', public string $prefix = '', public int $timeout = 30,
public int $read_timeout = 30)
{ /**
} * @param array $config
*/
public function __construct(array $config)
public function init() {
{ $this->host = $config['host'];
$this->heartbeat_check(); $this->port = $config['port'];
} $this->database = $config['databases'];
$this->auth = $config['auth'];
$this->prefix = $config['prefix'];
/** $this->timeout = $config['timeout'];
* $this->read_timeout = $config['read_timeout'];
*/ $this->pool = $config['pool'];
public function heartbeat_check(): void }
{
if (env('state', 'start') == 'exit') {
return; public function init()
} {
if ($this->_timer === -1 && Context::inCoroutine()) { $this->heartbeat_check();
$this->_timer = Timer::tick(1000, function () { }
try {
if (env('state', 'start') == 'exit') {
Kiri::getDi()->get(Logger::class)->critical('timer end'); /**
$this->stopHeartbeatCheck(); *
} */
if (time() - $this->_last > 10 * 60) { public function heartbeat_check(): void
$this->stopHeartbeatCheck(); {
$this->pdo = null; if (env('state', 'start') == 'exit') {
} return;
} catch (\Throwable $throwable) { }
error($throwable); if ($this->_timer === -1) {
} $this->_timer = Timer::tick(1000, fn() => $this->waite());
}); }
} }
}
/**
/** * @throws Exception
* */
*/ private function waite(): void
public function stopHeartbeatCheck(): void {
{ try {
if ($this->_timer > -1) { if (env('state', 'start') == 'exit') {
Timer::clear($this->_timer); Kiri::getDi()->get(Logger::class)->critical('timer end');
} $this->stopHeartbeatCheck();
$this->_timer = -1; }
} if (time() - $this->_last > intval($this->pool['tick'] ?? 60)) {
$this->stopHeartbeatCheck();
$this->pdo = null;
/** }
* @param string $name } catch (\Throwable $throwable) {
* @param array $arguments error($throwable);
* @return mixed }
* @throws RedisConnectException|RedisException }
*/
public function __call(string $name, array $arguments)
{ /**
if (!method_exists($this, $name)) { *
return $this->_pdo()->{$name}(...$arguments); */
} public function stopHeartbeatCheck(): void
return $this->{$name}(...$arguments); {
} if ($this->_timer > -1) {
Timer::clear($this->_timer);
}
/** $this->_timer = -1;
* @return \Redis }
* @throws RedisConnectException
* @throws RedisException
*/ /**
public function _pdo(): \Redis * @param string $name
{ * @param array $arguments
if ($this->_timer === -1) { * @return mixed
$this->heartbeat_check(); * @throws RedisConnectException|RedisException
} */
if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) { public function __call(string $name, array $arguments)
$this->pdo = $this->newClient(); {
} if (!method_exists($this, $name)) {
return $this->pdo; return $this->_pdo()->{$name}(...$arguments);
} }
return $this->{$name}(...$arguments);
}
/**
* @return \Redis
* @throws RedisConnectException /**
*/ * @return \Redis
private function newClient(): \Redis * @throws RedisConnectException
{ * @throws RedisException
$redis = new \Redis(); */
if (!$redis->connect($this->host, $this->port, $this->timeout)) { public function _pdo(): \Redis
throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port)); {
} if ($this->_timer === -1) {
if (!empty($this->auth) && !$redis->auth($this->auth)) { $this->heartbeat_check();
throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $this->host, $this->auth)); }
} if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) {
if ($this->read_timeout < 0) { $this->pdo = $this->newClient();
$this->read_timeout = 0; }
} return $this->pdo;
$redis->select($this->database); }
if ($this->read_timeout > 0) {
$redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout);
} /**
$redis->setOption(\Redis::OPT_PREFIX, $this->prefix); * @return \Redis
return $redis; * @throws RedisConnectException
*/
} private function newClient(): \Redis
{
} $redis = new \Redis();
if (!$redis->connect($this->host, $this->port, $this->timeout)) {
throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port));
}
if (!empty($this->auth) && !$redis->auth($this->auth)) {
throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $this->host, $this->auth));
}
if ($this->read_timeout < 0) {
$this->read_timeout = 0;
}
$redis->select($this->database);
if ($this->read_timeout > 0) {
$redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout);
}
$redis->setOption(\Redis::OPT_PREFIX, $this->prefix);
return $redis;
}
}
+141 -141
View File
@@ -1,141 +1,141 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/5/2 0002 * Date: 2018/5/2 0002
* Time: 14:51 * Time: 14:51
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Cache;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Swoole\Coroutine\System; use Swoole\Coroutine\System;
/** /**
* Class File * Class File
* @package Kiri\Kiri\Cache * @package Kiri\Kiri\Cache
*/ */
class File extends Component implements ICache class File extends Component implements ICache
{ {
public string $path; public string $path;
/** /**
* @param $key * @param $key
* @param $val * @param $val
* @return string|int * @return string|int
*/ */
public function set($key, $val): string|int public function set($key, $val): string|int
{ {
if (is_array($val) || is_object($val)) { if (is_array($val) || is_object($val)) {
$val = swoole_serialize($val); $val = swoole_serialize($val);
} }
$tmpFile = $this->getCacheKey($key); $tmpFile = $this->getCacheKey($key);
if (!$this->exists($tmpFile)) { if (!$this->exists($tmpFile)) {
touch($tmpFile); touch($tmpFile);
} }
return System::writeFile($tmpFile, $val, LOCK_EX); return System::writeFile($tmpFile, $val, LOCK_EX);
} }
/** /**
* @param $key * @param $key
* @param array $hashKeys * @param array $hashKeys
* @return array|bool * @return array|bool
*/ */
public function hMGet($key, array $hashKeys): array|bool public function hMGet($key, array $hashKeys): array|bool
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
$nowHash = []; $nowHash = [];
foreach ($hashKeys as $hashKey) { foreach ($hashKeys as $hashKey) {
$nowHash[$hashKey] = $hash[$hashKey] ?? null; $nowHash[$hashKey] = $hash[$hashKey] ?? null;
} }
return $nowHash; return $nowHash;
} }
/** /**
* @param $key * @param $key
* @param array $val * @param array $val
* @return bool|int|string * @return bool|int|string
*/ */
public function hMSet($key, array $val): bool|int|string public function hMSet($key, array $val): bool|int|string
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
$merge = array_merge($hash, $val); $merge = array_merge($hash, $val);
return $this->set($key, $merge); return $this->set($key, $merge);
} }
/** /**
* @param string $key * @param string $key
* @param string $hashKey * @param string $hashKey
* @return string|int|bool * @return string|int|bool
*/ */
public function hGet(string $key, string $hashKey): string|int|bool public function hGet(string $key, string $hashKey): string|int|bool
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
return $hash[$hashKey] ?? false; return $hash[$hashKey] ?? false;
} }
/** /**
* @param $key * @param $key
* @param $hashKey * @param $hashKey
* @param $hashValue * @param $hashValue
* @return bool|int|string * @return bool|int|string
*/ */
public function hSet($key, $hashKey, $hashValue): bool|int|string public function hSet($key, $hashKey, $hashValue): bool|int|string
{ {
$hash = $this->get($key); $hash = $this->get($key);
if (!is_array($hash)) { if (!is_array($hash)) {
return false; return false;
} }
$hash[$hashKey] = $hashValue; $hash[$hashKey] = $hashValue;
return $this->set($key, $hash); return $this->set($key, $hash);
} }
/** /**
* @param $key * @param $key
* @return bool * @return bool
*/ */
#[Pure] public function exists($key): bool #[Pure] public function exists($key): bool
{ {
return file_exists($key); return file_exists($key);
} }
/** /**
* @param $key * @param $key
* @return mixed|bool * @return mixed|bool
*/ */
public function get($key): string|bool public function get($key): string|bool
{ {
$tmpFile = $this->getCacheKey($key); $tmpFile = $this->getCacheKey($key);
if (!$this->exists($tmpFile)) { if (!$this->exists($tmpFile)) {
return false; return false;
} }
$content = file_get_contents($tmpFile); $content = file_get_contents($tmpFile);
return swoole_unserialize($content); return swoole_unserialize($content);
} }
/** /**
* @param $key * @param $key
* @return string * @return string
* @throws * @throws
*/ */
private function getCacheKey($key): string private function getCacheKey($key): string
{ {
return storage($key, 'cache'); return storage($key, 'cache');
} }
} }
+65 -65
View File
@@ -1,65 +1,65 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/11/8 0008 * Date: 2018/11/8 0008
* Time: 16:35 * Time: 16:35
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Cache;
/** /**
* Interface ICache * Interface ICache
* @package Kiri\Kiri\Cache * @package Kiri\Kiri\Cache
*/ */
interface ICache interface ICache
{ {
/** /**
* @param $key * @param $key
* @param $val * @param $val
* @return string|int * @return string|int
*/ */
public function set($key, $val): string|int; public function set($key, $val): string|int;
/** /**
* @param $key * @param $key
* @return string|int|bool * @return string|int|bool
*/ */
public function get($key): string|int|bool; public function get($key): string|int|bool;
/** /**
* @param $key * @param $key
* @param array $hashKeys * @param array $hashKeys
* @return array|bool|null * @return array|bool|null
*/ */
public function hMGet($key, array $hashKeys): array|bool|null; public function hMGet($key, array $hashKeys): array|bool|null;
/** /**
* @param $key * @param $key
* @param array $val * @param array $val
* @return mixed * @return mixed
*/ */
public function hMSet($key, array $val): mixed; public function hMSet($key, array $val): mixed;
/** /**
* @param string $key * @param string $key
* @param string $hashKey * @param string $hashKey
* @return string|int|bool * @return string|int|bool
*/ */
public function hGet(string $key, string $hashKey): string|int|bool; public function hGet(string $key, string $hashKey): string|int|bool;
/** /**
* @param $key * @param $key
* @param $hashKey * @param $hashKey
* @param $hashValue * @param $hashValue
* @return mixed * @return mixed
*/ */
public function hSet($key, $hashKey, $hashValue): mixed; public function hSet($key, $hashKey, $hashValue): mixed;
/** /**
* @param $key * @param $key
* @return bool * @return bool
*/ */
public function exists($key): bool; public function exists($key): bool;
} }
+186 -160
View File
@@ -1,160 +1,186 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/27 0027 * Date: 2018/4/27 0027
* Time: 11:00 * Time: 11:00
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Cache; namespace Kiri\Cache;
use Annotation\Inject; use Exception;
use Exception; use Kiri\Abstracts\Component;
use Server\Events\OnWorkerExit; use Kiri\Abstracts\Config;
use Kiri\Abstracts\Component; use Kiri\Core\Json;
use Kiri\Abstracts\Config; use Kiri\Events\EventProvider;
use Kiri\Core\Json; use Kiri\Exception\ConfigException;
use Kiri\Events\EventProvider; use Kiri\Kiri;
use Kiri\Exception\ConfigException; use Kiri\Pool\Redis as PoolRedis;
use Kiri\Kiri; use Kiri\Annotation\Inject;
use Kiri\Pool\Redis as PoolRedis; use Kiri\Server\Events\OnWorkerExit;
use Swoole\Timer;
/**
* Class Redis /**
* @package Kiri\Kiri\Cache * Class Redis
* @mixin \Redis * @package Kiri\Kiri\Cache
*/ * @mixin \Redis
class Redis extends Component */
{ class Redis extends Component
{
/**
* @var EventProvider
*/ const REDIS_OPTION_HOST = 'host';
#[Inject(EventProvider::class)] const REDIS_OPTION_PORT = 'port';
public EventProvider $eventProvider; const REDIS_OPTION_PREFIX = 'prefix';
const REDIS_OPTION_AUTH = 'auth';
const REDIS_OPTION_DATABASES = 'databases';
/** const REDIS_OPTION_TIMEOUT = 'timeout';
* @throws ConfigException const REDIS_OPTION_POOL = 'pool';
* @throws Exception const REDIS_OPTION_POOL_TICK = 'tick';
*/ const REDIS_OPTION_POOL_MIN = 'min';
public function init() const REDIS_OPTION_POOL_MAX = 'max';
{
$connections = Kiri::getDi()->get(PoolRedis::class);
/**
$config = $this->get_config(); * @throws ConfigException
* @throws Exception
$length = Config::get('connections.pool.max', 10); */
public function init()
$this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0); {
$connections = Kiri::getDi()->get(PoolRedis::class);
$connections->initConnections('Redis:' . $config['host'], true, $length);
} $config = $this->get_config();
$length = Config::get('cache.redis.pool.max', 10);
/**
* @param $name $this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0);
* @param $arguments
* @return mixed $connections->initConnections('Redis:' . $config['host'], true, $length);
* @throws }
*/
public function __call($name, $arguments): mixed
{ /**
$time = microtime(true); * @param $name
if (method_exists($this, $name)) { * @param $arguments
$data = $this->{$name}(...$arguments); * @return mixed
} else { * @throws
$data = $this->proxy($name, $arguments); */
} public function __call($name, $arguments): mixed
if (microtime(true) - $time >= 0.02) { {
$this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time)); $time = microtime(true);
} if (method_exists($this, $name)) {
return $data; $data = $this->{$name}(...$arguments);
} } else {
$data = $this->proxy($name, $arguments);
}
/** if (microtime(true) - $time >= 0.02) {
* @param $key $this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time));
* @param int $timeout }
* @return bool|int return $data;
* @throws Exception }
*/
public function lock($key, int $timeout = 5): bool|int
{ /**
$script = <<<SCRIPT * @param $key
local _nx = redis.call('setnx',KEYS[1], ARGV[1]) * @param int $timeout
if (_nx ~= 0) then * @return bool
redis.call('expire',KEYS[1], ARGV[1]) */
return 1 public function waite($key, int $timeout = 5): bool
end {
return 0 $time = time();
SCRIPT; while (!$this->setNx($key, 1)) {
return $this->eval($script, ['{lock}:' . $key, $timeout], 1); if (time()- $time >= $timeout) {
} return FALSE;
}
usleep(1000);
/** }
* @param $key $this->expire($key, $timeout);
* @return int return TRUE;
* @throws Exception }
*/
public function unlock($key): int
{ /**
return $this->del('{lock}:' . $key); * @param $key
} * @param int $timeout
* @return bool|int
* @throws Exception
/** */
* @throws ConfigException public function lock($key, int $timeout = 5): bool|int
* @throws Exception {
*/ $script = <<<SCRIPT
public function release() local _nx = redis.call('setnx',KEYS[1], ARGV[1])
{ if (_nx ~= 0) then
$connections = Kiri::getDi()->get(PoolRedis::class); redis.call('expire',KEYS[1], ARGV[1])
$connections->release($this->get_config(), true); return 1
} end
return 0
/** SCRIPT;
* 销毁连接池 return $this->eval($script, ['{lock}:' . $key, $timeout], 1);
* @throws ConfigException }
* @throws Exception
*/
public function destroy() /**
{ * @param $key
$connections = Kiri::getDi()->get(PoolRedis::class); * @return int
$connections->connection_clear($this->get_config(), true); * @throws Exception
} */
public function unlock($key): int
/** {
* @param $name return $this->del('{lock}:' . $key);
* @param $arguments }
* @return mixed
* @throws ConfigException
* @throws Exception /**
*/ * @throws ConfigException
public function proxy($name, $arguments): mixed * @throws Exception
{ */
$connections = Kiri::getDi()->get(PoolRedis::class); public function release()
{
$config = $this->get_config(); $connections = Kiri::getDi()->get(PoolRedis::class);
$connections->release($this->get_config(), true);
$client = $connections->get($config, true); }
if (!($client instanceof Base\Redis)) {
throw new Exception('Redis connections more.'); /**
} * 销毁连接池
$response = $client->{$name}(...$arguments); * @throws ConfigException
$this->release(); * @throws Exception
return $response; */
} public function destroy()
{
/** $connections = Kiri::getDi()->get(PoolRedis::class);
* @return array $connections->connection_clear($this->get_config(), true);
* @throws ConfigException }
*/
public function get_config(): array /**
{ * @param $name
return Config::get('cache.redis', null, true); * @param $arguments
} * @return mixed
* @throws ConfigException
} * @throws Exception
*/
public function proxy($name, $arguments): mixed
{
$connections = Kiri::getDi()->get(PoolRedis::class);
$config = $this->get_config();
$client = $connections->get($config, true);
if (!($client instanceof Base\Redis)) {
throw new Exception('Redis connections more.');
}
$response = $client->{$name}(...$arguments);
$this->release();
return $response;
}
/**
* @return array
* @throws ConfigException
*/
public function get_config(): array
{
return Config::get('cache.redis', null, true);
}
}
+209 -189
View File
@@ -1,189 +1,209 @@
<?php <?php
namespace Kiri; namespace Kiri;
use Kiri\Abstracts\BaseContext; use Kiri\Abstracts\BaseContext;
use Swoole\Coroutine; use Swoole\Coroutine;
/** /**
* Class Context * Class Context
* @package Yoc\http * @package Yoc\http
*/ */
class Context extends BaseContext class Context extends BaseContext
{ {
protected static array $_contents = []; protected static array $_contents = [];
/** /**
* @param $id * @param $id
* @param $context * @param $context
* @param null $coroutineId * @param null $coroutineId
* @return mixed * @return mixed
*/ */
public static function setContext($id, $context, $coroutineId = null): mixed public static function setContext($id, $context, $coroutineId = null): mixed
{ {
if (Coroutine::getCid() === -1) { if (is_null($coroutineId)) {
return static::$_contents[$id] = $context; $coroutineId = Coroutine::getCid();
} }
return Coroutine::getContext($coroutineId)[$id] = $context; if (Coroutine::getCid() !== -1) {
} return Coroutine::getContext($coroutineId)[$id] = $context;
}
/** return static::$_contents[$id] = $context;
* @param $id }
* @param int $value
* @param null $coroutineId /**
* @return bool|int * @param $id
*/ * @param int $value
public static function increment($id, int $value = 1, $coroutineId = null): bool|int * @param null $coroutineId
{ * @return bool|int
if (!isset(Coroutine::getContext($coroutineId)[$id])) { */
Coroutine::getContext($coroutineId)[$id] = 0; public static function increment($id, int $value = 1, $coroutineId = null): bool|int
} {
return Coroutine::getContext($coroutineId)[$id] += $value; if (is_null($coroutineId)) {
} $coroutineId = Coroutine::getCid();
}
/** if (!isset(Coroutine::getContext($coroutineId)[$id])) {
* @param $id Coroutine::getContext($coroutineId)[$id] = 0;
* @param int $value }
* @param null $coroutineId return Coroutine::getContext($coroutineId)[$id] += $value;
* @return bool|int }
*/
public static function decrement($id, int $value = 1, $coroutineId = null): bool|int /**
{ * @param $id
if (!isset(Coroutine::getContext($coroutineId)[$id])) { * @param int $value
Coroutine::getContext($coroutineId)[$id] = 0; * @param null $coroutineId
} * @return bool|int
return Coroutine::getContext($coroutineId)[$id] -= $value; */
} public static function decrement($id, int $value = 1, $coroutineId = null): bool|int
{
/** if (is_null($coroutineId)) {
* @param $id $coroutineId = Coroutine::getCid();
* @param null $default }
* @param null $coroutineId if (!isset(Coroutine::getContext($coroutineId)[$id])) {
* @return mixed Coroutine::getContext($coroutineId)[$id] = 0;
*/ }
public static function getContext($id, $default = null, $coroutineId = null): mixed return Coroutine::getContext($coroutineId)[$id] -= $value;
{ }
if (Coroutine::getCid() === -1) {
return static::loadByStatic($id, $default); /**
} * @param $id
return static::loadByContext($id, $default, $coroutineId); * @param null $default
} * @param null $coroutineId
* @return mixed
*/
/** public static function getContext($id, $default = null, $coroutineId = null): mixed
* @param $id {
* @param null $default if (Coroutine::getCid() === -1) {
* @param null $coroutineId return static::loadByStatic($id, $default);
* @return mixed }
*/ return static::loadByContext($id, $default, $coroutineId);
private static function loadByContext($id, $default = null, $coroutineId = null): mixed }
{
return Coroutine::getContext($coroutineId)[$id] ?? $default;
} /**
* @param $id
* @param null $default
/** * @param null $coroutineId
* @param $id * @return mixed
* @param null $default */
* @return mixed private static function loadByContext($id, $default = null, $coroutineId = null): mixed
*/ {
private static function loadByStatic($id, $default = null): mixed if (is_null($coroutineId)) {
{ $coroutineId = Coroutine::getCid();
return static::$_contents[$id] ?? $default; }
} return Coroutine::getContext($coroutineId)[$id] ?? $default;
}
/**
* @param null $coroutineId /**
* @return mixed * @param $id
*/ * @param null $default
public static function getAllContext($coroutineId = null): mixed * @return mixed
{ */
if (Coroutine::getCid() === -1) { private static function loadByStatic($id, $default = null): mixed
return Coroutine::getContext($coroutineId) ?? []; {
} else { return static::$_contents[$id] ?? $default;
return static::$_contents ?? []; }
}
}
/**
/** * @param null $coroutineId
* @param string $id * @return mixed
* @param null $coroutineId */
*/ public static function getAllContext($coroutineId = null): mixed
public static function remove(string $id, $coroutineId = null) {
{ if (Coroutine::getCid() === -1) {
if (!static::hasContext($id, $coroutineId)) { return Coroutine::getContext($coroutineId) ?? [];
return; } else {
} return static::$_contents ?? [];
if (Coroutine::getCid() === -1) { }
unset(static::$_contents[$id]); }
} else {
unset(Coroutine::getContext($coroutineId)[$id]); /**
} * @param string $id
} * @param null $coroutineId
*/
/** public static function remove(string $id, $coroutineId = null)
* @param $id {
* @param null $key if (is_null($coroutineId)) {
* @param null $coroutineId $coroutineId = Coroutine::getCid();
* @return bool }
*/ if (!static::hasContext($id, $coroutineId)) {
public static function hasContext($id, $key = null, $coroutineId = null): bool return;
{ }
if (Coroutine::getCid() === -1) { if (Coroutine::getCid() === -1) {
return static::searchByStatic($id, $key); unset(static::$_contents[$id]);
} } else {
return static::searchByCoroutine($id, $key, $coroutineId); unset(Coroutine::getContext($coroutineId)[$id]);
} }
}
/** /**
* @param $id * @param $id
* @param null $key * @param null $key
* @return bool * @param null $coroutineId
*/ * @return bool
private static function searchByStatic($id, $key = null): bool */
{ public static function hasContext($id, $key = null, $coroutineId = null): bool
if (!isset(static::$_contents[$id])) { {
return false; if (Coroutine::getCid() === -1) {
} return static::searchByStatic($id, $key);
if (!empty($key) && !isset(static::$_contents[$id][$key])) { }
return false; return static::searchByCoroutine($id, $key, $coroutineId);
} }
return true;
}
/**
* @param $id
/** * @param null $key
* @param $id * @return bool
* @param null $key */
* @param null $coroutineId private static function searchByStatic($id, $key = null): bool
* @return bool {
*/ if (!isset(static::$_contents[$id])) {
private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool return false;
{ }
if (!isset(Coroutine::getContext($coroutineId)[$id])) { $value = static::$_contents[$id];
return false; if (!empty($key) && is_array($value)) {
} return isset($value[$key]);
if ($key !== null) { }
return isset((Coroutine::getContext($coroutineId)[$id] ?? [])[$key]); return true;
} }
return true;
}
/**
* @param $id
/** * @param null $key
* @return bool * @param null $coroutineId
*/ * @return bool
public static function inCoroutine(): bool */
{ private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool
return Coroutine::getCid() !== -1; {
} if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid();
} }
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
return false;
}
$value = Coroutine::getContext($coroutineId)[$id];
if ($key !== null && is_array($value)) {
return isset($value[$key]);
}
return true;
}
/**
* @return bool
*/
public static function inCoroutine(): bool
{
return Coroutine::getCid() !== -1;
}
}
+100 -100
View File
@@ -1,100 +1,100 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/4 0004 * Date: 2018/4/4 0004
* Time: 14:57 * Time: 14:57
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class ArrayAccess * Class ArrayAccess
* @package Kiri\Core * @package Kiri\Core
*/ */
class ArrayAccess class ArrayAccess
{ {
/** /**
* @param $data * @param $data
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public static function toArray($data): array public static function toArray($data): array
{ {
if (!is_object($data) && !is_array($data)) { if (!is_object($data) && !is_array($data)) {
return []; return [];
} }
if (is_object($data)) { if (is_object($data)) {
$data = self::objToArray($data); $data = self::objToArray($data);
} }
$tmp = []; $tmp = [];
if (!is_array($data)) { if (!is_array($data)) {
return $tmp; return $tmp;
} }
foreach ($data as $key => $val) { foreach ($data as $key => $val) {
if (is_array($val) || is_object($val)) { if (is_array($val) || is_object($val)) {
$tmp[$key] = self::toArray($val); $tmp[$key] = self::toArray($val);
} else { } else {
$tmp[$key] = $val; $tmp[$key] = $val;
} }
} }
return $tmp; return $tmp;
} }
/** /**
* @param $data * @param $data
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public static function objToArray($data): array public static function objToArray($data): array
{ {
if (!is_object($data)) { if (!is_object($data)) {
return $data; return $data;
} }
if (method_exists($data, 'get')) { if (method_exists($data, 'get')) {
$data = $data->get(); $data = $data->get();
if (is_array($data)) { if (is_array($data)) {
return $data; return $data;
} }
} }
if (method_exists($data, 'toArray')) { if (method_exists($data, 'toArray')) {
$data = $data->toArray(); $data = $data->toArray();
} else { } else {
$data = get_object_vars((object)$data); $data = get_object_vars((object)$data);
} }
return $data; return $data;
} }
/** /**
* @param array $oldArray * @param array $oldArray
* @param array $newArray * @param array $newArray
* @return array * @return array
*/ */
public static function merge(array $oldArray, array $newArray): array public static function merge(array $oldArray, array $newArray): array
{ {
if (empty($oldArray)) { if (empty($oldArray)) {
return $newArray; return $newArray;
} else if (empty($newArray)) { } else if (empty($newArray)) {
return $oldArray; return $oldArray;
} }
foreach ($newArray as $item => $value) { foreach ($newArray as $item => $value) {
if (!isset($oldArray[$item])) { if (!isset($oldArray[$item])) {
$oldArray[$item] = $value; $oldArray[$item] = $value;
} }
if (is_array($value)) { if (is_array($value)) {
$oldArray[$item] = self::merge($oldArray[$item], $value); $oldArray[$item] = self::merge($oldArray[$item], $value);
} else { } else {
$oldArray[$item] = $value; $oldArray[$item] = $value;
} }
} }
return $oldArray; return $oldArray;
} }
} }
+104 -106
View File
@@ -1,106 +1,104 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: dell * User: dell
* Date: 2019/1/14 0014 * Date: 2019/1/14 0014
* Time: 13:50 * Time: 13:50
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
/** /**
* Class DateFormat * Class DateFormat
* @package Kiri\Kiri\Core * @package Kiri\Kiri\Core
*/ */
class DateFormat class DateFormat
{ {
/** /**
* @param $time * @param $time
* @return bool|false|int|string * @return bool|false|int|string
*/ */
private static function check($time): bool|int|string private static function check($time): bool|int|string
{ {
if ($time === null) { if ($time === null) {
$time = time(); $time = time();
} else if (is_numeric($time)) { } else if (is_numeric($time)) {
$length = strlen(floatval($time)); $length = strlen((string)$time);
if ($length != 10 && $length != 13) { if ($length != 10 && $length != 13) {
return false; return false;
} }
} else if (is_string($time)) { } else if (is_string($time)) {
$time = strtotime($time); $time = strtotime($time);
} }
if (date('Y-m-d', $time)) { if (date('Y-m-d', $time)) {
return $time; return $time;
} }
return false; return false;
} }
/** /**
* @param null $time * @param null $time
* @return bool|false|int * @return bool|false|int
* *
* 获取指定日期当周第一天的时间 * 获取指定日期当周第一天的时间
*/ */
public static function getWeekCurrentDay($time = null): bool|int public static function getWeekCurrentDay($time = null): bool|int
{ {
if (!($time = static::check($time))) { if (!($time = static::check($time))) {
return false; return false;
} }
$time = strtotime('-' . (date('N') - 1) . 'days', $time); $time = strtotime('-' . (date('N') - 1) . 'days', $time);
return strtotime(date('Y-m-d'), $time); return strtotime(date('Y-m-d'), $time);
} }
/** /**
* @param null $time * @param null $time
* @return bool|false|int * @return bool|false|int
* *
* 获取指定日期当月第一天的时间 * 获取指定日期当月第一天的时间
*/ */
public static function getMonthCurrentDay($time = null): bool|int public static function getMonthCurrentDay($time = null): bool|int
{ {
if (!($time = static::check($time))) { if (!($time = static::check($time))) {
return false; return false;
} }
return strtotime(date('Y-m', $time) . '-01'); return strtotime(date('Y-m', $time) . '-01');
} }
/** /**
* @param $time * @param $time
* @return bool|int|string 指定的月份有几天 * @return bool|int|string 指定的月份有几天
* 指定的月份有几天 * 指定的月份有几天
*/ */
public static function getMonthTotalDay($time): bool|int|string public static function getMonthTotalDay($time): bool|int|string
{ {
if (!($time = static::check($time))) { if (!($time = static::check($time))) {
return false; return false;
} }
$time = date('t', $time); return date('t', $time);
}
return $time;
} /**
* @param $startTime
/** * @param null $endTime
* @param $startTime * @return string
* @param null $endTime */
* @return string public static function mtime($startTime, $endTime = null)
*/ {
public static function mtime($startTime, $endTime = null) if ($endTime === null) {
{ $endTime = microtime(true);
if ($endTime === null) { }
$endTime = microtime(true); return sprintf('%.7f', $endTime - $startTime);
} }
return sprintf('%.7f', $endTime - $startTime); }
}
}
+58 -60
View File
@@ -1,60 +1,58 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
/** /**
* Class Dtl * Class Dtl
* @package Kiri\Core * @package Kiri\Core
*/ */
class Dtl extends Component class Dtl extends Component
{ {
protected array $params; protected array $params;
/** /**
* Dtl constructor. * Dtl constructor.
* @param $params * @param $params
*/ * @throws Exception
public function __construct($params) */
{ public function __construct($params)
parent::__construct([]); {
$this->params = $params; parent::__construct([]);
} $this->params = $params;
}
/**
* @return array /**
* @throws Exception * @return array
*/ * @throws Exception
public function toArray(): array */
{ public function toArray(): array
if (!is_array($this->params)) { {
return ArrayAccess::toArray($this->params); return $this->params;
} }
return $this->params;
}
/**
* @param $name
/** * @return mixed
* @param $name * @throws Exception
* @return mixed */
* @throws Exception public function get($name): mixed
*/ {
public function get($name): mixed $array = $this->toArray();
{ if (!isset($array[$name])) {
$array = $this->toArray(); return null;
if (!isset($array[$name])) { }
return null; return $array[$name];
} }
return $array[$name];
}
}
}
+101
View File
@@ -0,0 +1,101 @@
<?php
namespace Kiri\Core;
use JetBrains\PhpStorm\Pure;
use ReturnTypeWillChange;
class HashMap implements \ArrayAccess
{
/**
* @var array
*/
private array $lists = [];
/**
* @param string $key
* @param $value
*/
public function put(string $key, $value)
{
$this->lists[$key] = $value;
}
/**
* @param string $key
* @return mixed
*/
#[Pure] public function get(string $key): mixed
{
if (!$this->has($key)) {
return null;
}
return $this->lists[$key];
}
/**
* @param string $key
*/
public function del(string $key)
{
if (!$this->has($key)) {
return;
}
unset($this->lists[$key]);
}
/**
* @param string $key
* @return bool
*/
public function has(string $key): bool
{
return array_key_exists($key, $this->lists);
}
/**
* @param mixed $offset
* @return bool
*/
public function offsetExists(mixed $offset): bool
{
return isset($this->lists[$offset]);
}
/**
* @param mixed $offset
* @return mixed
*/
#[Pure] public function offsetGet(mixed $offset): mixed
{
return $this->get($offset);
}
/**
* @param mixed $offset
* @param mixed $value
*/
#[ReturnTypeWillChange]
public function offsetSet(mixed $offset, mixed $value)
{
$this->put($offset, $value);
}
/**
* @param mixed $offset
*/
#[ReturnTypeWillChange]
public function offsetUnset(mixed $offset)
{
unset($this->lists[$offset]);
}
}
+219 -215
View File
@@ -1,215 +1,219 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class Help * Class Help
* @package Kiri\Kiri\Core * @package Kiri\Kiri\Core
*/ */
class Help class Help
{ {
/** /**
* @param array $data * @param array $data
* @return string * @return string
*/ */
public static function toXml(array $data): string public static function toXml(array $data): string
{ {
$xml = "<xml>"; $xml = "<xml>";
foreach ($data as $key => $val) { foreach ($data as $key => $val) {
if (is_array($val)) { if (is_array($val)) {
$xml .= "<" . $key . ">" . static::xmlChild($val) . "</" . $key . ">"; $xml .= "<" . $key . ">" . static::xmlChild($val) . "</" . $key . ">";
} else if (is_numeric($val)) { } else if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">"; $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else { } else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
} }
} }
$xml .= "</xml>"; $xml .= "</xml>";
return $xml; return $xml;
} }
/** /**
* @param array $array * @param array $array
* @return string * @return string
*/ */
private static function xmlChild(array $array): string private static function xmlChild(array $array): string
{ {
$string = ''; $string = '';
foreach ($array as $key => $value) { foreach ($array as $key => $value) {
if (is_array($value)) { if (is_array($value)) {
$string .= static::xmlChild($value); $string .= static::xmlChild($value);
} else if (is_numeric($value)) { } else if (is_numeric($value)) {
$string .= "<" . $key . ">" . $value . "</" . $key . ">"; $string .= "<" . $key . ">" . $value . "</" . $key . ">";
} else { } else {
$string .= "<" . $key . "><![CDATA[" . $value . "]]></" . $key . ">"; $string .= "<" . $key . "><![CDATA[" . $value . "]]></" . $key . ">";
} }
} }
return $string; return $string;
} }
/** /**
* @param $xml * @param $xml
* @return mixed * @return mixed
*/ * @throws Exception
public static function toArray($xml): mixed */
{ public static function toArray($xml): mixed
if (empty($xml)) { {
return []; if (empty($xml)) {
} else if (is_array($xml)) { return [];
return $xml; } else if (is_array($xml)) {
} return $xml;
if (!($_xml = Xml::isXml($xml))) { }
return static::jsonToArray($xml); if (!($_xml = Xml::isXml($xml))) {
} return static::jsonToArray($xml);
return $_xml; }
} return $_xml;
}
/**
* @param $xml /**
* @return mixed * @param $xml
*/ * @return mixed
public static function jsonToArray($xml): mixed */
{ public static function jsonToArray($xml): mixed
$_xml = json_decode($xml, true); {
if (is_null($_xml)) { $_xml = json_decode($xml, true);
return []; if (is_null($_xml)) {
} return [];
return $_xml; }
} return $_xml;
}
/**
* @param $xml /**
* @return mixed * @param $xml
*/ * @return mixed
public static function xmlToArray($xml): mixed */
{ public static function xmlToArray($xml): mixed
if (is_array($xml)) { {
return $xml; if (is_array($xml)) {
} return $xml;
if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) { }
return json_decode(json_encode($data), TRUE); if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) {
} return json_decode(json_encode($data), TRUE);
if (!is_null($json = json_decode($xml, TRUE))) { }
return $json; if (!is_null($json = json_decode($xml, TRUE))) {
} return $json;
return $xml; }
} return $xml;
}
/**
* @param $parameter /**
* @return array|false|string * @param $parameter
* @throws Exception * @return array|false|string
*/ * @throws Exception
public static function toString($parameter): bool|array|string */
{ public static function toString($parameter): bool|array|string
if (!is_string($parameter)) { {
$parameter = ArrayAccess::toArray($parameter); if (!is_string($parameter)) {
if (is_array($parameter)) { $parameter = ArrayAccess::toArray($parameter);
$parameter = Json::encode($parameter); if (is_array($parameter)) {
} $parameter = Json::encode($parameter);
} }
return $parameter; }
} return $parameter;
}
/**
* @param mixed $json /**
* @return bool|string * @param mixed $json
*/ * @return bool|string
public static function toJson(mixed $json): bool|string */
{ public static function toJson(mixed $json): bool|string
if (is_object($json)) { {
$json = get_object_vars($json); if (is_object($json)) {
} $json = get_object_vars($json);
if (is_array($json)) { }
return json_encode($json, JSON_UNESCAPED_UNICODE); if (is_array($json)) {
} return json_encode($json, JSON_UNESCAPED_UNICODE);
$matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><!.*?><\/\4>)+<\/\2>/'; }
if (preg_match($matchQuote, $json)) { $matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><!.*?><\/\4>)+<\/\2>/';
$json = self::xmlToArray($json); if (preg_match($matchQuote, $json)) {
} else { $json = self::xmlToArray($json);
$json = json_decode($json, true); } else {
} $json = json_decode($json, true);
if (!is_array($json)) { }
$json = []; if (!is_array($json)) {
} $json = [];
return json_encode($json, JSON_UNESCAPED_UNICODE); }
} return json_encode($json, JSON_UNESCAPED_UNICODE);
}
/**
* @param int $length /**
* @return string * @param int $length
* * @return string
* 随机字符串 *
*/ * 随机字符串
public static function random($length = 20): string */
{ public static function random($length = 20): string
$res = []; {
$str = 'abcdefghijklmnopqrstuvwxyz'; $res = [];
$str .= strtoupper($str) . '1234567890'; $str = 'abcdefghijklmnopqrstuvwxyz';
for ($i = 0; $i < $length; $i++) { $str .= strtoupper($str) . '1234567890';
$rand = substr($str, rand(0, strlen($str) - 2), 1); for ($i = 0; $i < $length; $i++) {
if (empty($rand)) { $rand = substr($str, rand(0, strlen($str) - 2), 1);
$rand = substr($str, strlen($str) - 3, 1); if (empty($rand)) {
} $rand = substr($str, strlen($str) - 3, 1);
array_push($res, $rand); }
} array_push($res, $rand);
}
return implode($res);
} return implode($res);
}
/**
* @param array $array /**
* @param $key * @param array $array
* @param string $type * @param $key
* @return string * @param string $type
*/ * @return string
public static function sign(array $array, $key, string $type = 'MD5'): string */
{ public static function sign(array $array, $key, string $type = 'MD5'): string
ksort($array, SORT_ASC); {
$string = []; ksort($array, SORT_ASC);
foreach ($array as $hashKey => $val) { $string = [];
if (empty($val)) { foreach ($array as $hashKey => $val) {
continue; if (empty($val)) {
} continue;
$string[] = $hashKey . '=' . $val; }
} $string[] = $hashKey . '=' . $val;
$string[] = 'key=' . $key; }
$string = implode('&', $string); $string[] = 'key=' . $key;
if ($type == 'MD5') { $string = implode('&', $string);
return strtoupper(md5($string)); if ($type == 'MD5') {
} else { return strtoupper(md5($string));
return hash('sha256', $string); } else {
} return hash('sha256', $string);
} }
}
/**
* @param $email /**
* @param string $Subject * @param $email
* @param $messageContent * @param string $Subject
*/ * @param $messageContent
public static function sendEmail($email, string $Subject, $messageContent) */
{ public static function sendEmail($email, string $Subject, $messageContent)
$mailer = new \Swift_Mailer((new \Swift_SmtpTransport($email['host'], $email['port'])) {
->setUsername($email['username'])->setPassword($email['password'])); if (!class_exists('\Swift_Mailer')) {
$message = (new \Swift_Message($Subject)) return;
->setFrom([$email['send']['address'] => $email['send']['nickname']]) }
->setBody('Here is the message itself'); $mailer = new \Swift_Mailer((new \Swift_SmtpTransport($email['host'], $email['port']))
->setUsername($email['username'])->setPassword($email['password']));
foreach ($email['receive'] as $item) { $message = (new \Swift_Message($Subject))
$message->setTo([$item['address'], $item['address'] => $item['nickname']]); ->setFrom([$email['send']['address'] => $email['send']['nickname']])
} ->setBody('Here is the message itself');
$mailer->send($messageContent);
} foreach ($email['receive'] as $item) {
$message->setTo([$item['address'], $item['address'] => $item['nickname']]);
} }
$mailer->send($messageContent);
}
}
+121 -122
View File
@@ -1,122 +1,121 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-20 * Date: 2019-03-20
* Time: 01:04 * Time: 01:04
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Error; use Error;
use Exception; use Exception;
use Throwable; use Throwable;
/** /**
* Class JSON * Class JSON
* @package Kiri\Kiri\Core * @package Kiri\Kiri\Core
*/ */
class Json class Json
{ {
/** /**
* @param $data * @param $data
* @return false|string * @return false|string
*/ */
public static function encode($data): bool|string public static function encode($data): bool|string
{ {
if (empty($data)) { if (empty($data)) {
return false; return false;
} }
if (is_array($data)) { if (is_array($data)) {
return json_encode($data, JSON_UNESCAPED_UNICODE); return json_encode($data, JSON_UNESCAPED_UNICODE);
} }
return $data; return $data;
} }
/** /**
* @param $data * @param $data
* @param bool $asArray * @param bool $asArray
* @return mixed * @return mixed
*/ */
public static function decode($data, $asArray = true): mixed public static function decode($data, bool $asArray = true): mixed
{ {
if (is_array($data) || is_numeric($data)) { if (is_array($data) || is_numeric($data)) {
return $data; return $data;
} }
if (!is_string($data)) return null; if (!is_string($data)) return null;
return json_decode($data, $asArray); return json_decode($data, $asArray);
} }
/** /**
* @param $code * @param $code
* @param string $message * @param string|array $message
* @param array $data * @param array|int $data
* @param int $count * @param int $count
* @param array $exPageInfo * @param array $exPageInfo
* @return mixed * @return string|bool
* @throws */
*/ public static function to($code, string|array $message = '', array|int $data = [], int $count = 0, array $exPageInfo = []): string|bool
public static function to($code, $message = '', $data = [], $count = 0, $exPageInfo = []): mixed {
{ $params['code'] = $code;
$params['code'] = $code; if (!is_string($message)) {
if (!is_string($message)) { $params['message'] = 'System success.';
$params['param'] = $message; $params['param'] = $message;
if (!empty($data)) { if (!empty($data)) {
$params['exPageInfo'] = $data; $params['exPageInfo'] = $data;
} }
$params['message'] = 'System success.'; } else {
} else { $params['message'] = $message;
$params['message'] = $message; $params['param'] = $data;
$params['param'] = $data; }
} if (!empty($exPageInfo)) {
if (!empty($exPageInfo)) { $params['exPageInfo'] = $exPageInfo;
$params['exPageInfo'] = $exPageInfo; }
} $params['count'] = $count;
$params['count'] = $count; if (is_numeric($data) || !is_numeric($count)) {
if (is_numeric($data) || !is_numeric($count)) { $params['count'] = $data;
$params['count'] = $data; $params['exPageInfo'] = $count;
$params['exPageInfo'] = $count; }
} if ((int)$params['count'] == -100) {
if ((int)$params['count'] == -100) { $params['count'] = 1;
$params['count'] = 1; }
} return static::encode($params);
return static::encode($params); }
}
/**
/** * @param Throwable|Error $throwable
* @param Throwable|Error $throwable * @return bool|string
* @return bool|string */
*/ public static function error(Throwable|Error $throwable): bool|string
public static function error(Throwable|Error $throwable): bool|string {
{ $array['code'] = $throwable->getCode() == 0 ? 500 : $throwable->getCode();
$array['code'] = $throwable->getCode() == 0 ? 500 : $throwable->getCode(); $array['message'] = $throwable->getMessage();
$array['message'] = $throwable->getMessage(); $array['param'] = [
$array['param'] = [ 'file' => $throwable->getFile(),
'file' => $throwable->getFile(), 'line' => $throwable->getLine()
'line' => $throwable->getLine() ];
]; return Json::encode($array);
return Json::encode($array); }
}
/**
/** * @param $state
* @param $state * @param $body
* @param $body * @return false|int|string
* @return false|int|string * @throws Exception
* @throws Exception */
*/ public static function output($state, $body): bool|int|string
public static function output($state, $body): bool|int|string {
{ $params['state'] = $state;
$params['state'] = $state; $params['body'] = ArrayAccess::toArray($body);
$params['body'] = ArrayAccess::toArray($body);
return static::encode($params);
return static::encode($params); }
} }
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Kiri\Core;
class Network
{
/**
* @return string
*/
public static function local(): string
{
return current(swoole_get_local_ip());
}
}
+31 -31
View File
@@ -1,31 +1,31 @@
<?php <?php
namespace Kiri\Core; namespace Kiri\Core;
class Number class Number
{ {
/** /**
* @param int $userId * @param int $userId
* @return string * @return string
*/ */
public static function order(int $userId): string public static function order(int $userId): string
{ {
$explode = current(explode(' ', str_replace('0.', '', microtime()))); $explode = current(explode(' ', str_replace('0.', '', microtime())));
return 'No.' . sprintf('%010d', $userId) . '.' . date('Ymd.His') . '.' . $explode; return 'No.' . sprintf('%010d', $userId) . '.' . date('Ymd.His') . '.' . $explode;
} }
/** /**
* @param int $userId * @param int $userId
* @return string * @return string
*/ */
public static function create(int $userId): string public static function create(int $userId): string
{ {
return static::order($userId); return static::order($userId);
} }
} }
+172 -172
View File
@@ -1,172 +1,172 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
/** /**
* Class Reader * Class Reader
* @package Kiri\Kiri\Core * @package Kiri\Kiri\Core
*/ */
class Reader class Reader
{ {
/** /**
* @param $filepath * @param $filepath
* @param int $page * @param int $page
* @param int $size * @param int $size
* @return array and int * @return array and int
*/ */
public static function readerServerLogPagination($filepath, int $page = 1, int $size = 20): array public static function readerServerLogPagination($filepath, int $page = 1, int $size = 20): array
{ {
$count = 0; $count = 0;
$strings = []; $strings = [];
$offset = ($page - 1) * $size; $offset = ($page - 1) * $size;
if (!file_exists($filepath)) { if (!file_exists($filepath)) {
return [0, []]; return [0, []];
} }
//只读方式打开文件 //只读方式打开文件
$fp = fopen($filepath, "r"); $fp = fopen($filepath, "r");
//开始循环读取$buffer_size //开始循环读取$buffer_size
while (!feof($fp)) { while (!feof($fp)) {
//读文件到缓冲区 //读文件到缓冲区
$buffer = fgets($fp); $buffer = fgets($fp);
$count++; $count++;
if ($count > $offset && count($strings) < $size) { if ($count > $offset && count($strings) < $size) {
$strings[] = [ $strings[] = [
'id' => $count, 'id' => $count,
'content' => $buffer 'content' => $buffer
]; ];
} }
} }
//关闭文件 //关闭文件
fclose($fp); fclose($fp);
unset($fp); unset($fp);
return ['total' => $count, 'list' => $strings]; return ['total' => $count, 'list' => $strings];
} }
/** /**
* @param $filename * @param $filename
* @param $start * @param $start
* @param $lines * @param $lines
* @return array * @return array
*/ */
public static function read_backward_line($filename, $start, $lines): array public static function read_backward_line($filename, $start, $lines): array
{ {
$lines++; $lines++;
$offset = -1; $offset = -1;
$read = ''; $read = '';
$fp = @fopen($filename, "r"); $fp = @fopen($filename, "r");
$tmpStart = 0; $tmpStart = 0;
while ($lines && fseek($fp, $offset, SEEK_END) >= 0) { while ($lines && fseek($fp, $offset, SEEK_END) >= 0) {
$c = fgetc($fp); $c = fgetc($fp);
if ($c == "\n" || $c == "\r") { if ($c == "\n" || $c == "\r") {
if (++$tmpStart >= $start) if (++$tmpStart >= $start)
$lines--; $lines--;
} }
if ($tmpStart >= $start) if ($tmpStart >= $start)
$read .= $c; $read .= $c;
$offset--; $offset--;
} }
$read = trim($read); $read = trim($read);
$contents = []; $contents = [];
$read = array_reverse(explode("\n", strrev($read))); $read = array_reverse(explode("\n", strrev($read)));
foreach ($read as $key => $value) { foreach ($read as $key => $value) {
if (empty($value)) { if (empty($value)) {
unset($read[$key]); unset($read[$key]);
} else { } else {
$contents[] = ['content' => $value, 'id' => $key + $start]; $contents[] = ['content' => $value, 'id' => $key + $start];
} }
} }
$response['total'] = self::read_count_by_file($filename); $response['total'] = self::read_count_by_file($filename);
$response['list'] = $contents; $response['list'] = $contents;
return $response; return $response;
} }
/** /**
* @param $filepath * @param $filepath
* @return int * @return int
*/ */
private static function read_count_by_file($filepath): int private static function read_count_by_file($filepath): int
{ {
$count = 0; $count = 0;
//只读方式打开文件 //只读方式打开文件
$fp = fopen($filepath, "r"); $fp = fopen($filepath, "r");
//开始循环读取$buffer_size //开始循环读取$buffer_size
while (fgets($fp)) { while (fgets($fp)) {
$count++; $count++;
} }
//关闭文件 //关闭文件
fclose($fp); fclose($fp);
unset($fp); unset($fp);
return $count; return $count;
} }
/** /**
* @param $filepath * @param $filepath
* @param int $page * @param int $page
* @param int $size * @param int $size
* @return array * @return array
*/ */
public static function folderPagination($filepath, int $page = 1, int $size = 20): array public static function folderPagination($filepath, int $page = 1, int $size = 20): array
{ {
$count = 0; $count = 0;
$strings = []; $strings = [];
$offset = ($page - 1) * $size; $offset = ($page - 1) * $size;
if (!is_dir($filepath)) { if (!is_dir($filepath)) {
return [0, []]; return [0, []];
} }
foreach (glob($filepath . '/*') as $key => $value) { foreach (glob($filepath . '/*') as $key => $value) {
$count++; $count++;
if ($key < $offset || count($strings) >= $size) { if ($key < $offset || count($strings) >= $size) {
continue; continue;
} }
$explode = explode(DIRECTORY_SEPARATOR, $value); $explode = explode(DIRECTORY_SEPARATOR, $value);
$addTime = fileatime($value); $addTime = fileatime($value);
$changeTime = filectime($value); $changeTime = filectime($value);
$modifyTime = filemtime($value); $modifyTime = filemtime($value);
$strings[] = [ $strings[] = [
'id' => $count, 'id' => $count,
'path' => $value, 'path' => $value,
'isDir' => (int)is_dir($value), 'isDir' => (int)is_dir($value),
'name' => end($explode), 'name' => end($explode),
'atime' => [ 'atime' => [
'format' => date('Y-m-d H:i:s', $addTime), 'format' => date('Y-m-d H:i:s', $addTime),
'microtime' => $addTime 'microtime' => $addTime
], ],
'ctime' => [ 'ctime' => [
'format' => date('Y-m-d H:i:s', $changeTime), 'format' => date('Y-m-d H:i:s', $changeTime),
'microtime' => $changeTime 'microtime' => $changeTime
], ],
'mtime' => [ 'mtime' => [
'format' => date('Y-m-d H:i:s', $modifyTime), 'format' => date('Y-m-d H:i:s', $modifyTime),
'microtime' => $modifyTime 'microtime' => $modifyTime
], ],
]; ];
} }
array_multisort($strings, array_column($strings, 'isDir'), SORT_DESC); array_multisort($strings, array_column($strings, 'isDir'), SORT_DESC);
return ['total' => $count, 'list' => $strings]; return ['total' => $count, 'list' => $strings];
} }
} }
+283 -277
View File
@@ -1,277 +1,283 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class Str * Class Str
* @package Kiri\Kiri\Core * @package Kiri\Kiri\Core
*/ */
class Str class Str
{ {
const STRING = 'abcdefghijklmnopqrstuvwxyz'; const STRING = 'abcdefghijklmnopqrstuvwxyz';
const NUMBER = '01234567890'; const NUMBER = '01234567890';
/** /**
* @param int $length * @param int $length
* *
* @return string * @return string
* 获取随机字符串 * 获取随机字符串
*/ */
public static function rand(int $length = 20): string public static function rand(int $length = 20): string
{ {
$string = ''; $string = '';
if ($length < 1) $length = 20; if ($length < 1) $length = 20;
$default = self::STRING . strtoupper(self::STRING) . self::NUMBER; $default = self::STRING . strtoupper(self::STRING) . self::NUMBER;
$default = str_split($default); $default = str_split($default);
$string .= str_repeat($default[array_rand($default)], $length); for ($i = 0; $i < $length; $i++) {
return (string)$string; shuffle($default);
} $string .= $default[array_rand($default)];
}
/** return $string;
* @param int $length }
*
* @return int|string 获取随机数字 /**
* 获取随机数字 * @param int $length
*/ *
public static function random(int $length = 20): int|string * @return int|string 获取随机数字
{ * 获取随机数字
$number = ''; */
$default = str_split(self::NUMBER); public static function random(int $length = 20): int|string
if ($length < 1) $length = 1; {
$number .= str_repeat($default[array_rand($default)], $length); $number = '';
return $number; $default = str_split(self::NUMBER);
} if ($length < 1) $length = 1;
for ($i = 0; $i < $length; $i++) {
/** shuffle($default);
* @param $string $number .= $default[array_rand($default)];
* @param $sullen }
* @param bool $strip_tags return $number;
* @param string $append }
*
* @return string /**
*/ * @param $string
public static function cut_str_utf8($string, $sullen, bool $strip_tags = true, string $append = '...'): string * @param $sullen
{ * @param bool $strip_tags
if ($strip_tags) { * @param string $append
$string = strip_tags($string); *
}//去掉签标 * @return string
$pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/"; */
preg_match_all($pa, $string, $t_string); public static function cut_str_utf8($string, $sullen, bool $strip_tags = TRUE, string $append = '...'): string
$str = ""; {
for ($i = 0; $i < count($t_string[0]); $i++) { if ($strip_tags) {
$str .= $t_string[0][$i]; $string = strip_tags($string);
//转为gbk,一个汉字长度为2 }//去掉签标
if (strlen(@iconv('utf-8', 'gbk', $str)) >= $sullen) { $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
if ($i != count($t_string[0]) - 1) $str .= $append; preg_match_all($pa, $string, $t_string);
break; $str = "";
} for ($i = 0; $i < count($t_string[0]); $i++) {
} $str .= $t_string[0][$i];
return $str; //转为gbk,一个汉字长度为2
} if (strlen(@iconv('utf-8', 'gbk', $str)) >= $sullen) {
if ($i != count($t_string[0]) - 1) $str .= $append;
/** break;
* @param $data }
* }
* @param null $callback return $str;
* @return bool }
* 判断是否为json字符串
*/ /**
public static function isJson($data, $callback = null): bool * @param $data
{ *
$json = !is_null(json_decode($data)) && !is_numeric($data); * @param null $callback
if ($json && is_callable($callback, true)) { * @return bool
return call_user_func($callback, $data); * 判断是否为json字符串
} */
return $json; public static function isJson($data, $callback = NULL): bool
} {
$json = !is_null(json_decode($data)) && !is_numeric($data);
/** if ($json && is_callable($callback, TRUE)) {
* @param $data return call_user_func($callback, $data);
* }
* @param null $callBack return $json;
* @return bool }
* 判断是否序列化字符串
*/ /**
public static function isSerialize($data, $callBack = null): bool * @param $data
{ *
$false = !empty($data) && swoole_unserialize($data) !== false; * @param null $callBack
if ($false && is_callable($callBack, true)) { * @return bool
return call_user_func($callBack, $data); * 判断是否序列化字符串
} */
return $false; public static function isSerialize($data, $callBack = NULL): bool
} {
$false = !empty($data) && swoole_unserialize($data) !== FALSE;
/** if ($false && is_callable($callBack, TRUE)) {
* @param $string return call_user_func($callBack, $data);
* @param int $length }
* return $false;
* @param string $append }
* @return string
*/ /**
public static function cut($string, int $length = 20, string $append = '...'): string * @param $string
{ * @param int $length
if (empty($string)) { *
return ''; * @param string $append
} * @return string
if ($length < 1) { */
$length = 1; public static function cut($string, int $length = 20, string $append = '...'): string
} {
$array = str_split($string); if (empty($string)) {
if (count($array) <= $length) { return '';
return implode('', $array); }
} if ($length < 1) {
$string = implode('', array_slice($array, 0, $length)); $length = 1;
if (!empty($append)) { }
$string .= $append; $array = str_split($string);
} if (count($array) <= $length) {
return $string; return implode('', $array);
} }
$string = implode('', array_slice($array, 0, $length));
/** if (!empty($append)) {
* @param $str $string .= $append;
* @param int $number }
* @param string $key return $string;
* }
* @return string
*/ /**
public static function encrypt($str, int $number = 10, string $key = 'xshucai.com'): string * @param $str
{ * @param int $number
$res = []; * @param string $key
$add = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; *
$len = strlen($key) < 0 ? 1 : (strlen($key) + 5 > strlen($add) ? strlen($add) - 5 : strlen($key)); * @return string
if ($number < 1) $number = 10; */
$array = str_split($str); public static function encrypt($str, int $number = 10, string $key = 'xshucai.com'): string
asort($array); {
$str = implode('', $array); $res = [];
for ($i = 0; $i < $number; $i++) { $add = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$_tmp = md5($key) . md5($str) . mb_substr($add, $len, $len + 5, 'utf-8'); $len = strlen($key) < 0 ? 1 : (strlen($key) + 5 > strlen($add) ? strlen($add) - 5 : strlen($key));
$res[] = md5($_tmp); if ($number < 1) $number = 10;
} $array = str_split($str);
sort($res, SORT_STRING); asort($array);
return hash('sha384', implode('', $res)); $str = implode('', $array);
} for ($i = 0; $i < $number; $i++) {
$_tmp = md5($key) . md5($str) . mb_substr($add, $len, $len + 5, 'utf-8');
/** $res[] = md5($_tmp);
* @param $file }
* @param $type sort($res, SORT_STRING);
* @return string return hash('sha384', implode('', $res));
*/ }
public static function filename($file, $type): string
{ /**
switch ($type) { * @param $file
case 'image/png': * @param $type
return md5_file($file) . '.png'; * @return string
case 'image/jpeg': */
case 'image/jpg': public static function filename($file, $type): string
return md5_file($file) . '.jpg'; {
case 'image/gif': switch ($type) {
return md5_file($file) . '.gif'; case 'image/png':
break; return md5_file($file) . '.png';
} case 'image/jpeg':
return md5_file($file); case 'image/jpg':
} return md5_file($file) . '.jpg';
case 'image/gif':
/** return md5_file($file) . '.gif';
* @param $endTime break;
* @param int|null $startTime }
* @return array return md5_file($file);
* 剩余天,带分秒 }
*/
public static function timeout($endTime, int $startTime = null): array /**
{ * @param $endTime
$endTime = $endTime - (!empty($startTime) ? $startTime : time()); * @param int|null $startTime
* @return array
$day = intval($endTime / (3600 * 24)); * 剩余天,带分秒
*/
$hours = intval(($endTime - ($day * (3600 * 24))) / 3600); public static function timeout($endTime, int $startTime = NULL): array
{
$minute = intval(($endTime - ($day * (3600 * 24) + $hours * 3600)) / 60); $endTime = $endTime - (!empty($startTime) ? $startTime : time());
$scrod = intval(($endTime - ($day * (3600 * 24) + $hours * 3600 + $minute * 60))); $day = intval($endTime / (3600 * 24));
return [$day, $hours, $minute, $scrod]; $hours = intval(($endTime - ($day * (3600 * 24))) / 3600);
}
$minute = intval(($endTime - ($day * (3600 * 24) + $hours * 3600)) / 60);
/** $scrod = intval(($endTime - ($day * (3600 * 24) + $hours * 3600 + $minute * 60)));
* @return false|int
*/ return [$day, $hours, $minute, $scrod];
public static function get_sy_time(): bool|int }
{
$time = strtotime('+1days', strtotime(date('Y-m-d')));
/**
return $time - time(); * @return false|int
} */
public static function get_sy_time(): bool|int
/** {
* @param string $string $time = strtotime('+1days', strtotime(date('Y-m-d')));
* @return string
*/ return $time - time();
public static function encode(string $string): string }
{
return addslashes($string); /**
} * @param string $string
* @return string
/** */
* @param string $string public static function encode(string $string): string
* @return string|string[]|null {
* 清除标点符号 return addslashes($string);
*/ }
public static function clear(string $string): array|string|null
{ /**
$char = '。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()'; * @param string $string
return preg_replace(array("/[[:punct:]]/i", '/[' . $char . ']/u', '/[ ]{2,}/'), '', $string); * @return string|string[]|null
} * 清除标点符号
*/
public static function clear(string $string): array|string|null
/** {
* @param int $user $char = '。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()';
* @param array $param return preg_replace(["/[[:punct:]]/i", '/[' . $char . ']/u', '/[ ]{2,}/'], '', $string);
* @param null $requestTime }
*
* @return string
* @throws Exception /**
*/ * @param int $user
public static function token(int $user, array $param = [], $requestTime = NULL): string * @param array $param
{ * @param null $requestTime
$str = ''; *
if (!$requestTime) { * @return string
$requestTime = microtime(true); * @throws Exception
} */
$_user = str_split(md5($user . md5((string)$user))); public static function token(int $user, array $param = [], $requestTime = NULL): string
ksort($_user); {
foreach ($_user as $key => $val) { $str = '';
$str .= md5(sha1($key . $val . 'www.xshucai.com')); if (!$requestTime) {
} $requestTime = microtime(TRUE);
if (is_array($param)) { }
foreach ($param as $key => $val) { $_user = str_split(md5($user . md5((string)$user)));
$str .= md5($str . sha1($key . md5($val))); ksort($_user);
} foreach ($_user as $key => $val) {
} $str .= md5(sha1($key . $val . 'www.xshucai.com'));
$str .= sha1(base64_encode((string)$requestTime)); }
if (is_array($param)) {
$md5 = md5($str . $user); foreach ($param as $key => $val) {
$str .= md5($str . sha1($key . md5($val)));
return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $md5); }
} }
$str .= sha1(base64_encode((string)$requestTime));
/** $md5 = md5($str . $user);
* @param string $str
* @param bool $unfairest return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $md5);
* @return string }
*/
public static function convertUnderline(string $str, bool $unfairest = true): string
{ /**
$str = ucwords(str_replace('_', ' ', $str)); * @param string $str
$str = str_replace(' ', '', lcfirst($str)); * @param bool $unfairest
return $unfairest ? ucfirst($str) : $str; * @return string
} */
} public static function convertUnderline(string $str, bool $unfairest = TRUE): string
{
$str = ucwords(str_replace('_', ' ', $str));
$str = str_replace(' ', '', lcfirst($str));
return $unfairest ? ucfirst($str) : $str;
}
}
+57 -57
View File
@@ -1,57 +1,57 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-20 * Date: 2019-03-20
* Time: 01:03 * Time: 01:03
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Core; namespace Kiri\Core;
use Exception; use Exception;
/** /**
* Class Xml * Class Xml
* @package Kiri\Kiri\Core * @package Kiri\Kiri\Core
*/ */
class Xml class Xml
{ {
/** /**
* @param $data * @param $data
* @param bool $asArray * @param bool $asArray
* @return array|object * @return array|object
* @throws Exception * @throws Exception
*/ */
public static function toArray($data, bool $asArray = true): object|array public static function toArray($data, bool $asArray = true): object|array
{ {
$data = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA); $data = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
if ($data === false) { if ($data === false) {
throw new Exception('Parameter format error.'); throw new Exception('Parameter format error.');
} }
$array = get_object_vars($data); $array = get_object_vars($data);
if (isset($array[0])) { if (isset($array[0])) {
$array[$data->getName()] = $array[0]; $array[$data->getName()] = $array[0];
unset($array[0]); unset($array[0]);
} }
return $array; return $array;
} }
/** /**
* @param $str * @param $str
* @return array|bool|object * @return array|bool|object
* @throws Exception * @throws Exception
*/ */
public static function isXml($str): object|bool|array public static function isXml($str): object|bool|array
{ {
$xml_parser = xml_parser_create(); $xml_parser = xml_parser_create();
if (!xml_parse($xml_parser, $str, true)) { if (!xml_parse($xml_parser, $str, true)) {
xml_parser_free($xml_parser); xml_parser_free($xml_parser);
return false; return false;
} else { } else {
return self::toArray($str); return self::toArray($str);
} }
} }
} }
+450 -438
View File
@@ -1,438 +1,450 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/24 0024 * Date: 2018/4/24 0024
* Time: 17:27 * Time: 17:27
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Di; namespace Kiri\Di;
use Annotation\Inject; use Kiri\Annotation\Inject;
use Closure; use Closure;
use Exception; use Exception;
use Kiri\Abstracts\BaseObject; use Kiri\Abstracts\Logger;
use Kiri\Abstracts\Logger; use Kiri\Kiri;
use Kiri\Kiri; use Psr\Log\LoggerInterface;
use Psr\Log\LoggerInterface; use ReflectionClass;
use ReflectionClass; use ReflectionException;
use ReflectionException; use ReflectionFunction;
use ReflectionFunction; use ReflectionMethod;
use ReflectionMethod; use ReflectionProperty;
use ReflectionProperty; use Psr\Container\ContainerInterface;
/** /**
* Class Container * Class Container
* @package Kiri\Di * @package Kiri\Di
*/ */
class Container extends BaseObject implements ContainerInterface class Container implements ContainerInterface
{ {
/** /**
* @var array * @var array
* *
* instance class by className * instance class by className
*/ */
private array $_singletons = []; private array $_singletons = [];
/** /**
* @var ReflectionMethod[] * @var ReflectionMethod[]
* *
* class new instance construct parameter * class new instance construct parameter
*/ */
private array $_constructs = []; private array $_constructs = [];
/** /**
* @var array * @var array
* *
* implements \ReflectClass * implements \ReflectClass
*/ */
private array $_reflection = []; private array $_reflection = [];
/** @var array */ /** @var array */
private array $_parameters = []; private array $_parameters = [];
/** @var array|string[] */ /** @var array|string[] */
private array $_interfaces = [ private array $_interfaces = [
LoggerInterface::class => Logger::class LoggerInterface::class => Logger::class
]; ];
/** /**
* @param $class * @param string $id
* @param array $constrict * @return mixed
* @param array $config * @throws
* */
* @return mixed public function get(string $id): mixed
* @throws {
*/ return $this->make($id, [], []);
public function get($class, array $constrict = [], array $config = []): mixed }
{
if ($this->isInterface($class)) {
$class = $this->_interfaces[$class];
} /**
if (!isset($this->_singletons[$class])) { * @param $class
$this->_singletons[$class] = $this->resolve($class, $constrict, $config); * @param array $constrict
} * @param array $config
return $this->_singletons[$class]; * @return mixed
} * @throws
*/
public function make($class, array $constrict = [], array $config = []): mixed
/** {
* @param string $interface if ($this->isInterface($class)) {
* @param string $class $class = $this->_interfaces[$class];
*/ }
public function mapping(string $interface, string $class) if (!isset($this->_singletons[$class])) {
{ $this->_singletons[$class] = $this->resolve($class, $constrict, $config);
$this->_interfaces[$interface] = $class; }
} return $this->_singletons[$class];
}
/**
* @param $class
* @return bool /**
* @throws ReflectionException * @param string $interface
*/ * @param string $class
public function isInterface($class): bool */
{ public function mapping(string $interface, string $class)
$reflect = $this->getReflect($class); {
if ($reflect->isInterface()) { $this->_interfaces[$interface] = $class;
return true; }
}
return false;
} /**
* @param $class
* @return bool
/** */
* @param string $interface public function isInterface($class): bool
* @param $object {
*/ $reflect = $this->getReflect($class);
public function setBindings(string $interface, $object) if ($reflect->isInterface()) {
{ return true;
if (is_string($object)) { }
$this->_interfaces[$interface] = $object; return false;
} else { }
$className = get_class($object);
$this->_interfaces[$interface] = $className;
$this->_singletons[$className] = $object; /**
} * @param string $interface
} * @param $object
*/
public function setBindings(string $interface, $object)
/** {
* @param $class if (is_string($object)) {
* @param array $constrict $this->_interfaces[$interface] = $object;
* @param array $config } else {
* @return object $className = get_class($object);
* @throws $this->_interfaces[$interface] = $className;
*/ $this->_singletons[$className] = $object;
public function create($class, array $constrict = [], array $config = []): object }
{ }
return $this->resolve($class, $constrict, $config);
}
/**
* @param $class
/** * @param array $constrict
* @param $class * @param array $config
* @param $constrict * @return object
* @param $config * @throws
* */
* @return object public function create($class, array $constrict = [], array $config = []): object
* @throws Exception {
*/ return $this->resolve($class, $constrict, $config);
private function resolve($class, $constrict, $config): object }
{
$reflect = $this->resolveDependencies($class);
if (!$reflect->isInstantiable()) { /**
throw new ReflectionException('Class ' . $class . ' cannot be instantiated'); * @param $class
} * @param $constrict
* @param $config
$object = $this->newInstance($reflect, $constrict); *
* @return object
$this->propertyInject($reflect, $object); * @throws Exception
*/
return $this->onAfterInit($object, $config); private function resolve($class, $constrict, $config): object
} {
$reflect = $this->resolveDependencies($class);
if (!$reflect->isInstantiable()) {
/** throw new ReflectionException('Class ' . $class . ' cannot be instantiated');
* @param ReflectionClass $reflect }
* @param $dependencies
* @return object $object = $this->newInstance($reflect, $constrict);
* @throws ReflectionException
*/ $this->propertyInject($reflect, $object);
private function newInstance(ReflectionClass $reflect, $dependencies): object
{ return $this->onAfterInit($object, $config);
if (!isset($this->_constructs[$reflect->getName()])) { }
return $reflect->newInstance();
}
$construct = $this->_constructs[$reflect->getName()]; /**
if ($construct->getNumberOfParameters() < 1) { * @param ReflectionClass $reflect
return $reflect->newInstance(); * @param $dependencies
} * @return object
$parameters = $this->mergeParam($this->resolveMethodParameters($construct), $dependencies); * @throws ReflectionException
return $reflect->newInstanceArgs($parameters); */
} private function newInstance(ReflectionClass $reflect, $dependencies): object
{
if (!isset($this->_constructs[$reflect->getName()])) {
/** return $reflect->newInstance();
* @param ReflectionClass $reflect }
* @param $object $construct = $this->_constructs[$reflect->getName()];
* @return mixed if ($construct->getNumberOfParameters() < 1) {
* @throws Exception return $reflect->newInstance();
*/ }
public function propertyInject(ReflectionClass $reflect, $object): mixed $parameters = $this->mergeParam($this->resolveMethodParameters($construct), $dependencies);
{ return $reflect->newInstanceArgs($parameters);
foreach (NoteManager::getPropertyNote($reflect) as $property => $inject) { }
/** @var Inject $inject */
$inject->execute($object, $property);
} /**
return $object; * @param ReflectionClass $reflect
} * @param $object
* @return mixed
* @throws Exception
/** */
* @param $className public function propertyInject(ReflectionClass $reflect, $object): mixed
* @param $method {
* @return array foreach (NoteManager::getPropertyAnnotation($reflect) as $property => $inject) {
* @throws ReflectionException /** @var Inject $inject */
*/ $inject->execute($object, $property);
public function getMethodAttribute($className, $method = null): array }
{ return $object;
$methods = NoteManager::getMethodNote($this->getReflect($className)); }
if (!empty($method)) {
return $methods[$method] ?? [];
} /**
return $methods; * @param $className
} * @param $method
* @return array
*/
/** public function getMethodAttribute($className, $method = null): array
* @param string $class {
* @param string|null $property $methods = NoteManager::getMethodAnnotation($this->getReflect($className));
* @return ReflectionProperty|ReflectionProperty[]|null if (!empty($method)) {
* @throws ReflectionException return $methods[$method] ?? [];
*/ }
public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array return $methods;
{ }
$lists = NoteManager::getProperty($this->getReflect($class));
if (empty($lists)) {
return null; /**
} * @param string $class
if (!empty($property)) { * @param string|null $property
return $lists[$property] ?? null; * @return ReflectionProperty|ReflectionProperty[]|null
} */
return $lists; public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array
} {
$lists = NoteManager::getProperty($this->getReflect($class));
if (empty($lists)) {
/** return null;
* @param $object }
* @param $config if (!empty($property)) {
* @return mixed return $lists[$property] ?? null;
*/ }
private function onAfterInit($object, $config): mixed return $lists;
{ }
Kiri::configure($object, $config);
if (method_exists($object, 'init') && is_callable([$object, 'init'])) {
call_user_func([$object, 'init']); /**
} * @param $object
return $object; * @param $config
} * @return mixed
*/
private function onAfterInit($object, $config): mixed
/** {
* @param $class Kiri::configure($object, $config);
* @return ReflectionClass if (method_exists($object, 'init') && is_callable([$object, 'init'])) {
* @throws ReflectionException call_user_func([$object, 'init']);
*/ }
private function resolveDependencies($class): ReflectionClass return $object;
{ }
if (isset($this->_reflection[$class])) {
return $this->_reflection[$class];
} /**
$reflect = new ReflectionClass($class); * @param $class
if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) { * @return ReflectionClass
return $this->_reflection[$class] = $reflect; */
} private function resolveDependencies($class): ReflectionClass
$construct = NoteManager::resolveTarget($reflect); {
if (!empty($construct) && $construct->getNumberOfParameters() > 0) { if (isset($this->_reflection[$class])) {
$this->_constructs[$class] = $construct; return $this->_reflection[$class];
} }
return $this->_reflection[$class] = $reflect; $reflect = new ReflectionClass($class);
} if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) {
return $this->_reflection[$class] = $reflect;
}
/** $construct = NoteManager::resolveTarget($reflect);
* @param ReflectionClass|string $class if (!empty($construct) && $construct->getNumberOfParameters() > 0) {
* @return ReflectionMethod[] $this->_constructs[$class] = $construct;
* @throws ReflectionException }
*/ return $this->_reflection[$class] = $reflect;
public function getReflectMethods(ReflectionClass|string $class): array }
{
if (is_string($class)) {
$class = $this->getReflect($class); /**
} * @param ReflectionClass|string $class
return NoteManager::getMethods($class); * @return ReflectionMethod[]
} * @throws ReflectionException
*/
public function getReflectMethods(ReflectionClass|string $class): array
/** {
* @param ReflectionClass|string $class if (is_string($class)) {
* @param string $method $class = $this->getReflect($class);
* @return ReflectionMethod|null }
* @throws ReflectionException return NoteManager::getMethods($class);
*/ }
public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
{
return $this->getReflectMethods($class)[$method] ?? null; /**
} * @param ReflectionClass|string $class
* @param string $method
* @return ReflectionMethod|null
/** * @throws ReflectionException
* @param string $className */
* @param string $method public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
* @return array|null {
* @throws ReflectionException return $this->getReflectMethods($class)[$method] ?? null;
*/ }
public function getMethodParameters(string $className, string $method): ?array
{
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) { /**
return $this->_parameters[$className][$method]; * @param string $className
} * @param string $method
$reflectMethod = $this->getReflectMethod($this->getReflect($className), $method); * @return array|null
if (!($reflectMethod instanceof ReflectionMethod)) { * @throws ReflectionException
throw new ReflectionException("Class does not have a function $className::$method"); */
} public function getMethodParameters(string $className, string $method): ?array
$className = $reflectMethod->getDeclaringClass()->getName(); {
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) { if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) {
return $this->_parameters[$className][$reflectMethod->getName()]; return $this->_parameters[$className][$method];
} }
return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod)); $reflectMethod = $this->getReflectMethod($this->getReflect($className), $method);
} if (!($reflectMethod instanceof ReflectionMethod)) {
throw new ReflectionException("Class does not have a function $className::$method");
}
/** $className = $reflectMethod->getDeclaringClass()->getName();
* @param $class if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) {
* @param $method return $this->_parameters[$className][$reflectMethod->getName()];
* @param $parameters }
* @return mixed return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod));
*/ }
private function setParameters($class, $method, $parameters): mixed
{
if (!isset($this->_parameters[$class])) { /**
$this->_parameters[$class] = []; * @param $class
} * @param $method
if (!isset($this->_parameters[$class][$method])) { * @param $parameters
$this->_parameters[$class][$method] = []; * @return mixed
} */
return $this->_parameters[$class][$method] = $parameters; private function setParameters($class, $method, $parameters): mixed
} {
if (!isset($this->_parameters[$class])) {
$this->_parameters[$class] = [];
/** }
* @param Closure $reflectionMethod return $this->_parameters[$class][$method] = $parameters;
* @return array }
* @throws ReflectionException
*/
public function getFunctionParameters(Closure $reflectionMethod): array /**
{ * @param Closure $reflectionMethod
return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod)); * @return array
} * @throws ReflectionException
*/
public function getFunctionParameters(Closure $reflectionMethod): array
/** {
* @param ReflectionMethod|ReflectionFunction $reflectionMethod return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod));
* @return array }
* @throws ReflectionException
*/
private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array /**
{ * @param ReflectionMethod|ReflectionFunction $reflectionMethod
if ($reflectionMethod->getNumberOfParameters() < 1) { * @return array
return []; */
} private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array
$params = []; {
foreach ($reflectionMethod->getParameters() as $key => $parameter) { if ($reflectionMethod->getNumberOfParameters() < 1) {
if ($parameter->isDefaultValueAvailable()) { return [];
$params[$key] = $parameter->getDefaultValue(); }
} else if ($parameter->getType() === null) { $params = [];
$params[$key] = $parameter->getType(); foreach ($reflectionMethod->getParameters() as $key => $parameter) {
} else { if ($parameter->isDefaultValueAvailable()) {
$type = $parameter->getType()->getName(); $params[$key] = $parameter->getDefaultValue();
if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) { } else if ($parameter->getType() === null) {
$type = Kiri::getDi()->get($type); $params[$key] = $parameter->getType();
} } else {
$params[$key] = match ($parameter->getType()) { $type = $parameter->getType()->getName();
'string' => '', if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) {
'int', 'float' => 0, $type = Kiri::getDi()->get($type);
'', null, 'object', 'mixed' => NULL, }
'bool' => false, $params[$key] = match ($parameter->getType()) {
default => $type 'string' => '',
}; 'int', 'float' => 0,
} '', null, 'object', 'mixed' => NULL,
} 'bool' => false,
return $params; default => $type
} };
}
}
/** return $params;
* @param $class }
* @return ReflectionClass|null
* @throws ReflectionException
*/ /**
public function getReflect($class): ?ReflectionClass * @param $class
{ * @return ReflectionClass|null
if (!isset($this->_reflection[$class])) { */
return $this->resolveDependencies($class); public function getReflect($class): ?ReflectionClass
} {
return $this->_reflection[$class]; if (!isset($this->_reflection[$class])) {
} return $this->resolveDependencies($class);
}
/** return $this->_reflection[$class];
* @param $class }
*/
public function unset($class) /**
{ * @param $class
if (is_array($class) && isset($class['class'])) { */
$class = $class['class']; public function unset($class)
} else if (is_object($class)) { {
$class = $class::class; if (is_array($class) && isset($class['class'])) {
} $class = $class['class'];
unset( } else if (is_object($class)) {
$this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class] $class = $class::class;
); }
} unset(
$this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class]
/** );
* @return $this }
*/
public function flush(): static /**
{ * @return $this
$this->_reflection = []; */
$this->_singletons = []; public function flush(): static
$this->_constructs = []; {
return $this; $this->_reflection = [];
} $this->_singletons = [];
$this->_constructs = [];
/** return $this;
* @param $old }
* @param $newParam
* /**
* @return mixed * @param $old
*/ * @param $newParam
private function mergeParam($old, $newParam): array *
{ * @return mixed
if (empty($old)) { */
return $newParam; private function mergeParam($old, $newParam): array
} else if (empty($newParam)) { {
return $old; if (empty($old)) {
} return $newParam;
foreach ($newParam as $key => $val) { } else if (empty($newParam)) {
$old[$key] = $val; return $old;
} }
return $old; foreach ($newParam as $key => $val) {
} $old[$key] = $val;
} }
return $old;
}
/**
* @param string $id
* @return bool
*/
public function has(string $id): bool
{
return isset($this->_singletons[$id]) || isset($this->_interfaces[$id]);
}
}
-12
View File
@@ -1,12 +0,0 @@
<?php
namespace Kiri\Di;
/**
* @mixin Container
*/
interface ContainerInterface
{
}
+88 -88
View File
@@ -1,88 +1,88 @@
<?php <?php
namespace Kiri\Di; namespace Kiri\Di;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Kiri; use Kiri\Kiri;
/** /**
* 服务定位器 * 服务定位器
*/ */
class LocalService extends Component class LocalService extends Component
{ {
private array $_components = []; private array $_components = [];
private array $_definition = []; private array $_definition = [];
/** /**
* @param $name * @param $name
* @param $define * @param $define
*/ */
public function set($name, $define) public function set($name, $define)
{ {
unset($this->_components[$name]); unset($this->_components[$name]);
$this->_definition[$name] = $define; $this->_definition[$name] = $define;
if (is_object($define) || $define instanceof \Closure) { if (is_object($define) || $define instanceof \Closure) {
$this->_components[$name] = $define; $this->_components[$name] = $define;
} }
} }
/** /**
* @throws \Exception * @throws \Exception
*/ */
public function get(string $name, $throwException = true) public function get(string $name, $throwException = true)
{ {
if (isset($this->_components[$name])) { if (isset($this->_components[$name])) {
return $this->_components[$name]; return $this->_components[$name];
} }
if (isset($this->_definition[$name])) { if (isset($this->_definition[$name])) {
$definition = $this->_definition[$name]; $definition = $this->_definition[$name];
if (is_object($definition) && !$definition instanceof \Closure) { if (is_object($definition) && !$definition instanceof \Closure) {
return $this->_components[$name] = $definition; return $this->_components[$name] = $definition;
} }
return $this->_components[$name] = Kiri::createObject($definition); return $this->_components[$name] = Kiri::createObject($definition);
} else if ($throwException) { } else if ($throwException) {
throw new \Exception("Unknown component ID: $name"); throw new \Exception("Unknown component ID: $name");
} }
return null; return null;
} }
/** /**
* @param array $components * @param array $components
*/ */
public function setComponents(array $components) public function setComponents(array $components)
{ {
foreach ($components as $name => $component) { foreach ($components as $name => $component) {
$this->set($name, $component); $this->set($name, $component);
} }
} }
/** /**
* @param $id * @param $id
* @return bool * @return bool
*/ */
public function has($id): bool public function has($id): bool
{ {
return isset($this->_components[$id]) || isset($this->_definition[$id]); return isset($this->_components[$id]) || isset($this->_definition[$id]);
} }
/** /**
* @param $id * @param $id
*/ */
public function remove($id): void public function remove($id): void
{ {
unset($this->_components[$id], $this->_definition[$id]); unset($this->_components[$id], $this->_definition[$id]);
} }
} }
+303 -289
View File
@@ -1,289 +1,303 @@
<?php <?php
namespace Kiri\Di; namespace Kiri\Di;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use ReflectionAttribute; use ReflectionAttribute;
use ReflectionClass; use ReflectionClass;
use ReflectionProperty; use ReflectionProperty;
class NoteManager class NoteManager
{ {
private static array $_classTarget = []; private static array $_classTarget = [];
private static array $_classMethodNote = []; private static array $_classMethodAnnotation = [];
private static array $_classMethod = []; private static array $_classMethod = [];
private static array $_classPropertyNote = []; private static array $_classPropertyAnnotation = [];
private static array $_classProperty = []; private static array $_classProperty = [];
private static array $_mapping = []; private static array $_mapping = [];
/** /**
* @param ReflectionClass $class * @return void
*/ */
public static function setTargetNote(ReflectionClass $class) public static function clear()
{ {
$className = $class->getName(); static::$_classTarget = [];
if (!isset(static::$_classTarget[$className])) { static::$_classMethodAnnotation = [];
static::$_classTarget[$className] = []; static::$_classMethod = [];
} static::$_classPropertyAnnotation = [];
foreach ($class->getAttributes() as $attribute) { static::$_classProperty = [];
if (!class_exists($attribute->getName())) { static::$_mapping = [];
continue; }
}
$instance = $attribute->newInstance(); /**
* @param ReflectionClass $class
static::$_classTarget[$className][] = $instance; */
public static function setTargetAnnotation(ReflectionClass $class)
self::setMappingClass($attribute, $className); {
} $className = $class->getName();
} if (!isset(static::$_classTarget[$className])) {
static::$_classTarget[$className] = [];
}
/** foreach ($class->getAttributes() as $attribute) {
* @param ReflectionAttribute $attribute if (!class_exists($attribute->getName())) {
* @param string $class continue;
*/ }
public static function setMappingClass(ReflectionAttribute $attribute, string $class)
{ $instance = $attribute->newInstance();
if (!isset(static::$_mapping[$attribute->getName()])) {
static::$_mapping[$attribute->getName()] = []; static::$_classTarget[$className][] = $instance;
}
if (!isset(static::$_mapping[$attribute->getName()][$class])) { self::setMappingClass($attribute, $className);
static::$_mapping[$attribute->getName()][$class] = []; }
} }
}
/**
/** * @param ReflectionAttribute $attribute
* @param ReflectionAttribute $attribute * @param string $class
* @param string $class */
* @param string $method public static function setMappingClass(ReflectionAttribute $attribute, string $class)
* @param mixed $instance {
*/ if (!isset(static::$_mapping[$attribute->getName()])) {
public static function setMappingMethod(ReflectionAttribute $attribute, string $class, string $method, mixed $instance) static::$_mapping[$attribute->getName()] = [];
{ }
self::setMappingClass($attribute, $class); if (!isset(static::$_mapping[$attribute->getName()][$class])) {
static::$_mapping[$attribute->getName()][$class] = [];
if (!isset(static::$_mapping[$attribute->getName()][$class]['method'])) { }
static::$_mapping[$attribute->getName()][$class]['method'] = []; }
}
static::$_mapping[$attribute->getName()][$class]['method'][] = [$method => $instance];
} /**
* @param ReflectionAttribute $attribute
* @param string $class
/** * @param string $method
* @param ReflectionAttribute $attribute * @param mixed $instance
* @param string $class */
* @param string $property public static function setMappingMethod(ReflectionAttribute $attribute, string $class, string $method, mixed $instance)
* @param $instance {
*/ self::setMappingClass($attribute, $class);
public static function setMappingProperty(ReflectionAttribute $attribute, string $class, string $property, $instance)
{ if (!isset(static::$_mapping[$attribute->getName()][$class]['method'])) {
self::setMappingClass($attribute, $class); static::$_mapping[$attribute->getName()][$class]['method'] = [];
}
$mapping = static::$_mapping[$attribute->getName()][$class]; static::$_mapping[$attribute->getName()][$class]['method'][] = [$method => $instance];
if (!isset($mapping['property'])) { }
$mapping['property'] = [];
}
$mapping['property'][] = [$property => $instance]; /**
static::$_mapping[$attribute->getName()][$class] = $mapping; * @param ReflectionAttribute $attribute
} * @param string $class
* @param string $property
* @param $instance
/** */
* @param mixed $class public static function setMappingProperty(ReflectionAttribute $attribute, string $class, string $property, $instance)
* @return array {
*/ self::setMappingClass($attribute, $class);
public static function getTargetNote(mixed $class): array
{ $mapping = static::$_mapping[$attribute->getName()][$class];
if (!is_string($class)) { if (!isset($mapping['property'])) {
$class = $class::class; $mapping['property'] = [];
} }
return static::$_classTarget[$class] ?? []; $mapping['property'][] = [$property => $instance];
} static::$_mapping[$attribute->getName()][$class] = $mapping;
}
/**
* @param ReflectionClass $class /**
*/ * @param mixed $class
public static function setMethodNote(ReflectionClass $class) * @return array
{ */
$className = $class->getName(); public static function getTargetAnnotation(mixed $class): array
static::$_classMethodNote[$className] = static::$_classMethod[$className] = []; {
foreach ($class->getMethods() as $ReflectionMethod) { if (!is_string($class)) {
static::$_classMethod[$className][$ReflectionMethod->getName()] = $ReflectionMethod; $class = $class::class;
static::$_classMethodNote[$className][$ReflectionMethod->getName()] = []; }
foreach ($ReflectionMethod->getAttributes() as $attribute) { return static::$_classTarget[$class] ?? [];
if (!class_exists($attribute->getName())) { }
continue;
}
$instance = $attribute->newInstance(); /**
* @param ReflectionClass $class
static::$_classMethodNote[$className][$ReflectionMethod->getName()][] = $instance; */
public static function setMethodAnnotation(ReflectionClass $class)
self::setMappingMethod($attribute, $className, $ReflectionMethod->getName(), $instance); {
} $className = $class->getName();
} static::$_classMethodAnnotation[$className] = static::$_classMethod[$className] = [];
} foreach ($class->getMethods() as $ReflectionMethod) {
static::$_classMethod[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
static::$_classMethodAnnotation[$className][$ReflectionMethod->getName()] = [];
/** foreach ($ReflectionMethod->getAttributes() as $attribute) {
* @param string $class if (!class_exists($attribute->getName())) {
* @param string $method continue;
* @return bool }
*/ $instance = $attribute->newInstance();
public static function hasMethod(string $class, string $method): bool
{ static::$_classMethodAnnotation[$className][$ReflectionMethod->getName()][] = $instance;
return isset(static::$_classMethod[$class]) && isset(static::$_classMethod[$class][$method]);
} self::setMappingMethod($attribute, $className, $ReflectionMethod->getName(), $instance);
}
}
/** }
* @param ReflectionClass $class
* @return array
*/ /**
#[Pure] public static function getMethodNote(ReflectionClass $class): array * @param string $class
{ * @param string $method
return static::$_classMethodNote[$class->getName()] ?? []; * @return bool
} */
public static function hasMethod(string $class, string $method): bool
{
/** return isset(static::$_classMethod[$class]) && isset(static::$_classMethod[$class][$method]);
* @param \ReflectionClass $reflect }
* @return \ReflectionMethod|null
*/
public static function resolveTarget(ReflectionClass $reflect): ?\ReflectionMethod /**
{ * @param ReflectionClass $class
NoteManager::setPropertyNote($reflect); * @return array
NoteManager::setTargetNote($reflect); */
NoteManager::setMethodNote($reflect); #[Pure] public static function getMethodAnnotation(ReflectionClass $class): array
{
return $reflect->getConstructor(); return static::$_classMethodAnnotation[$class->getName()] ?? [];
} }
/** /**
* @param ReflectionClass $class * @param \ReflectionClass $reflect
*/ * @return \ReflectionMethod|null
public static function setPropertyNote(ReflectionClass $class) */
{ public static function resolveTarget(ReflectionClass $reflect): ?\ReflectionMethod
$className = $class->getName(); {
static::$_classProperty[$className] = static::$_classPropertyNote[$className] = []; NoteManager::setPropertyAnnotation($reflect);
foreach ($class->getProperties(ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PUBLIC | NoteManager::setTargetAnnotation($reflect);
ReflectionProperty::IS_PROTECTED) as $ReflectionMethod) { NoteManager::setMethodAnnotation($reflect);
static::$_classProperty[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
foreach ($ReflectionMethod->getAttributes() as $attribute) { return $reflect->getConstructor();
if (!class_exists($attribute->getName())) { }
continue;
}
/**
$instance = $attribute->newInstance(); * @param ReflectionClass $class
*/
static::$_classPropertyNote[$className][$ReflectionMethod->getName()] = $instance; public static function setPropertyAnnotation(ReflectionClass $class)
{
self::setMappingProperty($attribute, $className, $ReflectionMethod->getName(), $instance); $className = $class->getName();
} static::$_classProperty[$className] = static::$_classPropertyAnnotation[$className] = [];
} foreach ($class->getProperties(ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PUBLIC |
} ReflectionProperty::IS_PROTECTED) as $ReflectionMethod) {
static::$_classProperty[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
foreach ($ReflectionMethod->getAttributes() as $attribute) {
/** if (!class_exists($attribute->getName())) {
* @param string $attribute continue;
* @param string|null $class }
* @return array[]
*/ $instance = $attribute->newInstance();
public static function getAttributeTrees(string $attribute, string $class = null): array
{ static::$_classPropertyAnnotation[$className][$ReflectionMethod->getName()] = $instance;
$mapping = static::$_mapping[$attribute] ?? [];
if (empty($mapping) || empty($class)) { self::setMappingProperty($attribute, $className, $ReflectionMethod->getName(), $instance);
return $mapping; }
} }
return $mapping[$class] ?? []; }
}
/**
/** * @param string $attribute
* @param string $attribute * @param string|null $class
* @param string $class * @return array[]
* @param string|null $method */
* @return array public static function getAttributeTrees(string $attribute, string $class = null): array
*/ {
public static function getSpecify_annotation(string $attribute, string $class, string $method = null): mixed $mapping = static::$_mapping[$attribute] ?? [];
{ if (empty($mapping) || empty($class)) {
$class = self::getAttributeTrees($attribute, $class); return $mapping;
if (empty($class) || !isset($class['method'])){ }
return null; return $mapping[$class] ?? [];
} }
if (empty($method)) {
return $class['method'];
} /**
foreach ($class['method'] as $value) { * @param string $attribute
$key = key($value); * @param string $class
if ($method == $key) { * @param string|null $method
return $value[$key]; * @return array
} */
} public static function getSpecify_annotation(string $attribute, string $class, string $method = null): mixed
return null; {
} $class = self::getAttributeTrees($attribute, $class);
if (empty($class) || !isset($class['method'])) {
return null;
/** }
* @param string $attribute if (empty($method)) {
* @param string $class return $class['method'];
* @param string $method }
* @return mixed foreach ($class['method'] as $value) {
*/ $key = key($value);
public static function getPropertyByAnnotation(string $attribute, string $class, string $method): mixed if ($method == $key) {
{ return $value[$key];
$class = self::getAttributeTrees($attribute, $class); }
if (empty($class) || !isset($class['property'])) { }
return []; return null;
} }
foreach ($class['property'] as $value) {
$key = key($value);
if ($method == $key) { /**
return $value[$key]; * @param string $attribute
} * @param string $class
} * @param string $method
return null; * @return mixed
} */
public static function getPropertyByAnnotation(string $attribute, string $class, string $method): mixed
{
/** $class = self::getAttributeTrees($attribute, $class);
* @param ReflectionClass|string $class if (empty($class) || !isset($class['property'])) {
* @return array return [];
* @throws \ReflectionException }
*/ foreach ($class['property'] as $value) {
public static function getMethods(ReflectionClass|string $class): array $key = key($value);
{ if ($method == $key) {
if (is_string($class)) { return $value[$key];
$class = self::getReflect($class); }
} }
return static::$_classMethod[$class->getName()] ?? []; return null;
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass|string $class
* @return ReflectionProperty[] * @return array
*/ * @throws \ReflectionException
#[Pure] public static function getProperty(ReflectionClass $class): array */
{ public static function getMethods(ReflectionClass|string $class): array
return static::$_classProperty[$class->getName()] ?? []; {
} if (is_string($class)) {
$class = self::getReflect($class);
}
/** return static::$_classMethod[$class->getName()] ?? [];
* @param ReflectionClass $class }
* @return array
*/
#[Pure] public static function getPropertyNote(ReflectionClass $class): array /**
{ * @param ReflectionClass $class
return static::$_classPropertyNote[$class->getName()] ?? []; * @return ReflectionProperty[]
} */
#[Pure] public static function getProperty(ReflectionClass $class): array
{
} return static::$_classProperty[$class->getName()] ?? [];
}
/**
* @param ReflectionClass $class
* @return array
*/
#[Pure] public static function getPropertyAnnotation(ReflectionClass $class): array
{
return static::$_classPropertyAnnotation[$class->getName()] ?? [];
}
}
+46 -46
View File
@@ -1,46 +1,46 @@
<?php <?php
namespace Kiri; namespace Kiri;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
/** /**
* Class Environmental * Class Environmental
* @package Kiri * @package Kiri
*/ */
class Environmental class Environmental
{ {
/** /**
* @return bool * @return bool
*/ */
public function isMac(): bool public function isMac(): bool
{ {
$output = strtolower(PHP_OS | PHP_OS_FAMILY); $output = strtolower(PHP_OS | PHP_OS_FAMILY);
if (str_contains('mac', $output)) { if (str_contains('mac', $output)) {
return true; return true;
} else if (str_contains('darwin', $output)) { } else if (str_contains('darwin', $output)) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
/** /**
* @return bool * @return bool
*/ */
#[Pure] public function isLinux(): bool #[Pure] public function isLinux(): bool
{ {
if (!static::isMac()) { if (!static::isMac()) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
} }
+158 -158
View File
@@ -1,158 +1,158 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/26 0026 * Date: 2018/4/26 0026
* Time: 10:00 * Time: 10:00
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Error; namespace Kiri\Error;
use Exception; use Exception;
use Http\Handler\Formatter\IFormatter; use Kiri\Message\Handler\Formatter\IFormatter;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Core\Json; use Kiri\Core\Json;
use Kiri\Events\EventDispatch; use Kiri\Events\EventDispatch;
use Kiri\Kiri; use Kiri\Kiri;
use Http\Events\OnAfterRequest; use Kiri\Message\Events\OnAfterRequest;
/** /**
* Class ErrorHandler * Class ErrorHandler
* *
* @package Kiri\Kiri\Base * @package Kiri\Kiri\Base
* @property-read $asError * @property-read $asError
*/ */
class ErrorHandler extends Component implements ErrorInterface class ErrorHandler extends Component implements ErrorInterface
{ {
/** @var ?IFormatter $message */ /** @var ?IFormatter $message */
private ?IFormatter $message = NULL; private ?IFormatter $message = NULL;
public string $category = 'app'; public string $category = 'app';
/** /**
* 错误处理注册 * 错误处理注册
*/ */
public function register() public function register()
{ {
// ini_set('display_errors', '1'); // ini_set('display_errors', '1');
set_exception_handler([$this, 'exceptionHandler']); set_exception_handler([$this, 'exceptionHandler']);
if (defined('HHVM_VERSION')) { if (defined('HHVM_VERSION')) {
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
} else { } else {
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
} }
register_shutdown_function([$this, 'shutdown']); register_shutdown_function([$this, 'shutdown']);
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function shutdown() public function shutdown()
{ {
$lastError = error_get_last(); $lastError = error_get_last();
if (empty($lastError) || $lastError['type'] !== E_ERROR) { if (empty($lastError) || $lastError['type'] !== E_ERROR) {
return; return;
} }
$this->category = 'shutdown'; $this->category = 'shutdown';
$messages = explode(PHP_EOL, $lastError['message']); $messages = explode(PHP_EOL, $lastError['message']);
$message = array_shift($messages); $message = array_shift($messages);
$this->sendError($message, $lastError['file'], $lastError['line']); $this->sendError($message, $lastError['file'], $lastError['line']);
} }
/** /**
* @param \Throwable $exception * @param \Throwable $exception
* *
* @throws Exception * @throws Exception
*/ */
public function exceptionHandler(\Throwable $exception) public function exceptionHandler(\Throwable $exception)
{ {
$this->category = 'exception'; $this->category = 'exception';
di(EventDispatch::class)->dispatch(new OnAfterRequest()); di(EventDispatch::class)->dispatch(new OnAfterRequest());
$this->sendError($exception->getMessage(), $exception->getFile(), $exception->getLine()); $this->sendError($exception->getMessage(), $exception->getFile(), $exception->getLine());
} }
/** /**
* @throws Exception * @throws Exception
* *
* 以异常形式抛出错误,防止执行后续程序 * 以异常形式抛出错误,防止执行后续程序
*/ */
public function errorHandler() public function errorHandler()
{ {
$error = func_get_args(); $error = func_get_args();
$path = ['file' => $error[2], 'line' => $error[3]]; $path = ['file' => $error[2], 'line' => $error[3]];
if ($error[0] === 0) { if ($error[0] === 0) {
$error[0] = 500; $error[0] = 500;
} }
$data = Json::to(500, $error[1], $path); $data = Json::to(500, $error[1], $path);
Kiri::app()->error($data, 'error'); Kiri::app()->error($data, 'error');
di(EventDispatch::class)->dispatch(new OnAfterRequest()); di(EventDispatch::class)->dispatch(new OnAfterRequest());
throw new \ErrorException($error[1], $error[0], 1, $error[2], $error[3]); throw new \ErrorException($error[1], $error[0], 1, $error[2], $error[3]);
} }
/** /**
* @param $message * @param $message
* @param $file * @param $file
* @param $line * @param $line
* @param int $code * @param int $code
* @return false|string * @return false|string
* @throws Exception * @throws Exception
*/ */
public function sendError($message, $file, $line, $code = 500): bool|string public function sendError($message, $file, $line, $code = 500): bool|string
{ {
$path = ['file' => $file, 'line' => $line]; $path = ['file' => $file, 'line' => $line];
var_dump(func_get_args()); var_dump(func_get_args());
$data = Json::to($code, $this->category . ': ' . $message, $path); $data = Json::to($code, $this->category . ': ' . $message, $path);
write($data, $this->category); write($data, $this->category);
return $data; return $data;
} }
/** /**
* @return mixed * @return mixed
*/ */
public function getErrorMessage(): mixed public function getErrorMessage(): mixed
{ {
$message = $this->message; $message = $this->message;
$this->message = NULL; $this->message = NULL;
return $message->getData(); return $message->getData();
} }
/** /**
* @return bool * @return bool
*/ */
public function getAsError(): bool public function getAsError(): bool
{ {
return $this->message !== NULL; return $this->message !== NULL;
} }
/** /**
* @param $message * @param $message
* @param string $category * @param string $category
* *
* @throws Exception * @throws Exception
*/ */
public function writer($message, string $category = 'app') public function writer($message, string $category = 'app')
{ {
Kiri::app()->debug($message, $category); Kiri::app()->debug($message, $category);
} }
} }
+28 -28
View File
@@ -1,28 +1,28 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-20 * Date: 2019-03-20
* Time: 10:25 * Time: 10:25
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Error; namespace Kiri\Error;
/** /**
* Interface ErrorInterface * Interface ErrorInterface
* @package Kiri\Kiri\Error * @package Kiri\Kiri\Error
*/ */
interface ErrorInterface interface ErrorInterface
{ {
/** /**
* @param $message * @param $message
* @param $file * @param $file
* @param $line * @param $line
* @param int $code * @param int $code
* @return mixed * @return mixed
*/ */
public function sendError($message, $file, $line, $code = 500): mixed; public function sendError($message, $file, $line, $code = 500): mixed;
} }
+117 -111
View File
@@ -1,111 +1,117 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: admin * User: admin
* Date: 2019-03-22 * Date: 2019-03-22
* Time: 14:36 * Time: 14:36
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Error; namespace Kiri\Error;
use Annotation\Inject; use Exception;
use Exception; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Component; use Kiri\Core\Json;
use Kiri\Core\Json; use Kiri\Kiri;
use Kiri\Events\EventProvider; use Kiri\Annotation\Inject;
use Kiri\Kiri; use Psr\Log\LoggerInterface;
use Psr\Log\LoggerInterface; use Throwable;
use Throwable;
/**
/** * Class Logger
* Class Logger * @package Kiri\Kiri\Error
* @package Kiri\Kiri\Error * @mixin \Kiri\Abstracts\Logger
* @mixin \Kiri\Abstracts\Logger */
*/ class Logger extends Component
class Logger extends Component {
{
private array $logs = [];
private array $logs = [];
/**
/** @var EventProvider */ * inject logger
#[Inject(EventProvider::class)] *
public EventProvider $eventProvider; * @var LoggerInterface
*/
#[Inject(LoggerInterface::class)]
/** public LoggerInterface $logger;
* inject logger
*
* @var LoggerInterface private array $sources = [];
*/
#[Inject(LoggerInterface::class)]
public LoggerInterface $logger; /**
* @param string $application
* @return string
private array $sources = []; */
public function getLastError(string $application = 'app'): string
{
/** return $this->logs[$application] ?? 'Unknown error.';
* @param string $application }
* @return string
*/
public function getLastError(string $application = 'app'): string /**
{ * @param $message
return 'Unknown error.'; * @param $method
} * @return void
*/
/** public function fail($message, $method)
* @param string $messages {
* @param string $method $this->logs[$method] = $message;
* @throws Exception }
*/
public function write(string $messages, string $method = 'app')
{ /**
if (empty($messages)) { * @param string $messages
return; * @param string $method
} * @throws Exception
*/
$to_day = date('Y-m-d'); public function write(string $messages, string $method = 'app')
{
$fileName = storage('server-' . $to_day . '.log', $dirName = 'log/' . ($method ?? 'app')); if (empty($messages)) {
return;
file_put_contents($fileName, '[' . date('Y-m-d H:i:s') . ']:' . PHP_EOL . $messages . PHP_EOL); }
}
$to_day = date('Y-m-d');
/** $fileName = storage('server-' . $to_day . '.log', $dirName = 'log/' . ($method ?? 'app'));
* @param Throwable $exception
* @return mixed file_put_contents($fileName, '[' . date('Y-m-d H:i:s') . ']:' . PHP_EOL . $messages . PHP_EOL);
* @throws Exception }
*/
public function exception(Throwable $exception): mixed
{ /**
$code = $exception->getCode() == 0 ? 500 : $exception->getCode(); * @param Throwable $exception
* @return mixed
$logger = Kiri::app()->getLogger(); * @throws Exception
$logger->write(jTraceEx($exception), 'exception'); */
public function exception(Throwable $exception): mixed
return Json::to($code, $exception->getMessage(), [ {
'file' => $exception->getFile(), $code = $exception->getCode() == 0 ? 500 : $exception->getCode();
'line' => $exception->getLine()
]); $logger = Kiri::app()->getLogger();
} $logger->write(jTraceEx($exception), 'exception');
return Json::to($code, $exception->getMessage(), [
/** 'file' => $exception->getFile(),
* @param string $name 'line' => $exception->getLine()
* @param array $arguments ]);
* @return mixed }
*/
public function __call(string $name, array $arguments): mixed
{ /**
if (!method_exists($this, $name)) { * @param string $name
return $this->logger->{$name}(...$arguments); * @param array $arguments
} else { * @return mixed
return $this->{$name}(...$arguments); */
} public function __call(string $name, array $arguments): mixed
} {
if (!method_exists($this, $name)) {
return $this->logger->{$name}(...$arguments);
} } else {
return $this->{$name}(...$arguments);
}
}
}
+53 -52
View File
@@ -1,52 +1,53 @@
<?php <?php
namespace Kiri\Error; namespace Kiri\Error;
use Exception; use Exception;
use Http\Aspect\OnAspectInterface; use Kiri\Message\Aspect\OnAspectInterface;
use Http\Aspect\OnJoinPointInterface; use Kiri\Message\Aspect\OnJoinPointInterface;
use Http\Constrict\RequestInterface; use Kiri\Message\Constrict\RequestInterface;
use Kiri\Kiri; use Kiri\Kiri;
use Psr\Log\LoggerInterface;
/**
* Class LoggerAspect /**
* @package Kiri\Error * Class LoggerAspect
*/ * @package Kiri\Error
class LoggerAspect implements OnAspectInterface */
{ class LoggerAspect implements OnAspectInterface
{
/**
* @param OnJoinPointInterface $joinPoint /**
* @return mixed * @param OnJoinPointInterface $joinPoint
* @throws Exception * @return mixed
*/ * @throws Exception
public function process(OnJoinPointInterface $joinPoint): mixed */
{ public function process(OnJoinPointInterface $joinPoint): mixed
$time = microtime(true); {
$time = microtime(true);
$response = $joinPoint->process();
$response = $joinPoint->process();
$this->print_runtime($time);
$this->print_runtime($time);
return $response;
} return $response;
}
/**
* @param $startTime /**
* @throws Exception * @param $startTime
*/ * @throws Exception
private function print_runtime($startTime) */
{ private function print_runtime($startTime)
$request = Kiri::getDi()->get(RequestInterface::class); {
$request = Kiri::getDi()->get(RequestInterface::class);
$runTime = round(microtime(true) - $startTime, 6); $runTime = round(microtime(true) - $startTime, 6);
echo sprintf('run %s use time %6f', $request->getUri()->__toString(), $runTime);
echo PHP_EOL; $logger = Kiri::getDi()->get(LoggerInterface::class);
} $logger->debug(sprintf('run %s use time %6f', $request->getUri()->__toString(), $runTime));
}
}
}
+84 -83
View File
@@ -1,83 +1,84 @@
<?php <?php
namespace Kiri\Error; namespace Kiri\Error;
use Exception; use Exception;
use JetBrains\PhpStorm\Pure; use Kiri\Core\Json;
use Kiri\Core\Json; use Kiri\Exception\ComponentException;
use Kiri\Exception\ComponentException; use Kiri\Kiri;
use Kiri\Kiri; use Kiri\Server\Abstracts\BaseProcess;
use Swoole\Coroutine; use Swoole\Coroutine;
use Swoole\Process; use Swoole\Process;
use Server\Abstracts\BaseProcess;
/**
/** * Class LoggerProcess
* Class LoggerProcess * @package Kiri\Error
* @package Kiri\Error */
*/ class LoggerProcess extends BaseProcess
class LoggerProcess extends BaseProcess {
{
public string $name = 'logger process';
public string $name = 'logger process';
/**
* @param Process $process
/** * @throws ComponentException
* @param Process $process */
* @throws ComponentException public function process(Process $process): void
*/ {
public function process(Process $process): void // TODO: Implement onHandler() method.
{ $this->message($process);
// TODO: Implement onHandler() method. }
$this->message($process);
}
/**
* @param Process $process
/** * @throws ComponentException
* @param Process $process * @throws Exception
* @throws ComponentException */
* @throws Exception public function message(Process $process)
*/ {
public function message(Process $process) if ($this->isStop()) {
{ return;
$message = Json::decode($process->read()); }
if (!empty($message)) { $message = Json::decode($process->read());
Kiri::writeFile($this->getDirName($message), $message[0], FILE_APPEND); if (!empty($message)) {
Kiri::writeFile($this->getDirName($message), $message[0], FILE_APPEND);
$this->checkLogFile($message[1]);
} $this->checkLogFile($message[1]);
}
Coroutine\System::sleep(1);
Coroutine\System::sleep(1);
$this->message($process);
} $this->message($process);
}
/**
* @param $message /**
* @return string * @param $message
* @throws Exception * @return string
*/ * @throws Exception
private function getDirName($message): string */
{ private function getDirName($message): string
return storage('server-' . date('Y-m-d') . '.log', $message[1]); {
} return storage('server-' . date('Y-m-d') . '.log', $message[1]);
}
/**
* @param $dirName /**
* @throws Exception * @param $dirName
*/ * @throws Exception
private function checkLogFile($dirName) */
{ private function checkLogFile($dirName)
$files = new \DirectoryIterator(storage(null, $dirName)); {
if ($files->getSize() < 15) { $files = new \DirectoryIterator(storage(null, $dirName));
return; if ($files->getSize() < 15) {
} return;
Coroutine\System::exec('find ' . storage(null, $dirName) . '/ -mtime +15 -name "*.log" -exec rm -rf {} \;'); }
} Coroutine\System::exec('find ' . storage(null, $dirName) . '/ -mtime +15 -name "*.log" -exec rm -rf {} \;');
}
}
}
+238 -239
View File
@@ -1,239 +1,238 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri; namespace Kiri;
use Exception; use Exception;
use Kiri\Abstracts\BaseObject; use Kiri\Abstracts\Component;
use Swoole\Coroutine;
/**
/** * Class Event
* Class Event * @package Kiri
* @package Kiri */
*/ class Event extends Component
class Event extends BaseObject {
{
public bool $isVide = true;
public bool $isVide = true;
private static array $_events = [];
private static array $_events = [];
const PIPE_MESSAGE = 'SERVER:PIPE:MESSAGE';
const PIPE_MESSAGE = 'SERVER:PIPE:MESSAGE'; const TASK_FINISH = 'SERVER:TASK::FINISH';
const TASK_FINISH = 'SERVER:TASK::FINISH';
const EVENT_AFTER_REQUEST = 'SERVER:REQUEST:AFTER:START';
const EVENT_AFTER_REQUEST = 'SERVER:REQUEST:AFTER:START'; const EVENT_BEFORE_REQUEST = 'SERVER:REQUEST:BEFORE:START';
const EVENT_BEFORE_REQUEST = 'SERVER:REQUEST:BEFORE:START'; const RECEIVE_CONNECTION = 'SERVER:RECEIVE:CONNECTION';
const RECEIVE_CONNECTION = 'SERVER:RECEIVE:CONNECTION';
const SYSTEM_RESOURCE_RELEASES = 'SYSTEM::RESOURCE::RELEASES';
const SYSTEM_RESOURCE_RELEASES = 'SYSTEM::RESOURCE::RELEASES'; const SYSTEM_RESOURCE_CLEAN = 'SYSTEM::RESOURCE::CLEAN';
const SYSTEM_RESOURCE_CLEAN = 'SYSTEM::RESOURCE::CLEAN';
const PROCESS_WORKER_STOP = 'SERVER:PROCESS:WORKER:STOP';
const PROCESS_WORKER_STOP = 'SERVER:PROCESS:WORKER:STOP';
const SERVER_AFTER_RELOAD = 'SERVER:AFTER:RELOAD';
const SERVER_AFTER_RELOAD = 'SERVER:AFTER:RELOAD'; const SERVER_BEFORE_RELOAD = 'SERVER:BEFORE:RELOAD';
const SERVER_BEFORE_RELOAD = 'SERVER:BEFORE:RELOAD'; const SERVER_CONNECT = 'SERVER:CONNECT';
const SERVER_CONNECT = 'SERVER:CONNECT'; const SERVER_PACKAGE = 'SERVER:PACKAGE';
const SERVER_PACKAGE = 'SERVER:PACKAGE'; const SERVER_RECEIVE = 'SERVER:RECEIVE';
const SERVER_RECEIVE = 'SERVER:RECEIVE';
const SERVER_EVENT_START = 'SERVER:EVENT:START';
const SERVER_EVENT_START = 'SERVER:EVENT:START'; const SERVER_MANAGER_START = 'SERVER:EVENT:MANAGER:START';
const SERVER_MANAGER_START = 'SERVER:EVENT:MANAGER:START'; const SERVER_MANAGER_STOP = 'SERVER:EVENT:MANAGER:START';
const SERVER_MANAGER_STOP = 'SERVER:EVENT:MANAGER:START'; const SERVER_WORKER_STOP = 'SERVER:EVENT:WORKER:STOP';
const SERVER_WORKER_STOP = 'SERVER:EVENT:WORKER:STOP'; const SERVER_WORKER_START = 'SERVER:EVENT:WORKER:START';
const SERVER_WORKER_START = 'SERVER:EVENT:WORKER:START'; const SERVER_AFTER_WORKER_START = 'SERVER:EVENT:AFTER:WORKER:START';
const SERVER_AFTER_WORKER_START = 'SERVER:EVENT:AFTER:WORKER:START'; const SERVER_BEFORE_START = 'SERVER:EVENT:BEFORE:START';
const SERVER_BEFORE_START = 'SERVER:EVENT:BEFORE:START'; const BEFORE_COMMAND_EXECUTE = 'COMMAND:EVENT:BEFORE:EXECUTE';
const BEFORE_COMMAND_EXECUTE = 'COMMAND:EVENT:BEFORE:EXECUTE'; const AFTER_COMMAND_EXECUTE = 'COMMAND:EVENT:AFTER:EXECUTE';
const AFTER_COMMAND_EXECUTE = 'COMMAND:EVENT:AFTER:EXECUTE'; const SERVER_TASK_START = 'SERVER:EVENT:TASK:START';
const SERVER_TASK_START = 'SERVER:EVENT:TASK:START'; const SERVER_WORKER_EXIT = 'SERVER:EVENT:WORKER:EXIT';
const SERVER_WORKER_EXIT = 'SERVER:EVENT:WORKER:EXIT'; const SERVER_WORKER_ERROR = 'SERVER:EVENT:WORKER:ERROR';
const SERVER_WORKER_ERROR = 'SERVER:EVENT:WORKER:ERROR'; const SERVER_SHUTDOWN = 'SERVER:EVENT:SHUTDOWN';
const SERVER_SHUTDOWN = 'SERVER:EVENT:SHUTDOWN';
const SERVER_HANDSHAKE = 'on handshake';
const SERVER_HANDSHAKE = 'on handshake'; const SERVER_MESSAGE = 'on message';
const SERVER_MESSAGE = 'on message'; const SERVER_CLIENT_CLOSE = 'SERVER:CLIENT:CLOSE';
const SERVER_CLIENT_CLOSE = 'SERVER:CLIENT:CLOSE';
const SERVER_ON_START = 'Start';
const SERVER_ON_START = 'Start'; const SERVER_ON_SHUTDOWN = 'Shutdown';
const SERVER_ON_SHUTDOWN = 'Shutdown'; const SERVER_ON_WORKER_START = 'WorkerStart';
const SERVER_ON_WORKER_START = 'WorkerStart'; const SERVER_ON_WORKER_STOP = 'WorkerStop';
const SERVER_ON_WORKER_STOP = 'WorkerStop'; const SERVER_ON_WORKER_EXIT = 'WorkerExit';
const SERVER_ON_WORKER_EXIT = 'WorkerExit'; const SERVER_ON_CONNECT = 'Connect';
const SERVER_ON_CONNECT = 'Connect'; const SERVER_ON_RECEIVE = 'Receive';
const SERVER_ON_RECEIVE = 'Receive'; const SERVER_ON_PACKET = 'Packet';
const SERVER_ON_PACKET = 'Packet'; const SERVER_ON_REQUEST = 'request';
const SERVER_ON_REQUEST = 'request'; const SERVER_ON_CLOSE = 'Close';
const SERVER_ON_CLOSE = 'Close'; const SERVER_ON_TASK = 'Task';
const SERVER_ON_TASK = 'Task'; const SERVER_ON_FINISH = 'Finish';
const SERVER_ON_FINISH = 'Finish'; const SERVER_ON_PIPE_MESSAGE = 'OnPipeMessageInterface';
const SERVER_ON_PIPE_MESSAGE = 'OnPipeMessageInterface'; const SERVER_ON_WORKER_ERROR = 'WorkerError';
const SERVER_ON_WORKER_ERROR = 'WorkerError'; const SERVER_ON_MANAGER_START = 'ManagerStart';
const SERVER_ON_MANAGER_START = 'ManagerStart'; const SERVER_ON_MANAGER_STOP = 'ManagerStop';
const SERVER_ON_MANAGER_STOP = 'ManagerStop'; const SERVER_ON_BEFORE_RELOAD = 'BeforeReload';
const SERVER_ON_BEFORE_RELOAD = 'BeforeReload'; const SERVER_ON_AFTER_RELOAD = 'AfterReload';
const SERVER_ON_AFTER_RELOAD = 'AfterReload';
/**
/** * @param $name
* @param $name * @param $callback
* @param $callback * @param bool $isAppend
* @param bool $isAppend * @throws Exception
* @throws Exception */
*/ public static function on($name, $callback, bool $isAppend = false)
public static function on($name, $callback, bool $isAppend = false) {
{ if (!isset(static::$_events[$name])) {
if (!isset(static::$_events[$name])) { static::$_events[$name] = [];
static::$_events[$name] = []; }
} if (is_array($callback) && is_string($callback[0])) {
if (is_array($callback) && is_string($callback[0])) { if (!class_exists($callback[0])) {
if (!class_exists($callback[0])) { throw new Exception('Undefined callback class.');
throw new Exception('Undefined callback class.'); }
} $callback[0] = di($callback[0]);
$callback[0] = di($callback[0]); }
} if (static::exists($name, $callback)) {
if (static::exists($name, $callback)) { return;
return; }
} if (!empty(static::$_events[$name]) && $isAppend === true) {
if (!empty(static::$_events[$name]) && $isAppend === true) { array_unshift(static::$_events[$name], [$callback]);
array_unshift(static::$_events[$name], [$callback]); } else {
} else { static::$_events[$name][] = [$callback];
static::$_events[$name][] = [$callback]; }
} }
}
/**
/** * @param $name
* @param $name * @param $callback
* @param $callback */
*/ public static function of($name, $callback): void
public static function of($name, $callback): void {
{ if (!isset(static::$_events[$name])) {
if (!isset(static::$_events[$name])) { return;
return; }
} foreach (static::$_events[$name] as $index => $event) {
foreach (static::$_events[$name] as $index => $event) { [$handler] = $event;
[$handler] = $event; if ($handler !== $callback) {
if ($handler !== $callback) { continue;
continue; }
} unset(static::$_events[$name][$index]);
unset(static::$_events[$name][$index]); }
} }
}
/**
/** * @param $name
* @param $name */
*/ public static function offName($name): void
public static function offName($name): void {
{ unset(static::$_events[$name]);
unset(static::$_events[$name]); }
}
/**
/** * @param $name
* @param $name * @param null $callback
* @param null $callback * @return bool
* @return bool */
*/ public static function exists($name, $callback): bool
public static function exists($name, $callback): bool {
{ if ($callback instanceof \Closure || !isset(static::$_events[$name])) {
if ($callback instanceof \Closure || !isset(static::$_events[$name])) { return false;
return false; }
} foreach (static::$_events[$name] as $event) {
foreach (static::$_events[$name] as $event) { [$handler] = $event;
[$handler] = $event; if ($handler === $callback) {
if ($handler === $callback) { return true;
return true; }
} }
} return false;
return false; }
}
/**
/** * @param $name
* @param $name * @param $handler
* @param $handler * @return mixed
* @return mixed */
*/ public static function get($name, $handler): mixed
public static function get($name, $handler): mixed {
{ if (!static::exists($name, $handler)) {
if (!static::exists($name, $handler)) { return null;
return null; }
} if (empty($handler)) {
if (empty($handler)) { return static::$_events[$name];
return static::$_events[$name]; }
} foreach (static::$_events[$name] as $event) {
foreach (static::$_events[$name] as $event) { [$callback] = $event;
[$callback] = $event; if ($callback === $handler) {
if ($callback === $handler) { return [$event];
return [$event]; }
} }
} return null;
return null; }
}
public static function clean()
public static function clean() {
{ static::$_events = [];
static::$_events = []; }
}
/**
/** * @param $name
* @param $name * @param array $params
* @param array $params * @return bool
* @return bool * @throws Exception
* @throws Exception */
*/ public function dispatch($name, array $params = []): bool
public function dispatch($name, array $params = []): bool {
{ return static::trigger($name, $params);
return static::trigger($name, $params); }
}
/**
/** * @param $name
* @param $name * @param null $parameter
* @param null $parameter * @param false $is_remove
* @param false $is_remove * @return bool
* @return bool * @throws Exception
* @throws Exception */
*/ public static function trigger($name, $parameter = null, bool $is_remove = false): bool
public static function trigger($name, $parameter = null, bool $is_remove = false): bool {
{ foreach ((static::$_events[$name] ?? []) as $key => $event) {
foreach ((static::$_events[$name] ?? []) as $key => $event) { static::execute($event, $parameter);
static::execute($event, $parameter); if ($event instanceof \Closure) {
if ($event instanceof \Closure) { unset(static::$_events[$name][$key]);
unset(static::$_events[$name][$key]); }
} }
} if ($is_remove) {
if ($is_remove) { unset(static::$_events[$name]);
unset(static::$_events[$name]); }
} return true;
return true; }
}
/**
/** * @param $event
* @param $event * @param $parameter
* @param $parameter * @return void
* @return void * @throws Exception
* @throws Exception */
*/ private static function execute($event, $parameter): void
private static function execute($event, $parameter): void {
{ try {
try { call_user_func($event[0], ...$parameter);
call_user_func($event[0], ...$parameter); } catch (\Throwable $throwable) {
} catch (\Throwable $throwable) { logger()->addError($throwable, 'throwable');
logger()->addError($throwable, 'throwable'); return;
return; }
} }
}
}
}
+16 -16
View File
@@ -1,16 +1,16 @@
<?php <?php
namespace Kiri\Events; namespace Kiri\Events;
class OnAfterCommandExecute class OnAfterCommandExecute
{ {
/** /**
* *
*/ */
public function __construct() public function __construct()
{ {
} }
} }
@@ -1,8 +1,8 @@
<?php <?php
namespace Kiri\Events; namespace Kiri\Events;
class OnBeforeCommandExecute class OnBeforeCommandExecute
{ {
} }
+29 -29
View File
@@ -1,29 +1,29 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use Throwable; use Throwable;
/** /**
* Class AuthException * Class AuthException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class AuthException extends \Exception class AuthException extends \Exception
{ {
/** /**
* AuthException constructor. * AuthException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
public function __construct($message = "", $code = 0, Throwable $previous = null) public function __construct($message = "", $code = 0, Throwable $previous = null)
{ {
parent::__construct($message, 4001, $previous); parent::__construct($message, 4001, $previous);
} }
} }
+35 -35
View File
@@ -1,35 +1,35 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/25 0025 * Date: 2018/4/25 0025
* Time: 18:34 * Time: 18:34
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use Throwable; use Throwable;
/** /**
* Class ComponentException * Class ComponentException
* @package Kiri\Kiri\Exception * @package Kiri\Kiri\Exception
*/ */
class ComponentException extends \Exception class ComponentException extends \Exception
{ {
/** /**
* ComponentException constructor. * ComponentException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
public function __construct(string $message = "", int $code = 0, Throwable $previous = NULL) public function __construct(string $message = "", int $code = 0, Throwable $previous = NULL)
{ {
parent::__construct($message, 5000, $previous); parent::__construct($message, 5000, $previous);
} }
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
/** /**
* Class ConfigException * Class ConfigException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class ConfigException extends \Exception class ConfigException extends \Exception
{ {
} }
+14 -14
View File
@@ -1,14 +1,14 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
/** /**
* Class InitException * Class InitException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class InitException extends \Exception class InitException extends \Exception
{ {
} }
+36 -36
View File
@@ -1,36 +1,36 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/24 0024 * Date: 2018/4/24 0024
* Time: 17:32 * Time: 17:32
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use Throwable; use Throwable;
/** /**
* Class NotFindClassException * Class NotFindClassException
* @package Kiri\Kiri\Exception * @package Kiri\Kiri\Exception
*/ */
class NotFindClassException extends \Exception class NotFindClassException extends \Exception
{ {
/** /**
* NotFindClassException constructor. * NotFindClassException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
#[Pure] public function __construct(string $message = "", int $code = 0, Throwable $previous = null) #[Pure] public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
{ {
$message = "No class named `$message` was found, please check if the class name is correct"; $message = "No class named `$message` was found, please check if the class name is correct";
parent::__construct($message, 404, $previous); parent::__construct($message, 404, $previous);
} }
} }
@@ -1,35 +1,35 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: whwyy * User: whwyy
* Date: 2018/4/24 0024 * Date: 2018/4/24 0024
* Time: 17:32 * Time: 17:32
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
use Throwable; use Throwable;
/** /**
* Class NotFindClassException * Class NotFindClassException
* @package Kiri\Kiri\Exception * @package Kiri\Kiri\Exception
*/ */
class NotFindPropertyException extends \Exception class NotFindPropertyException extends \Exception
{ {
/** /**
* NotFindClassException constructor. * NotFindClassException constructor.
* @param string $message * @param string $message
* @param int $code * @param int $code
* @param Throwable|null $previous * @param Throwable|null $previous
*/ */
public function __construct(string $message = "", int $code = 0, Throwable $previous = null) public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
{ {
$message = "No class named `$message` was found, please check if the class name is correct"; $message = "No class named `$message` was found, please check if the class name is correct";
parent::__construct($message, 404, $previous); parent::__construct($message, 404, $previous);
} }
} }
+15 -15
View File
@@ -1,15 +1,15 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Exception; namespace Kiri\Exception;
/** /**
* Class RedisConnectException * Class RedisConnectException
* @package Kiri\Exception * @package Kiri\Exception
*/ */
class RedisConnectException extends \Exception class RedisConnectException extends \Exception
{ {
} }
+225 -154
View File
@@ -1,154 +1,225 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Annotation\Inject; use Exception;
use Exception; use Kiri\Abstracts\Config;
use Kiri\Abstracts\Config; use Kiri\Core\Json;
use Kiri\Error\Logger; use Kiri\Error\Logger;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri\Kiri;
use Swoole\Coroutine; use Kiri\Annotation\Inject;
use Swoole\Process; use Swoole\Coroutine;
use Symfony\Component\Console\Command\Command; use Swoole\Process;
use Symfony\Component\Console\Input\InputInterface; use Swoole\Timer;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
/** use Symfony\Component\Console\Output\OutputInterface;
*
*/
class HotReload extends Command /**
{ *
*/
class HotReload extends Command
public bool $isReloading = false; {
public bool $isReloadingOut = false;
public ?array $dirs = [];
public bool $isReloading = FALSE;
public int $events; public bool $isReloadingOut = FALSE;
public ?array $dirs = [];
public int $int = -1;
public int $events;
private ?Process $process = null; public int $int = -1;
public Inotify|Scaner $driver; private ?Process $process = NULL;
#[Inject(Logger::class)] public Inotify|Scaner $driver;
public Logger $logger;
#[Inject(Logger::class)]
protected mixed $source = null; public Logger $logger;
protected mixed $pipes = [];
protected mixed $source = NULL;
protected ?Coroutine\Channel $channel = null;
protected mixed $pipes = [];
/** protected ?Coroutine\Channel $channel = NULL;
*
*/
protected function configure() /**
{ */
$this->setName('sw:wather') protected function configure()
->setDescription('server start'); {
} $this->setName('sw:wather')->setDescription('server start');
}
/**
* @param InputInterface $input /**
* @param OutputInterface $output * @throws ConfigException
* @return int * @throws \ReflectionException
* @throws ConfigException * @throws Exception
* @throws Exception */
*/ protected function initCore()
public function execute(InputInterface $input, OutputInterface $output): int {
{ set_error_handler([$this, 'errorHandler']);
// TODO: Implement onHandler() method. $this->dirs = Config::get('inotify', [APP_PATH . 'app']);
set_error_handler([$this, 'onErrorHandler']); if (!extension_loaded('inotify')) {
$this->dirs = Config::get('inotify', [APP_PATH . 'app']); $this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]);
swoole_async_set(['enable_coroutine' => false]); } else {
if (!extension_loaded('inotify')) { $this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]);
$this->driver = Kiri::getDi()->get(Scaner::class, [$this->dirs, $this]); }
} else { $this->clearOtherService();
$this->driver = Kiri::getDi()->get(Inotify::class, [$this->dirs, $this]); $this->setProcessName();
} }
if (Kiri::getPlatform()->isLinux()) {
swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather');
} /**
$this->trigger_reload(); * @throws ConfigException
*/
var_dump(getmypid()); public function setProcessName()
Process::signal(SIGTERM, [$this, 'onSignal']); {
Process::signal(SIGKILL, [$this, 'onSignal']); swoole_async_set(['enable_coroutine' => FALSE]);
if (Kiri::getPlatform()->isLinux()) {
$this->driver->start(); swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather');
return 0; }
} }
/** /**
* @param $data * @throws Exception
* @throws Exception */
*/ public function clearOtherService()
public function onSignal($data) {
{ if (file_exists(storage('.manager.pid'))) {
if (!$data) { $pid = (int)file_get_contents(storage('.manager.pid'));
return; if ($pid > 0 && Process::kill($pid, 0)) {
} Process::kill($pid, 15) && Process::wait(TRUE);
$this->driver->clear(); }
$pid = file_get_contents(storage('.swoole.pid')); }
if (!empty($pid) && Process::kill($pid, 0)) { file_put_contents(storage('.manager.pid'), getmypid());
Process::kill($pid, SIGTERM); }
}
if ($this->process && Process::kill($this->process->pid, 0)) {
Process::kill($this->process->pid) && Process::wait(true); /**
} * @throws Exception
while ($ret = Process::wait(true)) { */
echo "PID={$ret['pid']}\n"; public function errorHandler()
sleep(1); {
} $error = func_get_args();
}
$path = ['file' => $error[2], 'line' => $error[3]];
/** if ($error[0] === 0) {
* @param $code $error[0] = 500;
* @param $message }
* @param $file $data = Json::to(500, $error[1], $path);
* @param $line
* @throws Exception $this->logger->error($data, 'error');
*/ }
public function onErrorHandler($code, $message, $file, $line)
{
if (str_contains($message, 'The file descriptor is not an inotify instance')) { /**
return; * @param InputInterface $input
} * @param OutputInterface $output
debug('Error:' . $message . ' at ' . $file . ':' . $line); * @return int
} * @throws ConfigException
* @throws Exception
*/
/** public function execute(InputInterface $input, OutputInterface $output): int
* 重启 {
* $this->initCore();
* @throws Exception
*/ $this->trigger_reload();
public function trigger_reload() Timer::tick(1000, fn() => $this->healthCheck());
{
$this->logger->warning('change reload'); Process::signal(SIGTERM, [$this, 'onSignal']);
$pid = $this->process?->pid; Process::signal(SIGKILL, [$this, 'onSignal']);
$process = new Process(function (Process $process) {
$process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "restart"]); $this->driver->start();
}); return 0;
$process->start(); }
if ($pid && Process::kill($pid, 0)) {
Process::kill($pid) && Process::wait(true);
} /**
$this->process = null; * @throws Exception
$this->process = $process; */
} public function healthCheck()
{
$pid = (int)file_get_contents(storage('.swoole.pid'));
} if ($this->int == 1) {
return;
}
if (empty($pid)) {
$this->logger->warning('service is shutdown you need reload.');
$this->trigger_reload();
} else if (!Process::kill($pid, 0)) {
$this->logger->warning('service is shutdown you need reload.');
$this->trigger_reload();
}
}
/**
* @param $data
* @throws Exception
*/
public function onSignal($data)
{
if (!$data) {
return;
}
Timer::clearAll();
$this->driver->clear();
$this->stopServer();
while ($ret = Process::wait(TRUE)) {
echo "PID={$ret['pid']}\n";
sleep(1);
}
}
/**
* @throws Exception
*/
protected function stopServer()
{
$pid = file_get_contents(storage('.swoole.pid'));
if (!empty($pid) && Process::kill($pid, 0)) {
Process::kill($pid, SIGTERM);
}
if ($this->process && Process::kill($this->process->pid, 0)) {
Process::kill($this->process->pid) && Process::wait(TRUE);
}
}
/**
* 重启
*
* @throws Exception
*/
public function trigger_reload()
{
if ($this->int == 1) {
return;
}
$this->int = 1;
$this->logger->warning('change reload');
$this->stopServer();
$this->process = new Process(function (Process $process) {
$process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "start"]);
});
$this->process->start();
$this->int = -1;
}
}
+169 -158
View File
@@ -1,158 +1,169 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Exception; use Exception;
use Swoole\Event; use Swoole\Event;
use Swoole\Timer; use Swoole\Timer;
class Inotify class Inotify
{ {
private mixed $inotify; private mixed $inotify;
private mixed $events; private mixed $events;
private array $watchFiles = []; private array $watchFiles = [];
protected bool $isReloading = FALSE; public bool $isReloading = FALSE;
protected int $cid; protected int $cid;
const IG_DIR = [APP_PATH . 'commands', APP_PATH . '.git', APP_PATH . '.gitee']; const IG_DIR = [APP_PATH . 'commands', APP_PATH . '.git', APP_PATH . '.gitee'];
/** /**
* @param array $dirs * @param array $dirs
* @param HotReload $process * @param HotReload $process
*/ */
public function __construct(protected array $dirs, public HotReload $process) public function __construct(protected array $dirs, public HotReload $process)
{ {
} set_error_handler([$this, 'error']);
set_exception_handler([$this, 'error']);
}
/**
* @throws Exception
*/ /**
public function start() * @return void
{ */
$this->inotify = inotify_init(); public function error(): void
$this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE; {
foreach ($this->dirs as $dir) {
if (!is_dir($dir)) continue; }
$this->watch($dir);
}
Event::add($this->inotify, [$this, 'check']); /**
Event::wait(); * @throws Exception
} */
public function start()
{
public function clear() $this->inotify = inotify_init();
{ $this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE;
Event::del($this->inotify); foreach ($this->dirs as $dir) {
Event::exit(); if (!is_dir($dir)) continue;
} $this->watch($dir);
}
Event::add($this->inotify, [$this, 'check']);
/** Event::wait();
* 开始监听 }
* @throws Exception
*/
public function check() public function clear()
{ {
if (!($events = inotify_read($this->inotify))) { Event::del($this->inotify);
return; Event::exit();
} }
if ($this->isReloading) {
return;
} /**
* 开始监听
$LISTEN_TYPE = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM]; * @throws Exception
foreach ($events as $ev) { */
if (!in_array($ev['mask'], $LISTEN_TYPE)) { public function check()
continue; {
} if (!($events = inotify_read($this->inotify))) {
//非重启类型 return;
if (str_ends_with($ev['name'], '.php')) { }
Timer::after(3000, fn()=>$this->reload()); if ($this->isReloading) {
$this->isReloading = TRUE; return;
} }
}
} $LISTEN_TYPE = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM];
foreach ($events as $ev) {
/** if (!in_array($ev['mask'], $LISTEN_TYPE)) {
* @throws Exception continue;
*/ }
public function reload() //非重启类型
{ if (str_ends_with($ev['name'], '.php')) {
$this->process->trigger_reload(); Timer::after(3000, fn() => $this->reload());
$this->clearWatch(); $this->isReloading = TRUE;
foreach ($this->dirs as $root) { }
$this->watch($root); }
} }
$this->process->int = -1;
$this->isReloading = FALSE; /**
} * @throws Exception
*/
public function reload()
/** {
* @throws Exception $this->process->trigger_reload();
*/ $this->clearWatch();
public function clearWatch() foreach ($this->dirs as $root) {
{ $this->watch($root);
foreach ($this->watchFiles as $wd) { }
try { $this->process->int = -1;
inotify_rm_watch($this->inotify, $wd); $this->isReloading = FALSE;
} catch (\Throwable $exception) { }
logger()->addError($exception, 'throwable');
}
} /**
$this->watchFiles = []; * @throws Exception
} */
public function clearWatch()
{
/** foreach ($this->watchFiles as $wd) {
* @param $dir try {
* @return bool @inotify_rm_watch($this->inotify, $wd);
* @throws Exception } catch (\Throwable $exception) {
*/ // logger()->addError($exception->getMessage(), 'throwable');
public function watch($dir): bool }
{ }
//目录不存在 $this->watchFiles = [];
if (!is_dir($dir)) { }
return logger()->addError("[$dir] is not a directory.");
}
//避免重复监听 /**
if (isset($this->watchFiles[$dir])) { * @param $dir
return FALSE; * @return bool
} * @throws Exception
*/
if (in_array($dir, self::IG_DIR)) { public function watch($dir): bool
return FALSE; {
} //目录不存在
if (!is_dir($dir)) {
$wd = @inotify_add_watch($this->inotify, $dir, $this->events); return logger()->addError("[$dir] is not a directory.");
$this->watchFiles[$dir] = $wd; }
//避免重复监听
$files = scandir($dir); if (isset($this->watchFiles[$dir])) {
foreach ($files as $f) { return FALSE;
if ($f == '.' || $f == '..') { }
continue;
} if (in_array($dir, self::IG_DIR)) {
$path = $dir . '/' . $f; return FALSE;
//递归目录 }
if (is_dir($path)) {
$this->watch($path); $wd = @inotify_add_watch($this->inotify, $dir, $this->events);
} else if (!str_ends_with($f, '.php')) { $this->watchFiles[$dir] = $wd;
continue;
} $files = scandir($dir);
//检测文件类型 foreach ($files as $f) {
if (strstr($f, '.') == '.php') { if ($f == '.' || $f == '..') {
$wd = @inotify_add_watch($this->inotify, $path, $this->events); continue;
$this->watchFiles[$path] = $wd; }
} $path = $dir . '/' . $f;
} //递归目录
return TRUE; if (is_dir($path)) {
} $this->watch($path);
} } else if (!str_ends_with($f, '.php')) {
continue;
}
//检测文件类型
if (strstr($f, '.') == '.php') {
$wd = @inotify_add_watch($this->inotify, $path, $this->events);
$this->watchFiles[$path] = $wd;
}
}
return TRUE;
}
}
+149 -147
View File
@@ -1,147 +1,149 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Exception; use Exception;
use Swoole\Timer;
class Scaner
{ class Scaner
{
private array $md5Map = [];
private array $md5Map = [];
/**
* @param array $dirs public bool $isReloading = FALSE;
* @param HotReload $process
*/
public function __construct(protected array $dirs, public HotReload $process) /**
{ * @param array $dirs
} * @param HotReload $process
*/
public function __construct(protected array $dirs, public HotReload $process)
/** {
* @throws Exception }
*/
public function start(): void
{ /**
$this->loadDirs(); * @throws Exception
$this->tick(); */
} public function start(): void
{
$this->loadDirs();
/** $this->tick();
* @param bool $isReload }
* @throws Exception
*/
private function loadDirs(bool $isReload = false) /**
{ * @param bool $isReload
foreach ($this->dirs as $value) { * @throws Exception
if (is_bool($path = realpath($value))) { */
continue; private function loadDirs(bool $isReload = FALSE)
} {
foreach ($this->dirs as $value) {
if (!is_dir($path)) continue; if (is_bool($path = realpath($value))) {
continue;
$this->loadByDir($path, $isReload); }
}
} if (!is_dir($path)) continue;
$this->loadByDir($path, $isReload);
/** }
* @param $path }
* @param bool $isReload
* @return void
* @throws Exception /**
*/ * @param $path
private function loadByDir($path, bool $isReload = false): void * @param bool $isReload
{ * @return void
if (!is_string($path)) { * @throws Exception
return; */
} private function loadByDir($path, bool $isReload = FALSE): void
$path = rtrim($path, '/'); {
foreach (glob(realpath($path) . '/*') as $value) { if (!is_string($path)) {
if (is_dir($value)) { return;
$this->loadByDir($value, $isReload); }
} $path = rtrim($path, '/');
if (is_file($value)) { foreach (glob(realpath($path) . '/*') as $value) {
if ($this->checkFile($value, $isReload)) { if (is_dir($value)) {
$this->timerReload(); $this->loadByDir($value, $isReload);
break; }
} if (is_file($value)) {
} if ($this->checkFile($value, $isReload)) {
} Timer::after(2000, fn() => $this->timerReload());
} $this->isReloading = TRUE;
break;
}
/** }
* @param $value }
* @param $isReload }
* @return bool
*/
private function checkFile($value, $isReload): bool /**
{ * @param $value
$md5 = md5($value); * @param $isReload
$mTime = filectime($value); * @return bool
if (!isset($this->md5Map[$md5])) { */
if ($isReload) { private function checkFile($value, $isReload): bool
return true; {
} $md5 = md5($value);
$this->md5Map[$md5] = $mTime; $mTime = filectime($value);
} else { if (!isset($this->md5Map[$md5])) {
if ($this->md5Map[$md5] != $mTime) { if ($isReload) {
if ($isReload) { return TRUE;
return true; }
} $this->md5Map[$md5] = $mTime;
$this->md5Map[$md5] = $mTime; } else {
} if ($this->md5Map[$md5] != $mTime) {
} if ($isReload) {
return false; return TRUE;
} }
$this->md5Map[$md5] = $mTime;
}
/** }
* @throws Exception return FALSE;
*/ }
public function timerReload()
{
if ($this->process->isReloading) { /**
return; * @throws Exception
} */
$this->process->isReloading = true; public function timerReload()
$this->process->trigger_reload(); {
$this->isReloading = TRUE;
$this->process->int = -1; $this->process->trigger_reload();
$this->loadDirs(); $this->process->int = -1;
$this->process->isReloading = FALSE; $this->loadDirs();
$this->process->isReloadingOut = FALSE;
$this->isReloading = FALSE;
$this->tick(); $this->process->isReloadingOut = FALSE;
}
$this->tick();
}
private bool $isStop = false;
public function clear() private bool $isStop = FALSE;
{
$this->isStop = true; public function clear()
} {
$this->isStop = TRUE;
}
/**
* @throws Exception
*/ /**
public function tick() * @throws Exception
{ */
if ($this->process->isReloading || $this->isStop) { public function tick()
return; {
} if ($this->isReloading || $this->isStop) {
return;
$this->loadDirs(true); }
sleep(2); $this->loadDirs(TRUE);
$this->tick(); sleep(2);
}
$this->tick();
} }
}
+27 -27
View File
@@ -1,27 +1,27 @@
<?php <?php
namespace Kiri; namespace Kiri;
interface IAspect interface IAspect
{ {
public function before(): void; public function before(): void;
/** /**
* @param mixed $response * @param mixed $response
*/ */
public function after(mixed $response): void; public function after(mixed $response): void;
/** /**
* @param mixed $handler * @param mixed $handler
* @param array $params * @param array $params
* @return mixed * @return mixed
*/ */
public function invoke(mixed $handler, array $params = []): mixed; public function invoke(mixed $handler, array $params = []): mixed;
} }
+13 -13
View File
@@ -1,13 +1,13 @@
<?php <?php
namespace Kiri; namespace Kiri;
interface IProxy interface IProxy
{ {
public function execute(); public function execute();
} }
-57
View File
@@ -1,57 +0,0 @@
<?php
declare(strict_types=1);
namespace Kiri\Jwt;
use Annotation\Inject;
use Exception;
use Http\Message\ServerRequest;
use Kiri\Kiri;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Server\Constrict\ResponseInterface;
/**
* Class CoreMiddleware
* @package Kiri\Kiri\Route
* 跨域中间件
*/
class JWTAuthMiddleware implements MiddlewareInterface
{
/** @var int */
public int $zOrder = 0;
#[Inject(ResponseInterface::class)]
public ResponseInterface $response;
/**
* @param ServerRequest $request
* @param RequestHandlerInterface $handler
* @return \Psr\Http\Message\ResponseInterface
* @throws Exception
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): \Psr\Http\Message\ResponseInterface
{
$authorization = $request->getHeaderLine('Authorization');
if (empty($authorization)) {
return $this->response->json(['code' => 401, 'JWT voucher cannot be empty.']);
}
if (!str_starts_with($authorization, 'Bearer ')) {
return $this->response->json(['code' => 401, 'JWT Voucher Format Error.']);
}
$authorization = str_replace('Bearer ', '', $authorization);
$jwt = Kiri::app()->getJwt();
if (!$jwt->validator($authorization)) {
return $this->response->json(['code' => 401, 'JWT Validator fail.']);
}
return $handler->handle($request);
}
}
-27
View File
@@ -1,27 +0,0 @@
<?php
namespace Kiri\Jwt;
use JetBrains\PhpStorm\Pure;
use Throwable;
/**
*
*/
class JWTAuthTokenException extends \Exception
{
/**
* @param string $message
* @param int $code
* @param Throwable|null $previous
*/
#[Pure] public function __construct($message = "", $code = 4001, Throwable $previous = null)
{
parent::__construct($message, 4001, $previous);
}
}
-201
View File
@@ -1,201 +0,0 @@
<?php
declare(strict_types=1);
namespace Kiri\Jwt;
use Annotation\Inject;
use Exception;
use Http\Constrict\RequestInterface;
use Kiri\Abstracts\Component;
use Kiri\Abstracts\Config;
use Kiri\Core\Json;
use Kiri\Exception\ConfigException;
/**
* Class Jwt
* @package Kiri\Jwt
*/
class Jwt extends Component
{
use JwtHelper;
#[Inject(RequestInterface::class)]
private RequestInterface $request;
/**
* @param RequestInterface $request
*/
public function setRequest(RequestInterface $request): void
{
$this->request = $request;
}
/**
* @throws ConfigException
* @throws Exception
* 'jwt' => [
* 'scene' => 'application',
* 'timeout' => 7200,
* 'encrypt' => '',
* 'iv' => '',
* 'key' => '',
* ]
*/
public function init()
{
$this->request = di(RequestInterface::class);
$this->public = Config::get('ssl.public', $this->public);
$this->private = Config::get('ssl.private', $this->private);
$this->timeout = Config::get('jwt.timeout', 7200);
$jwt = Config::get('jwt', []);
if ($jwt) {
$this->setScene($jwt['scene'] ?? 'application');
$this->setKey($jwt['key'] ?? get_called_class());
$length = openssl_cipher_iv_length($this->encrypt);
if ($length > 0) {
$defaultIv = openssl_random_pseudo_bytes($length);
$this->setIv($jwt['iv'] ?? $defaultIv);
}
}
}
/**
* @param int $unionId
*
* @return string
* @throws Exception
*/
public function create(int $unionId): string
{
$this->user = $unionId;
$this->config['time'] = time();
$this->data = $this->request->getHeaders();
if (!isset($this->data['source'])) {
$this->data['source'] = 'browser';
}
return $this->createEncrypt($unionId);
}
/**
* @return string
*/
private function jwtHeader(): string
{
$string = openssl_encrypt(
json_encode(['type' => 'openssl', 'encrypt' => $this->encrypt]),
$this->encrypt,
$this->key,
0,
$this->iv
);
return str_replace('=', '', $string);
}
/**
* @param $unionId
* @return string
* @throws Exception
*/
private function jwtBody($unionId): string
{
$json = json_encode(['unionId' => $unionId, 'createTime' => time(), 'expire_at' => time() + $this->timeout]);
openssl_private_encrypt($json, $encode, $this->private);
return base64_encode($encode);
}
/**
* @param $unionId
* @return string
* @throws Exception
*/
private function createEncrypt($unionId): string
{
$params[] = $this->jwtHeader();
$params[] = $this->jwtBody($unionId);
$params[] = hash('sha256', $params[0] . $params[1]);
return implode('.', $params);
}
/**
* @param $token
* @return string|int
* @throws JWTAuthTokenException
*/
public function getUnionId($token): string|int
{
$unpack = $this->unpack($token);
if (!$this->_validator($unpack)) {
throw new JWTAuthTokenException('JWT certificate has expired.');
}
return $unpack['unionId'];
}
/**
* @param $token
* @return bool
* @throws JWTAuthTokenException
*/
public function validator($token): bool
{
return $this->_validator($this->unpack($token));
}
/**
* @param $unpack
* @return bool
*/
private function _validator($unpack): bool
{
if ($unpack['expire_at'] < time()) {
return false;
}
return true;
}
/**
* @param $token
* @return string
* @throws JWTAuthTokenException
* @throws Exception
*/
public function refresh($token): string
{
return $this->create($this->unpack($token)['unionId']);
}
/**
* @param string $token
* @return mixed
* @throws JWTAuthTokenException
*/
private function unpack(string $token): array
{
if (count($explode = explode('.', $token)) != 3) {
throw new JWTAuthTokenException('JWT Voucher Format Error.');
}
if (hash('sha256', $explode[0] . $explode[1]) != $explode[2]) {
throw new JWTAuthTokenException('JWT Sign Validator Fail.');
}
if (!openssl_public_decrypt(base64_decode($explode[1]), $decode, $this->public)) {
throw new JWTAuthTokenException('JWT Voucher Unpack Error.');
}
return Json::decode($decode, true);
}
}
-134
View File
@@ -1,134 +0,0 @@
<?php
namespace Kiri\Jwt;
trait JwtHelper
{
/** @var int $user */
private int $user;
private array $data;
private array $source = ['browser', 'android', 'iphone', 'pc', 'mingame'];
private array $config = ['token' => ''];
private ?int $timeout = 7200;
private string $key = 'www.xshucai.com';
private string $secret = '';
private string $scene = 'default';
private string $encrypt = 'aes-128-ecb';
private string $iv = '';
private ?string $public = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6BuML3gtLGde7QKNuNST
UCB9gdHC7XIpOc7Wx2I64Esj3UxWHTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6Xad
jqfjEWpTy4WwGYsOfH0tFl3wAmse0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5t
WhTMEnpTFDYoDR0KXlLXltQMudBBUHFaVwP0wKJ/cGX7R1Mrv35K4MXwQFOuGZkP
hsp2rO9x5LjtSKIXbexy7WhUu6QMjD/XzgsXr9UF+ExYmBGXRVWgNFLMkiaCZ2Uz
WlQhpQrA5/wKd76dCzjvqw9M32OiZl2lCKT73cV8GUvt7BNsM1SiPhqfY7nhO6y3
cwIDAQAB
-----END PUBLIC KEY-----';
private ?string $private = '-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA6BuML3gtLGde7QKNuNSTUCB9gdHC7XIpOc7Wx2I64Esj3UxW
HTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6XadjqfjEWpTy4WwGYsOfH0tFl3wAmse
0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5tWhTMEnpTFDYoDR0KXlLXltQMudBB
UHFaVwP0wKJ/cGX7R1Mrv35K4MXwQFOuGZkPhsp2rO9x5LjtSKIXbexy7WhUu6QM
jD/XzgsXr9UF+ExYmBGXRVWgNFLMkiaCZ2UzWlQhpQrA5/wKd76dCzjvqw9M32Oi
Zl2lCKT73cV8GUvt7BNsM1SiPhqfY7nhO6y3cwIDAQABAoIBADPihJHP8XktmmCs
43Vfv5Z3zNaKR2LA1Eph3E0xviuJYHkFqXJarbESqqW2qRQeoQeB/lXWnxYzAo4M
tRcpNss+6FlqRVUHi3gKR7C4Yq3PTemcfIVUpAy7gYa8LJDTYZRcJMZXNDtiMbBh
9kFZU4SBhaTTx2KLQKS9yyWOqzbBvyLXN+1+Wy477M9+MXXTKw79dO+pML6cR0yl
pNfVR5FX5L/GB5vOtQB/Aqg/CKT8NC5MzWPnKY+TPCCHZyoZuB9dLDuWOlqsN4QX
Y4B8fFca5yRwzHra5aGoqdaT/zGctt+I6V/f/KNQCo36f9LPxeXg1+FHvvtTj5WZ
N8CGPzECgYEA9R7lRMXzrHE4rK0DhxQXIFbIKKtxrimqZQdbwOUeYYD2R6CDSItK
z88RSYElmd6wiS7fYIaheXNqJ8Yu6SQFBF/yshBwjQVl9NJG94LJlgx1XnVZEju6
OZjMUOhHXBymtXnLo16pDRl8odc4MFLRH25/vLtwChUr+Qoyt54GzFUCgYEA8mjL
jdh94JAmcdnDXsKgjNOGyNWGDVvWoFmy8lEQsMXY1JJnEd3YfDM2prmv3vaoiXzi
YkSETl6ZUtJqh78MnHCBY1vI6EAcKQAF/kvP2TataRCXNcGNQwn2mtq+B+heTta6
Di8jjAdmdUAYHbmOQryBudiRYG7JEF038elzvKcCgYEAq81ByFguGBkrLev94vkz
1Fi+5bJ0dSuC4Fit+J8eEhz/gOiB26C1iL2LUkeQgS5R8XTG37K9DpDUQJhpXMMA
OTa+tgtLt6um8FdJokUq4V5ODSyWh28RcTklSzfifC8gsWVyU0kPl7zbW9uq6EPD
ixI5uaBuQMLiFSUOsx+xiBkCgYEAtqXHWeVZUy7KCNavomK7XeCzmfdovgAIw2FS
t8nk7YzlR6XYC1pAl7Ru5Ujb/v+TFaUHXkuJ9RLKK+Fna0jEU8thcl/iDTzg+vON
kIHG5j+Qga2CgXqI2Y5URXGz5XlsNbMNFUrnWcbpqEbW5O6/BgHLLSDEyQgwbygN
0zS3g9kCgYEAhssb7kOljdIul4lY5MXc67Zf1dp6S2bucLOxsG6cRW07b3pBz7QF
5aPE7ZwnkzTnA4HuGGauKj+qKGAR7ve55XClAq/XipiVFrjwV/t3LC6j5DoqTJYR
mlAZUEjsoaT9vjvjGTxl3uCm0TX5KTgtSJIt2kA1tYVjQef+/iZTHxY=
-----END RSA PRIVATE KEY-----';
/**
* @param string $publicKey
*/
public function setPublic(string $publicKey)
{
$this->public = $publicKey;
}
/**
* @param int $timeout
*/
public function setTimeout(int $timeout)
{
$this->timeout = $timeout;
}
public function setScene(string $scene)
{
$this->scene = $scene;
}
/**
* @param string $timeout
*/
public function setKey(string $timeout)
{
$this->key = $timeout;
}
/**
* @param string $privateKey
*/
public function setPrivate(string $privateKey)
{
$this->private = $privateKey;
}
/**
* @param string $privateKey
*/
public function setIv(string $privateKey)
{
$this->iv = $privateKey;
}
/**
* @param string $privateKey
*/
public function setEncrypt(string $privateKey)
{
$this->encrypt = $privateKey;
}
}
+636 -624
View File
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -1,24 +1,24 @@
<?php <?php
namespace Kiri\Pool; namespace Kiri\Pool;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
trait Alias trait Alias
{ {
/** /**
* @param $cds * @param $cds
* @param false $isMaster * @param false $isMaster
* @return string * @return string
*/ */
#[Pure] public function name($cds, bool $isMaster = false): string #[Pure] public function name($cds, bool $isMaster = false): string
{ {
if ($isMaster === true) { if ($isMaster === true) {
return $cds . '_master'; return $cds . '_master';
} else { } else {
return $cds . '_slave'; return $cds . '_slave';
} }
} }
} }
+217 -219
View File
@@ -1,219 +1,217 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Pool; namespace Kiri\Pool;
use Closure; use Closure;
use Database\Mysql\PDO; use Database\Mysql\PDO;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Context; use Kiri\Context;
use Kiri\Kiri; use Kiri\Kiri;
use Swoole\Error; use Swoole\Error;
use Throwable; use Throwable;
/** /**
* Class Connection * Class Connection
* @package Kiri\Pool * @package Kiri\Pool
*/ */
class Connection extends Component class Connection extends Component
{ {
use Alias; use Alias;
/** /**
* @param $cds * @param $cds
* @return bool * @return bool
* *
* db is in transaction * db is in transaction
* @throws Exception * @throws Exception
*/ */
public function inTransaction($cds): bool public function inTransaction($cds): bool
{ {
$name = $this->name('Mysql:' . $cds, true); $name = $this->name('Mysql:' . $cds, true);
$connection = Context::getContext($name); $connection = Context::getContext($name);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
return $connection->inTransaction(); return $connection->inTransaction();
} }
return false; return false;
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @throws Exception * @throws Exception
*/ */
public function beginTransaction($coroutineName) public function beginTransaction($coroutineName)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, true); $coroutineName = $this->name('Mysql:' . $coroutineName, true);
$connection = Context::getContext($coroutineName); $connection = Context::getContext($coroutineName);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
$connection->beginTransaction(); $connection->beginTransaction();
} }
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @throws Exception * @throws Exception
*/ */
public function commit($coroutineName) public function commit($coroutineName)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, true); $coroutineName = $this->name('Mysql:' . $coroutineName, true);
$connection = Context::getContext($coroutineName); $connection = Context::getContext($coroutineName);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
$connection->commit(); $connection->commit();
} }
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @throws Exception * @throws Exception
*/ */
public function rollback($coroutineName) public function rollback($coroutineName)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, true); $coroutineName = $this->name('Mysql:' . $coroutineName, true);
$connection = Context::getContext($coroutineName); $connection = Context::getContext($coroutineName);
if ($connection instanceof PDO) { if ($connection instanceof PDO) {
$connection->rollBack(); $connection->rollBack();
} }
} }
/** /**
* @param mixed $config * @param mixed $config
* @param bool $isMaster * @param bool $isMaster
* @return PDO|null * @return PDO|null
* @throws Exception * @throws Exception
*/ */
public function get(mixed $config, bool $isMaster = false): ?PDO public function get(mixed $config, bool $isMaster = false): ?PDO
{ {
$coroutineName = $this->name('Mysql:' . $config['cds'], $isMaster); $coroutineName = $this->name('Mysql:' . $config['cds'], $isMaster);
if (($pdo = Context::getContext($coroutineName)) instanceof PDO) { if (($pdo = Context::getContext($coroutineName)) instanceof PDO) {
return $pdo; return $pdo;
} }
$minx = Config::get('databases.pool.min', 1); $minx = Config::get('databases.pool.min', 1);
/** @var PDO $connections */ /** @var PDO $connections */
$connections = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $minx); $connections = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $minx);
if (Context::hasContext('begin_' . $coroutineName)) { if (Context::hasContext('begin_' . $coroutineName)) {
$connections->beginTransaction(); $connections->beginTransaction();
} }
return Context::setContext($coroutineName, $connections); return Context::setContext($coroutineName, $connections);
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @param $config * @param $config
* @return Closure * @return Closure
*/ */
public function create($coroutineName, $config): Closure public function create($coroutineName, $config): Closure
{ {
return static function () use ($coroutineName, $config) { return static function () use ($coroutineName, $config) {
return Kiri::getDi()->create(PDO::class, [ return Kiri::getDi()->create(PDO::class, [$config]);
$config['database'], $config['cds'], $config['username'], $config['password'], $config['charset'] ?? 'utf8mb4' };
]); }
};
}
/**
* @param $name
/** * @param $isMaster
* @param $name * @param $max
* @param $isMaster * @throws Exception
* @param $max */
* @throws Exception public function initConnections($name, $isMaster, $max)
*/ {
public function initConnections($name, $isMaster, $max) $this->getPool()->initConnections($name, $isMaster, $max);
{ }
$this->getPool()->initConnections($name, $isMaster, $max);
}
/**
* @param $coroutineName
/** * @param $isMaster
* @param $coroutineName * @throws Exception
* @param $isMaster */
* @throws Exception public function release($coroutineName, $isMaster)
*/ {
public function release($coroutineName, $isMaster) $coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster);
{ /** @var PDO $client */
$coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster); if (!($client = Context::getContext($coroutineName)) instanceof PDO) {
/** @var PDO $client */ return;
if (!($client = Context::getContext($coroutineName)) instanceof PDO) { }
return; if ($client->inTransaction()) {
} return;
if ($client->inTransaction()) { }
return; $this->getPool()->push($coroutineName, $client);
} Context::remove($coroutineName);
$this->getPool()->push($coroutineName, $client); }
Context::remove($coroutineName);
}
/**
* @param $coroutineName
/** * @return bool
* @param $coroutineName */
* @return bool private function hasClient($coroutineName): bool
*/ {
private function hasClient($coroutineName): bool return Context::hasContext($coroutineName);
{ }
return Context::hasContext($coroutineName);
}
/**
* batch release
/** * @throws Exception
* batch release */
* @throws Exception public function connection_clear($name, $isMaster)
*/ {
public function connection_clear($name, $isMaster) $this->getPool()->clean($this->name($name, $isMaster));
{ }
$this->getPool()->clean($this->name($name, $isMaster));
}
/**
* @param string $name
/** * @param mixed $client
* @param string $name * @return bool
* @param mixed $client * @throws Exception
* @return bool */
* @throws Exception public function checkCanUse(string $name, mixed $client): bool
*/ {
public function checkCanUse(string $name, mixed $client): bool try {
{ if (empty($client) || !($client instanceof PDO)) {
try { $result = false;
if (empty($client) || !($client instanceof PDO)) { } else {
$result = false; $result = true;
} else { }
$result = true; } catch (Error | Throwable $exception) {
} $result = $this->addError($exception, 'mysql');
} catch (Error | Throwable $exception) { } finally {
$result = $this->addError($exception, 'mysql'); return $result;
} finally { }
return $result; }
}
}
/**
* @param $coroutineName
/** * @param bool $isMaster
* @param $coroutineName * @throws Exception
* @param bool $isMaster */
* @throws Exception public function disconnect($coroutineName, bool $isMaster = false)
*/ {
public function disconnect($coroutineName, bool $isMaster = false) Context::remove($coroutineName);
{ $coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster);
Context::remove($coroutineName); $this->getPool()->clean($coroutineName);
$coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster); }
$this->getPool()->clean($coroutineName);
}
/**
* @return Pool
/** * @throws Exception
* @return Pool */
* @throws Exception public function getPool(): Pool
*/ {
public function getPool(): Pool return Kiri::getDi()->get(Pool::class);
{ }
return Kiri::getDi()->get(Pool::class);
} }
}
+28 -28
View File
@@ -1,28 +1,28 @@
<?php <?php
namespace Kiri\Pool\Helper; namespace Kiri\Pool\Helper;
interface QueueInterface interface QueueInterface
{ {
public function isEmpty(): bool; public function isEmpty(): bool;
public function push(mixed $data, float $timeout = -1): bool; public function push(mixed $data, float $timeout = -1): bool;
public function pop(float $timeout = -1): mixed; public function pop(float $timeout = -1): mixed;
public function stats(): array; public function stats(): array;
public function close(): bool; public function close(): bool;
public function length(): int; public function length(): int;
public function isFull(): bool; public function isFull(): bool;
} }
+101 -101
View File
@@ -1,101 +1,101 @@
<?php <?php
namespace Kiri\Pool\Helper; namespace Kiri\Pool\Helper;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
/** /**
* *
*/ */
class SplQueue implements QueueInterface class SplQueue implements QueueInterface
{ {
private \SplQueue $channel; private \SplQueue $channel;
public int $errCode = 0; public int $errCode = 0;
/** /**
* @param int $max * @param int $max
*/ */
#[Pure] public function __construct(public int $max) #[Pure] public function __construct(public int $max)
{ {
$this->channel = new \SplQueue(); $this->channel = new \SplQueue();
} }
/** /**
* @return bool * @return bool
*/ */
public function isEmpty(): bool public function isEmpty(): bool
{ {
// TODO: Implement isEmpty() method. // TODO: Implement isEmpty() method.
return $this->channel->count() < 1; return $this->channel->count() < 1;
} }
/** /**
* @param mixed $data * @param mixed $data
* @param float $timeout * @param float $timeout
* @return bool * @return bool
*/ */
public function push(mixed $data, float $timeout = -1): bool public function push(mixed $data, float $timeout = -1): bool
{ {
// TODO: Implement push() method. // TODO: Implement push() method.
$this->channel->enqueue($data); $this->channel->enqueue($data);
return true; return true;
} }
/** /**
* @param float $timeout * @param float $timeout
* @return mixed * @return mixed
*/ */
public function pop(float $timeout = -1): mixed public function pop(float $timeout = -1): mixed
{ {
// TODO: Implement pop() method. // TODO: Implement pop() method.
return $this->channel->dequeue(); return $this->channel->dequeue();
} }
/** /**
* @return array * @return array
*/ */
public function stats(): array public function stats(): array
{ {
// TODO: Implement stats() method. // TODO: Implement stats() method.
return []; return [];
} }
/** /**
* @return bool * @return bool
*/ */
public function close(): bool public function close(): bool
{ {
// TODO: Implement close() method. // TODO: Implement close() method.
return false; return false;
} }
/** /**
* @return int * @return int
*/ */
public function length(): int public function length(): int
{ {
// TODO: Implement length() method. // TODO: Implement length() method.
return $this->channel->count(); return $this->channel->count();
} }
/** /**
* @return bool * @return bool
*/ */
public function isFull(): bool public function isFull(): bool
{ {
// TODO: Implement isFull() method. // TODO: Implement isFull() method.
return $this->channel->count() >= $this->max; return $this->channel->count() >= $this->max;
} }
} }
+249 -249
View File
@@ -1,249 +1,249 @@
<?php <?php
namespace Kiri\Pool; namespace Kiri\Pool;
use Exception; use Exception;
use Kiri\Context; use Kiri\Context;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Pool\Helper\SplQueue; use Kiri\Pool\Helper\SplQueue;
use Swoole\Coroutine; use Swoole\Coroutine;
use Swoole\Coroutine\Channel; use Swoole\Coroutine\Channel;
/** /**
* Class Pool * Class Pool
* @package Kiri\Pool * @package Kiri\Pool
*/ */
class Pool extends Component class Pool extends Component
{ {
/** @var Channel[] */ /** @var Channel[] */
private static array $_connections = []; private static array $_connections = [];
public int $max = 60; public int $max = 60;
use Alias; use Alias;
/** /**
* @param $channel * @param $channel
* @param $retain_number * @param $retain_number
* @throws Exception * @throws Exception
*/ */
public function flush($channel, $retain_number) public function flush($channel, $retain_number)
{ {
$this->pop($channel, $retain_number); $this->pop($channel, $retain_number);
} }
/** /**
* @param Channel $channel * @param Channel $channel
* @param $retain_number * @param $retain_number
* @throws Exception * @throws Exception
*/ */
protected function pop(Channel $channel, $retain_number): void protected function pop(Channel $channel, $retain_number): void
{ {
while ($channel->length() > $retain_number) { while ($channel->length() > $retain_number) {
if (Context::inCoroutine()) { if (Context::inCoroutine()) {
$connection = $channel->pop(); $connection = $channel->pop();
if ($connection instanceof StopHeartbeatCheck) { if ($connection instanceof StopHeartbeatCheck) {
$connection->stopHeartbeatCheck(); $connection->stopHeartbeatCheck();
} }
} }
} }
} }
/** /**
* @param $name * @param $name
* @param false $isMaster * @param false $isMaster
* @param int $max * @param int $max
* @throws ConfigException * @throws ConfigException
*/ */
public function initConnections($name, bool $isMaster = false, int $max = 60) public function initConnections($name, bool $isMaster = false, int $max = 60)
{ {
$name = $this->name($name, $isMaster); $name = $this->name($name, $isMaster);
if (isset(static::$_connections[$name])) { if (isset(static::$_connections[$name])) {
$value = static::$_connections[$name]; $value = static::$_connections[$name];
if ($value instanceof Channel || $value instanceof SplQueue) { if ($value instanceof Channel || $value instanceof SplQueue) {
return; return;
} }
} }
$this->newChannel($name, $max); $this->newChannel($name, $max);
$this->max = $max; $this->max = $max;
} }
/** /**
* @param $name * @param $name
* @return Channel|SplQueue * @return Channel|SplQueue
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
private function getChannel($name): Channel|SplQueue private function getChannel($name): Channel|SplQueue
{ {
if (!isset(static::$_connections[$name])) { if (!isset(static::$_connections[$name])) {
$this->newChannel($name); $this->newChannel($name);
} }
if (static::$_connections[$name]->errCode == SWOOLE_CHANNEL_CLOSED) { if (static::$_connections[$name]->errCode == SWOOLE_CHANNEL_CLOSED) {
throw new Exception('Channel is Close.'); throw new Exception('Channel is Close.');
} }
return static::$_connections[$name]; return static::$_connections[$name];
} }
/** /**
* @throws ConfigException * @throws ConfigException
*/ */
private function newChannel($name, $max = null) private function newChannel($name, $max = null)
{ {
if ($max == null) { if ($max == null) {
$max = Config::get('databases.pool.max', 10); $max = Config::get('databases.pool.max', 10);
} }
if (Coroutine::getCid() === -1) { if (Coroutine::getCid() === -1) {
static::$_connections[$name] = new SplQueue($max); static::$_connections[$name] = new SplQueue($max);
} else { } else {
static::$_connections[$name] = new Channel($max); static::$_connections[$name] = new Channel($max);
} }
} }
/** /**
* @param $name * @param $name
* @param $callback * @param $callback
* @param $minx * @param $minx
* @return array * @return array
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function get($name, $callback, $minx): mixed public function get($name, $callback, $minx): mixed
{ {
$channel = $this->getChannel($name); $channel = $this->getChannel($name);
if (!$channel->isEmpty()) { if (!$channel->isEmpty()) {
return $this->maxIdleQuantity($channel, $minx); return $this->maxIdleQuantity($channel, $minx);
} }
return $callback(); return $callback();
} }
/** /**
* @param $channel * @param $channel
* @param $minx * @param $minx
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
protected function maxIdleQuantity($channel, $minx): mixed protected function maxIdleQuantity($channel, $minx): mixed
{ {
$connection = $channel->pop(); $connection = $channel->pop();
if ($channel->length() > $minx) { if ($channel->length() > $minx) {
$this->pop($channel, $minx); $this->pop($channel, $minx);
} }
return $connection; return $connection;
} }
/** /**
* @param $name * @param $name
* @return bool * @return bool
* @throws ConfigException * @throws ConfigException
*/ */
public function isNull($name): bool public function isNull($name): bool
{ {
return $this->getChannel($name)->isEmpty(); return $this->getChannel($name)->isEmpty();
} }
/** /**
* @param string $name * @param string $name
* @param mixed $client * @param mixed $client
* @return bool * @return bool
* 检查连接可靠性 * 检查连接可靠性
*/ */
public function checkCanUse(string $name, mixed $client): bool public function checkCanUse(string $name, mixed $client): bool
{ {
return true; return true;
} }
/** /**
* @param string $name * @param string $name
* @return bool * @return bool
*/ */
public function hasItem(string $name): bool public function hasItem(string $name): bool
{ {
if (isset(static::$_connections[$name])) { if (isset(static::$_connections[$name])) {
return !static::$_connections[$name]->isEmpty(); return !static::$_connections[$name]->isEmpty();
} }
return false; return false;
} }
/** /**
* @param string $name * @param string $name
* @return mixed * @return mixed
*/ */
public function size(string $name): mixed public function size(string $name): mixed
{ {
if (!isset(static::$_connections[$name])) { if (!isset(static::$_connections[$name])) {
return 0; return 0;
} }
return static::$_connections[$name]->length(); return static::$_connections[$name]->length();
} }
/** /**
* @param string $name * @param string $name
* @param mixed $client * @param mixed $client
* @throws ConfigException * @throws ConfigException
*/ */
public function push(string $name, mixed $client) public function push(string $name, mixed $client)
{ {
$channel = $this->getChannel($name); $channel = $this->getChannel($name);
if (!$channel->isFull()) { if (!$channel->isFull()) {
$channel->push($client); $channel->push($client);
} }
unset($client); unset($client);
} }
/** /**
* @param string $name * @param string $name
* @throws Exception * @throws Exception
*/ */
public function clean(string $name) public function clean(string $name)
{ {
if (!isset(static::$_connections[$name])) { if (!isset(static::$_connections[$name])) {
return; return;
} }
while (static::$_connections[$name]->length() > 0) { while (static::$_connections[$name]->length() > 0) {
if (static::$_connections[$name] instanceof Channel) if (static::$_connections[$name] instanceof Channel)
{ {
if (!Context::inCoroutine()) if (!Context::inCoroutine())
{ {
break; break;
} }
} }
$client = static::$_connections[$name]->pop(); $client = static::$_connections[$name]->pop();
if ($client instanceof StopHeartbeatCheck) { if ($client instanceof StopHeartbeatCheck) {
$client->stopHeartbeatCheck(); $client->stopHeartbeatCheck();
} }
} }
static::$_connections[$name] = null; static::$_connections[$name] = null;
unset(static::$_connections[$name]); unset(static::$_connections[$name]);
} }
/** /**
* @return Channel[] * @return Channel[]
*/ */
protected function getChannels(): array protected function getChannels(): array
{ {
return static::$_connections; return static::$_connections;
} }
} }
+122 -126
View File
@@ -1,126 +1,122 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri\Pool; namespace Kiri\Pool;
use Closure; use Closure;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Context; use Kiri\Context;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri\Kiri;
/** /**
* Class RedisClient * Class RedisClient
* @package Kiri\Kiri\Pool * @package Kiri\Kiri\Pool
*/ */
class Redis extends Component class Redis extends Component
{ {
use Alias; use Alias;
/** /**
* @param mixed $config * @param mixed $config
* @param bool $isMaster * @param bool $isMaster
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function get(mixed $config, bool $isMaster = false): mixed public function get(mixed $config, bool $isMaster = false): mixed
{ {
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster); $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
if (Context::hasContext($coroutineName)) { if (Context::hasContext($coroutineName)) {
return Context::getContext($coroutineName); return Context::getContext($coroutineName);
} }
$pool = $config['pool'] ?? ['min' => 1, 'max' => 100]; $pool = $config['pool'] ?? ['min' => 1, 'max' => 100];
$clients = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $pool['min'] ?? 1); $clients = $this->getPool()->get($coroutineName, $this->create($coroutineName, $config), $pool['min'] ?? 1);
return Context::setContext($coroutineName, $clients); return Context::setContext($coroutineName, $clients);
} }
/** /**
* @param string $name * @param string $name
* @param mixed $config * @param mixed $config
* @return Closure * @return Closure
*/ */
public function create(string $name, mixed $config): Closure public function create(string $name, mixed $config): Closure
{ {
return static function () use ($name, $config) { return static function () use ($name, $config) {
return Kiri::getDi()->create(\Kiri\Cache\Base\Redis::class, [ return Kiri::getDi()->create(\Kiri\Cache\Base\Redis::class, [$config]);
$config['host'], (int)$config['port'], $config['databases'] ?? 0, };
$config['auth'], $config['prefix'] ?? '', $config['timeout'] ?? 30, }
$config['read_timeout'] ?? 30
]);
}; /**
} * @param array $config
* @param bool $isMaster
* @throws ConfigException
/** * @throws Exception
* @param array $config */
* @param bool $isMaster public function release(array $config, bool $isMaster = false)
* @throws ConfigException {
* @throws Exception $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
*/ if (!Context::hasContext($coroutineName)) {
public function release(array $config, bool $isMaster = false) return;
{ }
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
if (!Context::hasContext($coroutineName)) { $this->getPool()->push($coroutineName, Context::getContext($coroutineName));
return; Context::remove($coroutineName);
} }
$this->getPool()->push($coroutineName, Context::getContext($coroutineName)); /**
Context::remove($coroutineName); * @param array $config
} * @param bool $isMaster
* @throws Exception
/** */
* @param array $config public function destroy(array $config, bool $isMaster = false)
* @param bool $isMaster {
* @throws Exception $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
*/ $this->getPool()->clean($coroutineName);
public function destroy(array $config, bool $isMaster = false) Context::remove($coroutineName);
{ }
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
$this->getPool()->clean($coroutineName);
Context::remove($coroutineName); /**
} * @param array $config
* @param bool $isMaster
* @throws Exception
/** */
* @param array $config public function connection_clear(array $config, bool $isMaster = false)
* @param bool $isMaster {
* @throws Exception $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
*/ $this->getPool()->clean($coroutineName);
public function connection_clear(array $config, bool $isMaster = false) }
{
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
$this->getPool()->clean($coroutineName); /**
} * @return Pool
* @throws Exception
*/
/** public function getPool(): Pool
* @return Pool {
* @throws Exception return Kiri::getDi()->get(Pool::class);
*/ }
public function getPool(): Pool
{
return Kiri::getDi()->get(Pool::class); /**
} * @param $name
* @param $isMaster
* @param $max
/** * @throws Exception
* @param $name */
* @param $isMaster public function initConnections($name, $isMaster, $max)
* @param $max {
* @throws Exception $this->getPool()->initConnections($name, $isMaster, $max);
*/ }
public function initConnections($name, $isMaster, $max)
{
$this->getPool()->initConnections($name, $isMaster, $max); }
}
}
+11 -11
View File
@@ -1,11 +1,11 @@
<?php <?php
namespace Kiri\Pool; namespace Kiri\Pool;
interface StopHeartbeatCheck interface StopHeartbeatCheck
{ {
public function stopHeartbeatCheck(); public function stopHeartbeatCheck();
} }
+27 -27
View File
@@ -1,27 +1,27 @@
<?php <?php
namespace Kiri; namespace Kiri;
class Proxy class Proxy
{ {
/** /**
* Proxy constructor. * Proxy constructor.
* @param IProxy $IProxy * @param IProxy $IProxy
*/ */
public function __construct(public IProxy $IProxy) public function __construct(public IProxy $IProxy)
{ {
} }
/** /**
* @return mixed * @return mixed
*/ */
public function execute(): mixed public function execute(): mixed
{ {
return $this->IProxy->execute(); return $this->IProxy->execute();
} }
} }
+101 -101
View File
@@ -1,101 +1,101 @@
<?php <?php
namespace Kiri; namespace Kiri;
use Exception; use Exception;
use Kiri\Abstracts\Input; use Kiri\Abstracts\Config;
use Symfony\Component\Console\Command\Command; use Kiri\Abstracts\Input;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class Runtime /**
* @package Kiri * Class Runtime
*/ * @package Kiri
class Runtime extends Command */
{ class Runtime extends Command
{
public string $command = 'runtime:builder';
public string $command = 'runtime:builder';
public string $description = 'create app file cache';
public string $description = 'create app file cache';
const CACHE_NAME = '.runtime.cache';
const CONFIG_NAME = '.config.cache'; const CACHE_NAME = '.runtime.cache';
const CONFIG_NAME = '.config.cache';
protected function configure()
{ protected function configure()
$this->setName('runtime:builder'); {
} $this->setName('runtime:builder');
}
/**
* @param InputInterface $input /**
* @param OutputInterface $output * @param InputInterface $input
* @return int * @param OutputInterface $output
* @throws Exception * @return int
*/ * @throws Exception
public function execute(InputInterface $input, OutputInterface $output): int */
{ public function execute(InputInterface $input, OutputInterface $output): int
// TODO: Implement onHandler() method. {
$annotation = Kiri::app()->getAnnotation(); // TODO: Implement onHandler() method.
$annotation = Kiri::app()->getAnnotation();
$runtime = storage(static::CACHE_NAME);
$config = storage(static::CONFIG_NAME); $runtime = storage(static::CACHE_NAME);
$config = storage(static::CONFIG_NAME);
Kiri::writeFile($config, $this->configEach());
Kiri::writeFile($runtime, serialize($annotation->getLoader())); Kiri::writeFile($config, $this->configEach());
Kiri::writeFile($runtime, serialize($annotation->getLoader()));
return 1;
} return 1;
}
/**
* @return string /**
* @throws Exception * @return string
*/ * @throws Exception
public function configEach(): string */
{ public function configEach(): string
$array = []; {
$configs = Kiri::app()->getConfig(); $array = [];
foreach ($configs->getData() as $key => $datum) { foreach (Config::getData() as $key => $datum) {
if ($datum instanceof \Closure) { if ($datum instanceof \Closure) {
continue; continue;
} }
if (is_array($datum)) { if (is_array($datum)) {
$array[$key] = $this->arrayEach($datum); $array[$key] = $this->arrayEach($datum);
} else { } else {
$array[$key] = $datum; $array[$key] = $datum;
} }
} }
return serialize($array); return serialize($array);
} }
/** /**
* @param array $value * @param array $value
* @return array * @return array
*/ */
private function arrayEach(array $value): array private function arrayEach(array $value): array
{ {
$array = []; $array = [];
foreach ($value as $key => $item) { foreach ($value as $key => $item) {
if ($item instanceof \Closure) { if ($item instanceof \Closure) {
continue; continue;
} }
if (is_array($item)) { if (is_array($item)) {
$array[$key] = $this->arrayEach($item); $array[$key] = $this->arrayEach($item);
} else { } else {
$array[$key] = $item; $array[$key] = $item;
} }
} }
return $array; return $array;
} }
} }
+10 -10
View File
@@ -1,10 +1,10 @@
<?php <?php
namespace Kiri; namespace Kiri;
interface ToArray interface ToArray
{ {
public function toArray(); public function toArray();
} }
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace Kiri\Gateway;
class Collector
{
public function get()
{
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace Kiri\Gateway;
use Swoole\Http\Request;
use Swoole\Http\Response;
class GatewayServer
{
/**
* @param Request $request
* @param Response $response
*/
public function onRequest(Request $request, Response $response)
{
}
}

Some files were not shown because too many files have changed in this diff Show More