Compare commits

...

111 Commits

Author SHA1 Message Date
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
133 changed files with 12713 additions and 13085 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 -18
View File
@@ -1,18 +1,18 @@
<?php <?php
namespace PHPSTORM_META { namespace PHPSTORM_META {
// Reflect // Reflect
use Kiri\Di\Container; use Kiri\Di\Container;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
override(ContainerInterface::get(0), map('@')); override(ContainerInterface::get(0), map('@'));
override(Container::get(0), map('@')); override(Container::get(0), map('@'));
override(Container::make(0), map('@')); override(Container::make(0), map('@'));
override(Container::create(0), map('@')); override(Container::create(0), map('@'));
// override(\Hyperf\Utils\Context::get(0), map('@')); // override(\Hyperf\Utils\Context::get(0), map('@'));
// override(\make(0), map('@')); // override(\make(0), map('@'));
override(\di(0), map('@')); override(\di(0), map('@'));
override(\duplicate(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 -48
View File
@@ -1,48 +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.10", "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": "v6.3.*", "ext-inotify": "*"
"psr/container": "^2.0", },
"psr/http-server-middleware": "1.0.1", "autoload": {
"game-worker/kiri-event": "^v1.0", "psr-4": {
"ext-inotify": "*" "Kiri\\": "kiri-engine/",
}, "Kiri\\Gateway\\": "kiri-gateway/",
"autoload": { "Kiri\\Websocket\\": "kiri-websocket-server/",
"psr-4": { "Gii\\": "kiri-gii/",
"Kiri\\": "kiri-engine/", "Kiri\\Annotation\\": "kiri-annotation/",
"Kiri\\Gateway\\": "kiri-gateway/", "Kiri\\Task\\": "kiri-task/"
"Gii\\": "kiri-gii/", },
"Note\\": "kiri-note/" "files": [
}, "error.php",
"files": [ "function.php"
"error.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 -1166
View File
File diff suppressed because it is too large Load Diff
@@ -1,86 +1,86 @@
<?php <?php
namespace Note; namespace Kiri\Annotation;
use DirectoryIterator; use DirectoryIterator;
use Exception; use Exception;
use ReflectionException; use ReflectionException;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
/** /**
* Class Note * Class Annotation
* @package Note * @package Annotation
*/ */
class Note 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 Note; 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 Note * @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 Note; namespace Kiri\Annotation;
/** /**
* Class Attribute * Class Attribute
* @package Note * @package Annotation
*/ */
abstract class Attribute implements INote 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 Note; 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 Note * @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 Note; namespace Kiri\Annotation;
interface INote 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 Note; 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 Note * @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 Note; 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 Note * @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 Note; 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 Note\Route; namespace Kiri\Annotation\Route;
use Note\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Document * Class Document
* @package Note\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,53 +1,53 @@
<?php <?php
namespace Note\Route; namespace Kiri\Annotation\Route;
use Note\Attribute; use Kiri\Annotation\Attribute;
use Http\Handler\Abstracts\MiddlewareManager; use Http\Handler\Abstracts\MiddlewareManager;
use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\MiddlewareInterface;
/** /**
* Class Middleware * Class Middleware
* @package Note\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 * @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); MiddlewareManager::add($class, $method, $this->middleware);
return parent::execute($class, $method); return parent::execute($class, $method);
} }
} }
@@ -1,41 +1,41 @@
<?php <?php
namespace Note\Route; namespace Kiri\Annotation\Route;
use Note\Attribute; use Kiri\Annotation\Attribute;
use Http\Handler\Router; use Http\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 Note\Route; namespace Kiri\Annotation\Route;
use Note\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Socket * Class Socket
* @package Note * @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 Note; namespace Kiri\Annotation;
/** /**
* Class Target * Class Target
* @package Note * @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)
{ {
} }
} }
+44 -44
View File
@@ -1,44 +1,44 @@
<?php <?php
namespace Note; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Kiri; use Kiri\Kiri;
use Server\Tasker\AsyncTaskExecute; use Server\Tasker\AsyncTaskExecute;
/** /**
* Class Task * Class Task
* @package Note * @package Annotation
* Task任务 * Task任务
*/ */
#[\Attribute(\Attribute::TARGET_CLASS)] class Task extends Attribute #[\Attribute(\Attribute::TARGET_CLASS)] class Task extends Attribute
{ {
/** /**
* Task constructor. * Task constructor.
* @param string $name * @param string $name
*/ */
public function __construct(public string $name) public function __construct(public string $name)
{ {
} }
/** /**
* @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
{ {
$task = Kiri::getDi()->get(AsyncTaskExecute::class); $task = Kiri::getDi()->get(AsyncTaskExecute::class);
$task->reg($this->name, $class); $task->reg($this->name, $class);
return true; return true;
} }
} }
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace Kiri\Abstracts;
abstract class AbstractServer extends Component
{
public string $name = 'http';
}
+451 -460
View File
@@ -1,460 +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 Note\Note as SNote; use Database\Connection;
use Database\Connection; use Exception;
use Exception; use Http\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 Server\{Contract\OnTaskInterface, Server, ServerManager, Tasker\AsyncTaskExecute};
use Kiri\Events\EventProvider; use Swoole\Table;
use Kiri\Exception\InitException;
use Kiri\Exception\NotFindClassException; /**
use Kiri\Kiri; * Class BaseApplication
use ReflectionException; * @package Kiri\Kiri\Base
use Server\ServerManager; */
use Server\Contract\OnTaskInterface; abstract class BaseApplication extends Component
use Swoole\Table; {
/** use TraitApplication;
* Class BaseApplication
* @package Kiri\Kiri\Base
*/ /**
abstract class BaseApplication extends Component * @var string
{ */
public string $storage = APP_PATH . 'storage';
use TraitApplication;
public string $envPath = APP_PATH . '.env';
/** /**
* @var string * Init constructor.
*/ *
public string $storage = APP_PATH . 'storage'; *
* @throws
public string $envPath = APP_PATH . '.env'; */
public function __construct()
/** {
* Init constructor. Kiri::init($this);
*
* $config = sweep(APP_PATH . '/config');
* @throws
*/ $this->moreComponents();
public function __construct() $this->parseInt($config);
{ $this->parseEvents($config);
Kiri::init($this); $this->initErrorHandler();
$this->enableEnvConfig();
$config = sweep(APP_PATH . '/config'); $this->mapping($config['mapping'] ?? []);
$this->moreComponents(); parent::__construct();
$this->parseInt($config); }
$this->parseEvents($config);
$this->initErrorHandler();
$this->enableEnvConfig(); /**
$this->mapping($config['mapping'] ?? []); * @param array $mapping
*/
parent::__construct(); public function mapping(array $mapping)
} {
$di = Kiri::getDi();
foreach ($mapping as $interface => $class) {
/** $di->mapping($interface, $class);
* @param array $mapping }
*/ }
public function mapping(array $mapping)
{
$di = Kiri::getDi(); /**
foreach ($mapping as $interface => $class) { * @return array
$di->mapping($interface, $class); */
} public function enableEnvConfig(): array
} {
if (!file_exists($this->envPath)) {
return [];
/** }
* @return array $lines = $this->readLinesFromFile($this->envPath);
*/ foreach ($lines as $line) {
public function enableEnvConfig(): array if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
{ [$key, $value] = explode('=', $line);
if (!file_exists($this->envPath)) { putenv(trim($key) . '=' . trim($value));
return []; }
} }
$lines = $this->readLinesFromFile($this->envPath); return $lines;
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.
} *
return $lines; * @param string $filePath
} *
* @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
* @param string $filePath $autodetect = ini_get('auto_detect_line_endings');
* ini_set('auto_detect_line_endings', '1');
* @return array $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
*/ 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'); /**
$lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); * Determine if the line in the file is a comment, e.g. begins with a #.
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
*/ /**
protected function looksLikeSetter(string $line): bool * @param $config
{ *
return str_contains($line, '='); * @throws
} */
public function parseInt($config)
{
/** Config::sets($config);
* @param $config if ($storage = Config::get('storage', 'storage')) {
* if (!str_contains($storage, APP_PATH)) {
* @throws $storage = APP_PATH . $storage . '/';
*/ }
public function parseInt($config) if (!is_dir($storage)) {
{ mkdir($storage);
Config::sets($config); }
if ($storage = Config::get('storage', 'storage')) { if (!is_dir($storage) || !is_writeable($storage)) {
if (!str_contains($storage, APP_PATH)) { throw new InitException("Directory {$storage} does not have write permission");
$storage = APP_PATH . $storage . '/'; }
} }
if (!is_dir($storage)) { }
mkdir($storage);
}
if (!is_dir($storage) || !is_writeable($storage)) { /**
throw new InitException("Directory {$storage} does not have write permission"); * @param $name
} * @return mixed
} * @throws ReflectionException
} * @throws NotFindClassException
* @throws Exception
*/
/** public function __get($name): mixed
* @param $name {
* @return mixed if ($this->has($name)) {
* @throws ReflectionException return $this->get($name);
* @throws NotFindClassException }
* @throws Exception return parent::__get($name); // TODO: Change the autogenerated stub
*/ }
public function __get($name): mixed
{
if ($this->has($name)) { /**
return $this->get($name); * @param $config
} *
return parent::__get($name); // TODO: Change the autogenerated stub * @throws
} */
public function parseEvents($config)
{
/** if (!isset($config['events']) || !is_array($config['events'])) {
* @param $config return;
* }
* @throws foreach ($config['events'] as $key => $value) {
*/ if (is_string($value)) {
public function parseEvents($config) $value = Kiri::createObject($value);
{ }
if (!isset($config['events']) || !is_array($config['events'])) { $this->addEvent($key, $value);
return; }
} }
foreach ($config['events'] as $key => $value) {
if (is_string($value)) {
$value = Kiri::createObject($value); /**
} * @param OnTaskInterface $execute
$this->addEvent($key, $value); * @throws ReflectionException
} */
} public function task(OnTaskInterface $execute): void
{
di(AsyncTaskExecute::class)->execute($execute);
/** }
* @param OnTaskInterface $execute
* @throws ReflectionException
*/ /**
public function task(OnTaskInterface $execute): void * @param $key
{ * @param $value
di(ServerManager::class)->task($execute); * @throws InitException
} * @throws Exception
*/
private function addEvent($key, $value): void
/** {
* @param $key if ($value instanceof \Closure || is_object($value)) {
* @param $value $this->eventProvider->on($key, $value, 0);
* @throws InitException return;
* @throws Exception }
*/
private function addEvent($key, $value): void
{ if (is_array($value)) {
$eventProvider = di(EventProvider::class); if (is_object($value[0]) && !($value[0] instanceof \Closure)) {
if ($value instanceof \Closure || is_object($value)) { $this->eventProvider->on($key, $value, 0);
$eventProvider->on($key, $value, 0); return;
return; }
}
if (is_string($value[0])) {
$value[0] = Kiri::createObject($value[0]);
if (is_array($value)) { $this->eventProvider->on($key, $value, 0);
if (is_object($value[0]) && !($value[0] instanceof \Closure)) { return;
$eventProvider->on($key, $value, 0); }
return;
}
foreach ($value as $item) {
if (is_string($value[0])) { if (!is_callable($item, true)) {
$value[0] = Kiri::createObject($value[0]); throw new InitException("Class does not hav callback.");
$eventProvider->on($key, $value, 0); }
return; $this->eventProvider->on($key, $item, 0);
} }
}
foreach ($value as $item) { }
if (!is_callable($item, true)) {
throw new InitException("Class does not hav callback.");
} /**
$eventProvider->on($key, $item, 0); * @param $name
} * @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
public function initErrorHandler() * @return mixed
{ * @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 getLocalIps(): mixed public function getFirstLocal(): mixed
{ {
return swoole_get_local_ip(); return current($this->getLocalIps());
} }
/**
* @return mixed /**
*/ * @return Logger
public function getFirstLocal(): mixed * @throws
{ */
return current($this->getLocalIps()); public function getLogger(): Logger
} {
return $this->get('logger');
}
/**
* @return Logger
* @throws /**
*/ * @return \Redis|Redis
public function getLogger(): Logger * @throws
{ */
return $this->get('logger'); public function getRedis(): Redis|\Redis
} {
return Kiri::getDi()->get(Redis::class);
}
/**
* @return \Redis|Redis /**
* @throws * @param $ip
*/ * @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
public function isLocal($ip): bool * @throws
{ */
return $this->getFirstLocal() == $ip; public function getError(): ErrorHandler
} {
return $this->get('error');
}
/**
* @return ErrorHandler
* @throws /**
*/ * @param $name
public function getError(): ErrorHandler * @return Table
{ * @throws
return $this->get('error'); */
} public function getTable($name): Table
{
return $this->get($name);
/** }
* @param $name
* @return Table
* @throws /**
*/ * @return Config
public function getTable($name): Table * @throws
{ */
return $this->get($name); public function getConfig(): Config
} {
return $this->get('config');
}
/**
* @return Config
* @throws /**
*/ * @return Router
public function getConfig(): Config * @throws
{ */
return $this->get('config'); public function getRouter(): Router
} {
return Kiri::getDi()->get(Router::class);
}
/**
* @return Router
* @throws /**
*/ * @return Server
public function getRouter(): Router * @throws
{ */
return Kiri::getDi()->get(Router::class); public function getServer(): Server
} {
return $this->get('server');
}
/**
* @return Server
* @throws /**
*/ * @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
public function getServer(): Server * @throws
{ */
return $this->get('server'); public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
} {
return di(ServerManager::class)->getServer();
}
/**
* @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
* @throws /**
*/ * @return SAnnotation
public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null * @throws
{ */
return di(ServerManager::class)->getServer(); public function getAnnotation(): SAnnotation
} {
return $this->get('Annotation');
}
/**
* @return SNote
* @throws /**
*/ * @return Async
public function getNote(): SNote * @throws
{ */
return $this->get('note'); public function getAsync(): Async
} {
return $this->get('async');
}
/**
* @return Async
* @throws /**
*/ * @param $array
public function getAsync(): Async */
{ private function setComponents($array): void
return $this->get('async'); {
} di(LocalService::class)->setComponents($array);
}
/** /**
* @param $array * @param $id
*/ * @param $definition
private function setComponents($array): void */
{ public function set($id, $definition): void
di(LocalService::class)->setComponents($array); {
} di(LocalService::class)->set($id, $definition);
}
/**
* @param $id /**
* @param $definition * @param $id
*/ * @return bool
public function set($id, $definition): void */
{ public function has($id): bool
di(LocalService::class)->set($id, $definition); {
} return di(LocalService::class)->has($id);
}
/**
* @param $id /**
* @return bool * @throws Exception
*/ */
public function has($id): bool protected function moreComponents(): void
{ {
return di(LocalService::class)->has($id); $this->setComponents([
} 'error' => ['class' => ErrorHandler::class],
'config' => ['class' => Config::class],
'logger' => ['class' => Logger::class],
/** 'Annotation' => ['class' => SAnnotation::class],
* @throws Exception 'databases' => ['class' => Connection::class],
*/ 'jwt' => ['class' => Jwt::class],
protected function moreComponents(): void 'async' => ['class' => Async::class],
{ 'kafka-container' => ['class' => KafkaProvider::class],
$this->setComponents([ ]);
'error' => ['class' => ErrorHandler::class], }
'config' => ['class' => Config::class], }
'logger' => ['class' => Logger::class],
'note' => ['class' => SNote::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 Note\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 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 Note\Note as SNote; use Kiri\Annotation\Annotation as SAnnotation;
use Database\Connection; use Database\Connection;
use Database\DatabasesProviders; use Database\DatabasesProviders;
use Http\Handler\Client\Client; use Http\Handler\Router;
use Http\Handler\Client\Curl; use 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\JWTAuth; * 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 JWTAuth $jwt * @property Connection $databases
* @property SNote $annotation */
* @property BaseGoto $goto trait TraitApplication
* @property Client $client {
* @property Connection $databases
* @property Curl $curl }
*/
trait TraitApplication
{
}
+253 -255
View File
@@ -1,255 +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 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 ReflectionException private function enableFileChange(Command $class, $input, $output): void
* @throws Exception {
*/ fire(new OnBeforeCommandExecute());
private function enableFileChange(Command $class, $input, $output): void if (!($class instanceof HotReload)) {
{ scan_directory(directory('app'), 'App');
fire(new OnBeforeCommandExecute()); }
if (!($class instanceof HotReload)) {
scan_directory(directory('app'), 'App'); $this->container->setBindings(OutputInterface::class, $output);
}
$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
* @param $className * @return stdClass
* @param null $abstracts * @throws Exception
* @return stdClass */
* @throws Exception public function make($className, $abstracts = null): stdClass
*/ {
public function make($className, $abstracts = null): stdClass return make($className, $abstracts);
{ }
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 Server\ServerManager;
use 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 Note\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 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 -98
View File
@@ -1,98 +1,101 @@
<?php <?php
namespace Kiri\Core; namespace Kiri\Core;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use ReturnTypeWillChange;
class HashMap implements \ArrayAccess
{ class HashMap implements \ArrayAccess
{
/**
* @var array /**
*/ * @var array
private array $lists = []; */
private array $lists = [];
/**
* @param string $key /**
* @param $value * @param string $key
*/ * @param $value
public function put(string $key, $value) */
{ public function put(string $key, $value)
$this->lists[$key] = $value; {
} $this->lists[$key] = $value;
}
/**
* @param string $key /**
* @return mixed * @param string $key
*/ * @return mixed
#[Pure] public function get(string $key): mixed */
{ #[Pure] public function get(string $key): mixed
if (!$this->has($key)) { {
return null; if (!$this->has($key)) {
} return null;
return $this->lists[$key]; }
} return $this->lists[$key];
}
/**
* @param string $key /**
*/ * @param string $key
public function del(string $key) */
{ public function del(string $key)
if (!$this->has($key)) { {
return; if (!$this->has($key)) {
} return;
unset($this->lists[$key]); }
} unset($this->lists[$key]);
}
/**
* @param string $key /**
* @return bool * @param string $key
*/ * @return bool
public function has(string $key): bool */
{ public function has(string $key): bool
return array_key_exists($key, $this->lists); {
} return array_key_exists($key, $this->lists);
}
/**
* @param mixed $offset /**
* @return bool * @param mixed $offset
*/ * @return bool
public function offsetExists($offset): bool */
{ public function offsetExists(mixed $offset): bool
return isset($this->lists[$offset]); {
} return isset($this->lists[$offset]);
}
/**
* @param mixed $offset /**
* @return mixed * @param mixed $offset
*/ * @return mixed
#[Pure] public function offsetGet($offset): mixed */
{ #[Pure] public function offsetGet(mixed $offset): mixed
return $this->get($offset); {
} return $this->get($offset);
}
/**
* @param mixed $offset /**
* @param mixed $value * @param mixed $offset
*/ * @param mixed $value
public function offsetSet($offset, $value) */
{ #[ReturnTypeWillChange]
$this->put($offset, $value); public function offsetSet(mixed $offset, mixed $value)
} {
$this->put($offset, $value);
}
/**
* @param mixed $offset
*/ /**
public function offsetUnset($offset) * @param mixed $offset
{ */
unset($this->lists[$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 -283
View File
@@ -1,283 +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);
for ($i = 0; $i < $length; $i++) { for ($i = 0; $i < $length; $i++) {
shuffle($default); shuffle($default);
$string .= $default[array_rand($default)]; $string .= $default[array_rand($default)];
} }
return $string; return $string;
} }
/** /**
* @param int $length * @param int $length
* *
* @return int|string 获取随机数字 * @return int|string 获取随机数字
* 获取随机数字 * 获取随机数字
*/ */
public static function random(int $length = 20): int|string public static function random(int $length = 20): int|string
{ {
$number = ''; $number = '';
$default = str_split(self::NUMBER); $default = str_split(self::NUMBER);
if ($length < 1) $length = 1; if ($length < 1) $length = 1;
for ($i = 0; $i < $length; $i++) { for ($i = 0; $i < $length; $i++) {
shuffle($default); shuffle($default);
$number .= $default[array_rand($default)]; $number .= $default[array_rand($default)];
} }
return $number; return $number;
} }
/** /**
* @param $string * @param $string
* @param $sullen * @param $sullen
* @param bool $strip_tags * @param bool $strip_tags
* @param string $append * @param string $append
* *
* @return string * @return string
*/ */
public static function cut_str_utf8($string, $sullen, bool $strip_tags = TRUE, string $append = '...'): string public static function cut_str_utf8($string, $sullen, bool $strip_tags = TRUE, string $append = '...'): string
{ {
if ($strip_tags) { if ($strip_tags) {
$string = strip_tags($string); $string = strip_tags($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]/"; $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); preg_match_all($pa, $string, $t_string);
$str = ""; $str = "";
for ($i = 0; $i < count($t_string[0]); $i++) { for ($i = 0; $i < count($t_string[0]); $i++) {
$str .= $t_string[0][$i]; $str .= $t_string[0][$i];
//转为gbk,一个汉字长度为2 //转为gbk,一个汉字长度为2
if (strlen(@iconv('utf-8', 'gbk', $str)) >= $sullen) { if (strlen(@iconv('utf-8', 'gbk', $str)) >= $sullen) {
if ($i != count($t_string[0]) - 1) $str .= $append; if ($i != count($t_string[0]) - 1) $str .= $append;
break; break;
} }
} }
return $str; return $str;
} }
/** /**
* @param $data * @param $data
* *
* @param null $callback * @param null $callback
* @return bool * @return bool
* 判断是否为json字符串 * 判断是否为json字符串
*/ */
public static function isJson($data, $callback = NULL): bool public static function isJson($data, $callback = NULL): bool
{ {
$json = !is_null(json_decode($data)) && !is_numeric($data); $json = !is_null(json_decode($data)) && !is_numeric($data);
if ($json && is_callable($callback, TRUE)) { if ($json && is_callable($callback, TRUE)) {
return call_user_func($callback, $data); return call_user_func($callback, $data);
} }
return $json; return $json;
} }
/** /**
* @param $data * @param $data
* *
* @param null $callBack * @param null $callBack
* @return bool * @return bool
* 判断是否序列化字符串 * 判断是否序列化字符串
*/ */
public static function isSerialize($data, $callBack = NULL): bool public static function isSerialize($data, $callBack = NULL): bool
{ {
$false = !empty($data) && swoole_unserialize($data) !== FALSE; $false = !empty($data) && swoole_unserialize($data) !== FALSE;
if ($false && is_callable($callBack, TRUE)) { if ($false && is_callable($callBack, TRUE)) {
return call_user_func($callBack, $data); return call_user_func($callBack, $data);
} }
return $false; return $false;
} }
/** /**
* @param $string * @param $string
* @param int $length * @param int $length
* *
* @param string $append * @param string $append
* @return string * @return string
*/ */
public static function cut($string, int $length = 20, string $append = '...'): string public static function cut($string, int $length = 20, string $append = '...'): string
{ {
if (empty($string)) { if (empty($string)) {
return ''; return '';
} }
if ($length < 1) { if ($length < 1) {
$length = 1; $length = 1;
} }
$array = str_split($string); $array = str_split($string);
if (count($array) <= $length) { if (count($array) <= $length) {
return implode('', $array); return implode('', $array);
} }
$string = implode('', array_slice($array, 0, $length)); $string = implode('', array_slice($array, 0, $length));
if (!empty($append)) { if (!empty($append)) {
$string .= $append; $string .= $append;
} }
return $string; return $string;
} }
/** /**
* @param $str * @param $str
* @param int $number * @param int $number
* @param string $key * @param string $key
* *
* @return string * @return string
*/ */
public static function encrypt($str, int $number = 10, string $key = 'xshucai.com'): string public static function encrypt($str, int $number = 10, string $key = 'xshucai.com'): string
{ {
$res = []; $res = [];
$add = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $add = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$len = strlen($key) < 0 ? 1 : (strlen($key) + 5 > strlen($add) ? strlen($add) - 5 : strlen($key)); $len = strlen($key) < 0 ? 1 : (strlen($key) + 5 > strlen($add) ? strlen($add) - 5 : strlen($key));
if ($number < 1) $number = 10; if ($number < 1) $number = 10;
$array = str_split($str); $array = str_split($str);
asort($array); asort($array);
$str = implode('', $array); $str = implode('', $array);
for ($i = 0; $i < $number; $i++) { for ($i = 0; $i < $number; $i++) {
$_tmp = md5($key) . md5($str) . mb_substr($add, $len, $len + 5, 'utf-8'); $_tmp = md5($key) . md5($str) . mb_substr($add, $len, $len + 5, 'utf-8');
$res[] = md5($_tmp); $res[] = md5($_tmp);
} }
sort($res, SORT_STRING); sort($res, SORT_STRING);
return hash('sha384', implode('', $res)); return hash('sha384', implode('', $res));
} }
/** /**
* @param $file * @param $file
* @param $type * @param $type
* @return string * @return string
*/ */
public static function filename($file, $type): string public static function filename($file, $type): string
{ {
switch ($type) { switch ($type) {
case 'image/png': case 'image/png':
return md5_file($file) . '.png'; return md5_file($file) . '.png';
case 'image/jpeg': case 'image/jpeg':
case 'image/jpg': case 'image/jpg':
return md5_file($file) . '.jpg'; return md5_file($file) . '.jpg';
case 'image/gif': case 'image/gif':
return md5_file($file) . '.gif'; return md5_file($file) . '.gif';
break; break;
} }
return md5_file($file); return md5_file($file);
} }
/** /**
* @param $endTime * @param $endTime
* @param int|null $startTime * @param int|null $startTime
* @return array * @return array
* 剩余天,带分秒 * 剩余天,带分秒
*/ */
public static function timeout($endTime, int $startTime = NULL): array public static function timeout($endTime, int $startTime = NULL): array
{ {
$endTime = $endTime - (!empty($startTime) ? $startTime : time()); $endTime = $endTime - (!empty($startTime) ? $startTime : time());
$day = intval($endTime / (3600 * 24)); $day = intval($endTime / (3600 * 24));
$hours = intval(($endTime - ($day * (3600 * 24))) / 3600); $hours = intval(($endTime - ($day * (3600 * 24))) / 3600);
$minute = intval(($endTime - ($day * (3600 * 24) + $hours * 3600)) / 60); $minute = intval(($endTime - ($day * (3600 * 24) + $hours * 3600)) / 60);
$scrod = intval(($endTime - ($day * (3600 * 24) + $hours * 3600 + $minute * 60))); $scrod = intval(($endTime - ($day * (3600 * 24) + $hours * 3600 + $minute * 60)));
return [$day, $hours, $minute, $scrod]; return [$day, $hours, $minute, $scrod];
} }
/** /**
* @return false|int * @return false|int
*/ */
public static function get_sy_time(): bool|int public static function get_sy_time(): bool|int
{ {
$time = strtotime('+1days', strtotime(date('Y-m-d'))); $time = strtotime('+1days', strtotime(date('Y-m-d')));
return $time - time(); return $time - time();
} }
/** /**
* @param string $string * @param string $string
* @return string * @return string
*/ */
public static function encode(string $string): string public static function encode(string $string): string
{ {
return addslashes($string); return addslashes($string);
} }
/** /**
* @param string $string * @param string $string
* @return string|string[]|null * @return string|string[]|null
* 清除标点符号 * 清除标点符号
*/ */
public static function clear(string $string): array|string|null public static function clear(string $string): array|string|null
{ {
$char = '。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()'; $char = '。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()';
return preg_replace(["/[[:punct:]]/i", '/[' . $char . ']/u', '/[ ]{2,}/'], '', $string); return preg_replace(["/[[:punct:]]/i", '/[' . $char . ']/u', '/[ ]{2,}/'], '', $string);
} }
/** /**
* @param int $user * @param int $user
* @param array $param * @param array $param
* @param null $requestTime * @param null $requestTime
* *
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public static function token(int $user, array $param = [], $requestTime = NULL): string public static function token(int $user, array $param = [], $requestTime = NULL): string
{ {
$str = ''; $str = '';
if (!$requestTime) { if (!$requestTime) {
$requestTime = microtime(TRUE); $requestTime = microtime(TRUE);
} }
$_user = str_split(md5($user . md5((string)$user))); $_user = str_split(md5($user . md5((string)$user)));
ksort($_user); ksort($_user);
foreach ($_user as $key => $val) { foreach ($_user as $key => $val) {
$str .= md5(sha1($key . $val . 'www.xshucai.com')); $str .= md5(sha1($key . $val . 'www.xshucai.com'));
} }
if (is_array($param)) { if (is_array($param)) {
foreach ($param as $key => $val) { foreach ($param as $key => $val) {
$str .= md5($str . sha1($key . md5($val))); $str .= md5($str . sha1($key . md5($val)));
} }
} }
$str .= sha1(base64_encode((string)$requestTime)); $str .= sha1(base64_encode((string)$requestTime));
$md5 = md5($str . $user); $md5 = md5($str . $user);
return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $md5); return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $md5);
} }
/** /**
* @param string $str * @param string $str
* @param bool $unfairest * @param bool $unfairest
* @return string * @return string
*/ */
public static function convertUnderline(string $str, bool $unfairest = TRUE): string public static function convertUnderline(string $str, bool $unfairest = TRUE): string
{ {
$str = ucwords(str_replace('_', ' ', $str)); $str = ucwords(str_replace('_', ' ', $str));
$str = str_replace(' ', '', lcfirst($str)); $str = str_replace(' ', '', lcfirst($str));
return $unfairest ? ucfirst($str) : $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 -461
View File
@@ -1,461 +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 Note\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;
use Psr\Container\ContainerInterface;
/**
/** * Class Container
* Class Container * @package Kiri\Di
* @package Kiri\Di */
*/ class Container implements ContainerInterface
class Container extends BaseObject 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 string $id
* @param string $id * @return mixed
* @return mixed * @throws
* @throws ReflectionException */
*/ public function get(string $id): mixed
public function get(string $id): mixed {
{ return $this->make($id, [], []);
return $this->make($id, [], []); }
}
/**
/** * @param $class
* @param $class * @param array $constrict
* @param array $constrict * @param array $config
* @param array $config * @return mixed
* @return mixed * @throws
* @throws ReflectionException */
* @throws Exception public function make($class, array $constrict = [], array $config = []): mixed
*/ {
public function make($class, array $constrict = [], array $config = []): mixed if ($this->isInterface($class)) {
{ $class = $this->_interfaces[$class];
if ($this->isInterface($class)) { }
$class = $this->_interfaces[$class]; if (!isset($this->_singletons[$class])) {
} $this->_singletons[$class] = $this->resolve($class, $constrict, $config);
if (!isset($this->_singletons[$class])) { }
$this->_singletons[$class] = $this->resolve($class, $constrict, $config); return $this->_singletons[$class];
} }
return $this->_singletons[$class];
}
/**
* @param string $interface
/** * @param string $class
* @param string $interface */
* @param string $class public function mapping(string $interface, string $class)
*/ {
public function mapping(string $interface, string $class) $this->_interfaces[$interface] = $class;
{ }
$this->_interfaces[$interface] = $class;
}
/**
* @param $class
/** * @return bool
* @param $class */
* @return bool public function isInterface($class): bool
* @throws ReflectionException {
*/ $reflect = $this->getReflect($class);
public function isInterface($class): bool if ($reflect->isInterface()) {
{ return true;
$reflect = $this->getReflect($class); }
if ($reflect->isInterface()) { return false;
return true; }
}
return false;
} /**
* @param string $interface
* @param $object
/** */
* @param string $interface public function setBindings(string $interface, $object)
* @param $object {
*/ if (is_string($object)) {
public function setBindings(string $interface, $object) $this->_interfaces[$interface] = $object;
{ } else {
if (is_string($object)) { $className = get_class($object);
$this->_interfaces[$interface] = $object; $this->_interfaces[$interface] = $className;
} else { $this->_singletons[$className] = $object;
$className = get_class($object); }
$this->_interfaces[$interface] = $className; }
$this->_singletons[$className] = $object;
}
} /**
* @param $class
* @param array $constrict
/** * @param array $config
* @param $class * @return object
* @param array $constrict * @throws
* @param array $config */
* @return object public function create($class, array $constrict = [], array $config = []): object
* @throws {
*/ return $this->resolve($class, $constrict, $config);
public function create($class, array $constrict = [], array $config = []): object }
{
return $this->resolve($class, $constrict, $config);
} /**
* @param $class
* @param $constrict
/** * @param $config
* @param $class *
* @param $constrict * @return object
* @param $config * @throws Exception
* */
* @return object private function resolve($class, $constrict, $config): object
* @throws Exception {
*/ $reflect = $this->resolveDependencies($class);
private function resolve($class, $constrict, $config): object if (!$reflect->isInstantiable()) {
{ throw new ReflectionException('Class ' . $class . ' cannot be instantiated');
$reflect = $this->resolveDependencies($class); }
if (!$reflect->isInstantiable()) {
throw new ReflectionException('Class ' . $class . ' cannot be instantiated'); $object = $this->newInstance($reflect, $constrict);
}
$this->propertyInject($reflect, $object);
$object = $this->newInstance($reflect, $constrict);
return $this->onAfterInit($object, $config);
$this->propertyInject($reflect, $object); }
return $this->onAfterInit($object, $config);
} /**
* @param ReflectionClass $reflect
* @param $dependencies
/** * @return object
* @param ReflectionClass $reflect * @throws ReflectionException
* @param $dependencies */
* @return object private function newInstance(ReflectionClass $reflect, $dependencies): object
* @throws ReflectionException {
*/ if (!isset($this->_constructs[$reflect->getName()])) {
private function newInstance(ReflectionClass $reflect, $dependencies): object return $reflect->newInstance();
{ }
if (!isset($this->_constructs[$reflect->getName()])) { $construct = $this->_constructs[$reflect->getName()];
return $reflect->newInstance(); if ($construct->getNumberOfParameters() < 1) {
} return $reflect->newInstance();
$construct = $this->_constructs[$reflect->getName()]; }
if ($construct->getNumberOfParameters() < 1) { $parameters = $this->mergeParam($this->resolveMethodParameters($construct), $dependencies);
return $reflect->newInstance(); return $reflect->newInstanceArgs($parameters);
} }
$parameters = $this->mergeParam($this->resolveMethodParameters($construct), $dependencies);
return $reflect->newInstanceArgs($parameters);
} /**
* @param ReflectionClass $reflect
* @param $object
/** * @return mixed
* @param ReflectionClass $reflect * @throws Exception
* @param $object */
* @return mixed public function propertyInject(ReflectionClass $reflect, $object): mixed
* @throws Exception {
*/ foreach (NoteManager::getPropertyAnnotation($reflect) as $property => $inject) {
public function propertyInject(ReflectionClass $reflect, $object): mixed /** @var Inject $inject */
{ $inject->execute($object, $property);
foreach (NoteManager::getPropertyNote($reflect) as $property => $inject) { }
/** @var Inject $inject */ return $object;
$inject->execute($object, $property); }
}
return $object;
} /**
* @param $className
* @param $method
/** * @return array
* @param $className */
* @param $method public function getMethodAttribute($className, $method = null): array
* @return array {
* @throws ReflectionException $methods = NoteManager::getMethodAnnotation($this->getReflect($className));
*/ if (!empty($method)) {
public function getMethodAttribute($className, $method = null): array return $methods[$method] ?? [];
{ }
$methods = NoteManager::getMethodNote($this->getReflect($className)); return $methods;
if (!empty($method)) { }
return $methods[$method] ?? [];
}
return $methods; /**
} * @param string $class
* @param string|null $property
* @return ReflectionProperty|ReflectionProperty[]|null
/** */
* @param string $class public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array
* @param string|null $property {
* @return ReflectionProperty|ReflectionProperty[]|null $lists = NoteManager::getProperty($this->getReflect($class));
* @throws ReflectionException if (empty($lists)) {
*/ return null;
public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array }
{ if (!empty($property)) {
$lists = NoteManager::getProperty($this->getReflect($class)); return $lists[$property] ?? null;
if (empty($lists)) { }
return null; return $lists;
} }
if (!empty($property)) {
return $lists[$property] ?? null;
} /**
return $lists; * @param $object
} * @param $config
* @return mixed
*/
/** private function onAfterInit($object, $config): mixed
* @param $object {
* @param $config Kiri::configure($object, $config);
* @return mixed if (method_exists($object, 'init') && is_callable([$object, 'init'])) {
*/ call_user_func([$object, 'init']);
private function onAfterInit($object, $config): mixed }
{ return $object;
Kiri::configure($object, $config); }
if (method_exists($object, 'init') && is_callable([$object, 'init'])) {
call_user_func([$object, 'init']);
} /**
return $object; * @param $class
} * @return ReflectionClass
*/
private function resolveDependencies($class): ReflectionClass
/** {
* @param $class if (isset($this->_reflection[$class])) {
* @return ReflectionClass return $this->_reflection[$class];
* @throws ReflectionException }
*/ $reflect = new ReflectionClass($class);
private function resolveDependencies($class): ReflectionClass if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) {
{ return $this->_reflection[$class] = $reflect;
if (isset($this->_reflection[$class])) { }
return $this->_reflection[$class]; $construct = NoteManager::resolveTarget($reflect);
} if (!empty($construct) && $construct->getNumberOfParameters() > 0) {
$reflect = new ReflectionClass($class); $this->_constructs[$class] = $construct;
if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) { }
return $this->_reflection[$class] = $reflect; return $this->_reflection[$class] = $reflect;
} }
$construct = NoteManager::resolveTarget($reflect);
if (!empty($construct) && $construct->getNumberOfParameters() > 0) {
$this->_constructs[$class] = $construct; /**
} * @param ReflectionClass|string $class
return $this->_reflection[$class] = $reflect; * @return ReflectionMethod[]
} * @throws ReflectionException
*/
public function getReflectMethods(ReflectionClass|string $class): array
/** {
* @param ReflectionClass|string $class if (is_string($class)) {
* @return ReflectionMethod[] $class = $this->getReflect($class);
* @throws ReflectionException }
*/ return NoteManager::getMethods($class);
public function getReflectMethods(ReflectionClass|string $class): array }
{
if (is_string($class)) {
$class = $this->getReflect($class); /**
} * @param ReflectionClass|string $class
return NoteManager::getMethods($class); * @param string $method
} * @return ReflectionMethod|null
* @throws ReflectionException
*/
/** public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
* @param ReflectionClass|string $class {
* @param string $method return $this->getReflectMethods($class)[$method] ?? null;
* @return ReflectionMethod|null }
* @throws ReflectionException
*/
public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod /**
{ * @param string $className
return $this->getReflectMethods($class)[$method] ?? null; * @param string $method
} * @return array|null
* @throws ReflectionException
*/
/** public function getMethodParameters(string $className, string $method): ?array
* @param string $className {
* @param string $method if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) {
* @return array|null return $this->_parameters[$className][$method];
* @throws ReflectionException }
*/ $reflectMethod = $this->getReflectMethod($this->getReflect($className), $method);
public function getMethodParameters(string $className, string $method): ?array if (!($reflectMethod instanceof ReflectionMethod)) {
{ throw new ReflectionException("Class does not have a function $className::$method");
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) { }
return $this->_parameters[$className][$method]; $className = $reflectMethod->getDeclaringClass()->getName();
} if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) {
$reflectMethod = $this->getReflectMethod($this->getReflect($className), $method); return $this->_parameters[$className][$reflectMethod->getName()];
if (!($reflectMethod instanceof ReflectionMethod)) { }
throw new ReflectionException("Class does not have a function $className::$method"); return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod));
} }
$className = $reflectMethod->getDeclaringClass()->getName();
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) {
return $this->_parameters[$className][$reflectMethod->getName()]; /**
} * @param $class
return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod)); * @param $method
} * @param $parameters
* @return mixed
*/
/** private function setParameters($class, $method, $parameters): mixed
* @param $class {
* @param $method if (!isset($this->_parameters[$class])) {
* @param $parameters $this->_parameters[$class] = [];
* @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
if (!isset($this->_parameters[$class][$method])) { * @return array
$this->_parameters[$class][$method] = []; * @throws ReflectionException
} */
return $this->_parameters[$class][$method] = $parameters; public function getFunctionParameters(Closure $reflectionMethod): array
} {
return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod));
}
/**
* @param Closure $reflectionMethod
* @return array /**
* @throws ReflectionException * @param ReflectionMethod|ReflectionFunction $reflectionMethod
*/ * @return array
public function getFunctionParameters(Closure $reflectionMethod): array */
{ private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array
return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod)); {
} if ($reflectionMethod->getNumberOfParameters() < 1) {
return [];
}
/** $params = [];
* @param ReflectionMethod|ReflectionFunction $reflectionMethod foreach ($reflectionMethod->getParameters() as $key => $parameter) {
* @return array if ($parameter->isDefaultValueAvailable()) {
* @throws ReflectionException $params[$key] = $parameter->getDefaultValue();
*/ } else if ($parameter->getType() === null) {
private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array $params[$key] = $parameter->getType();
{ } else {
if ($reflectionMethod->getNumberOfParameters() < 1) { $type = $parameter->getType()->getName();
return []; if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) {
} $type = Kiri::getDi()->get($type);
$params = []; }
foreach ($reflectionMethod->getParameters() as $key => $parameter) { $params[$key] = match ($parameter->getType()) {
if ($parameter->isDefaultValueAvailable()) { 'string' => '',
$params[$key] = $parameter->getDefaultValue(); 'int', 'float' => 0,
} else if ($parameter->getType() === null) { '', null, 'object', 'mixed' => NULL,
$params[$key] = $parameter->getType(); 'bool' => false,
} else { default => $type
$type = $parameter->getType()->getName(); };
if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) { }
$type = Kiri::getDi()->get($type); }
} return $params;
$params[$key] = match ($parameter->getType()) { }
'string' => '',
'int', 'float' => 0,
'', null, 'object', 'mixed' => NULL, /**
'bool' => false, * @param $class
default => $type * @return ReflectionClass|null
}; */
} public function getReflect($class): ?ReflectionClass
} {
return $params; if (!isset($this->_reflection[$class])) {
} return $this->resolveDependencies($class);
}
return $this->_reflection[$class];
/** }
* @param $class
* @return ReflectionClass|null /**
* @throws ReflectionException * @param $class
*/ */
public function getReflect($class): ?ReflectionClass public function unset($class)
{ {
if (!isset($this->_reflection[$class])) { if (is_array($class) && isset($class['class'])) {
return $this->resolveDependencies($class); $class = $class['class'];
} } else if (is_object($class)) {
return $this->_reflection[$class]; $class = $class::class;
} }
unset(
/** $this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class]
* @param $class );
*/ }
public function unset($class)
{ /**
if (is_array($class) && isset($class['class'])) { * @return $this
$class = $class['class']; */
} else if (is_object($class)) { public function flush(): static
$class = $class::class; {
} $this->_reflection = [];
unset( $this->_singletons = [];
$this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class] $this->_constructs = [];
); return $this;
} }
/** /**
* @return $this * @param $old
*/ * @param $newParam
public function flush(): static *
{ * @return mixed
$this->_reflection = []; */
$this->_singletons = []; private function mergeParam($old, $newParam): array
$this->_constructs = []; {
return $this; if (empty($old)) {
} return $newParam;
} else if (empty($newParam)) {
/** return $old;
* @param $old }
* @param $newParam foreach ($newParam as $key => $val) {
* $old[$key] = $val;
* @return mixed }
*/ return $old;
private function mergeParam($old, $newParam): array }
{
if (empty($old)) { /**
return $newParam; * @param string $id
} else if (empty($newParam)) { * @return bool
return $old; */
} public function has(string $id): bool
foreach ($newParam as $key => $val) { {
$old[$key] = $val; return isset($this->_singletons[$id]) || isset($this->_interfaces[$id]);
} }
return $old; }
}
/**
* @param string $id
* @return bool
*/
public function has(string $id): bool
{
return isset($this->_singletons[$id]) || isset($this->_interfaces[$id]);
}
}
+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 getPropertyByNote(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 Http\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 Http\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 Note\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 Http\Aspect\OnAspectInterface;
use Http\Aspect\OnJoinPointInterface; use Http\Aspect\OnJoinPointInterface;
use Http\Constrict\RequestInterface; use Http\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 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
{ {
} }
+235 -177
View File
@@ -1,177 +1,235 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Exception; use Exception;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Error\Logger; use Kiri\Core\Json;
use Kiri\Exception\ConfigException; use Kiri\Error\Logger;
use Kiri\Kiri; use Kiri\Exception\ConfigException;
use Note\Inject; use Kiri\Kiri;
use Swoole\Coroutine; use Kiri\Annotation\Inject;
use Swoole\Process; use Swoole\Coroutine;
use Swoole\Timer; use Swoole\Process;
use Symfony\Component\Console\Command\Command; use Swoole\Timer;
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\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 bool $isReloadingOut = FALSE;
public int $events; public ?array $dirs = [];
public int $int = -1; public int $events;
public int $int = -1;
private ?Process $process = null;
private ?Process $process = NULL;
public Inotify|Scaner $driver;
public Inotify|Scaner $driver;
#[Inject(Logger::class)]
public Logger $logger;
#[Inject(Logger::class)]
public Logger $logger;
protected mixed $source = null;
protected mixed $pipes = []; protected mixed $source = NULL;
protected ?Coroutine\Channel $channel = null; protected mixed $pipes = [];
protected ?Coroutine\Channel $channel = NULL;
/**
*
*/ /**
protected function configure() */
{ protected function configure()
$this->setName('sw:wather') {
->setDescription('server start'); $this->setName('sw:wather')->setDescription('server start');
} }
/** /**
* @param InputInterface $input * @throws ConfigException
* @param OutputInterface $output * @throws \ReflectionException
* @return int * @throws Exception
* @throws ConfigException */
* @throws Exception protected function initCore()
*/ {
public function execute(InputInterface $input, OutputInterface $output): int set_error_handler([$this, 'errorHandler']);
{ $this->dirs = Config::get('inotify', [APP_PATH . 'app']);
// TODO: Implement onHandler() method. if (!extension_loaded('inotify')) {
set_error_handler([$this, 'onErrorHandler']); $this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]);
$this->dirs = Config::get('inotify', [APP_PATH . 'app']); } else {
swoole_async_set(['enable_coroutine' => false]); $this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]);
if (!extension_loaded('inotify')) { }
$this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]); $this->clearOtherService();
} else { $this->setProcessName();
$this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]); }
}
if (Kiri::getPlatform()->isLinux()) {
swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather'); /**
} * @throws ConfigException
$this->trigger_reload(); */
public function setProcessName()
Timer::tick(1000, fn() => $this->healthCheck()); {
swoole_async_set(['enable_coroutine' => FALSE]);
Process::signal(SIGTERM, [$this, 'onSignal']); if (Kiri::getPlatform()->isLinux()) {
Process::signal(SIGKILL, [$this, 'onSignal']); swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather');
}
$this->driver->start(); }
return 0;
}
/**
* @throws Exception
/** */
* @throws Exception public function clearOtherService()
*/ {
public function healthCheck() if (file_exists(storage('.manager.pid'))) {
{ $pid = (int)file_get_contents(storage('.manager.pid'));
$pid = (int)file_get_contents(storage('.swoole.pid')); if ($pid > 0 && Process::kill($pid, 0)) {
$this->logger->debug('timer ticker.' . $pid . '.' . Process::kill($pid, 0)); Process::kill($pid, 15) && Process::wait(TRUE);
if (empty($pid)) { }
$this->trigger_reload(); }
} else if (!Process::kill($pid, 0)) { file_put_contents(storage('.manager.pid'), getmypid());
if ($this->process && Process::kill($this->process->pid, 0)) { }
echo 'service is shutdown you need reload.';
Process::kill($this->process->pid, -15);
} /**
$this->trigger_reload(); * @throws Exception
} */
} public function errorHandler()
{
$error = func_get_args();
/**
* @param $data $path = ['file' => $error[2], 'line' => $error[3]];
* @throws Exception
*/ if ($error[0] === 0) {
public function onSignal($data) $error[0] = 500;
{ }
if (!$data) { $data = Json::to(500, $error[1], $path);
return;
} $this->logger->error($data, 'error');
$this->driver->clear(); }
$pid = file_get_contents(storage('.swoole.pid'));
if (!empty($pid) && Process::kill($pid, 0)) {
Process::kill($pid, SIGTERM); /**
} * @param InputInterface $input
if ($this->process && Process::kill($this->process->pid, 0)) { * @param OutputInterface $output
Process::kill($this->process->pid) && Process::wait(true); * @return int
} * @throws ConfigException
while ($ret = Process::wait(true)) { * @throws Exception
echo "PID={$ret['pid']}\n"; */
sleep(1); public function execute(InputInterface $input, OutputInterface $output): int
} {
} $this->initCore();
$this->trigger_reload();
/** Timer::tick(1000, fn() => $this->healthCheck());
* @param $code
* @param $message Process::signal(SIGTERM, [$this, 'onSignal']);
* @param $file Process::signal(SIGKILL, [$this, 'onSignal']);
* @param $line
* @throws Exception $this->driver->start();
*/ return 0;
public function onErrorHandler($code, $message, $file, $line) }
{
if (str_contains($message, 'The file descriptor is not an inotify instance')) {
return; /**
} * @throws Exception
debug('Error:' . $message . ' at ' . $file . ':' . $line); */
} public function healthCheck()
{
$pid = (int)file_get_contents(storage('.swoole.pid'));
/** if ($this->int == 1) {
* 重启 return;
* }
* @throws Exception if (empty($pid)) {
*/ $this->logger->warning('service is shutdown you need reload.');
public function trigger_reload() $this->trigger_reload();
{ } else if (!Process::kill($pid, 0)) {
$this->logger->warning('change reload'); $this->logger->warning('service is shutdown you need reload.');
$pid = $this->process?->pid; $this->trigger_reload();
$process = new Process(function (Process $process) { }
$process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "restart"]); }
$this->logger->warning('service stop.');
}); /**
$process->start(); * @param $data
if ($pid && Process::kill($pid, 0)) { * @throws Exception
Process::kill($pid) && Process::wait(true); */
} public function onSignal($data)
$this->process = null; {
$this->process = $process; if (!$data) {
} return;
}
Timer::clearAll();
} $this->driver->clear();
$this->stopServer();
$this->stopManager();
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);
}
}
/**
*
*/
protected function stopManager()
{
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->stopManager();
$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();
} }
+636 -633
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()->getNote(); // 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 -14
View File
@@ -1,14 +1,14 @@
<?php <?php
namespace Kiri\Gateway; namespace Kiri\Gateway;
class Collector class Collector
{ {
public function get() public function get()
{ {
} }
} }
+23 -23
View File
@@ -1,23 +1,23 @@
<?php <?php
namespace Kiri\Gateway; namespace Kiri\Gateway;
use Swoole\Http\Request; use Swoole\Http\Request;
use Swoole\Http\Response; use Swoole\Http\Response;
class GatewayServer class GatewayServer
{ {
/** /**
* @param Request $request * @param Request $request
* @param Response $response * @param Response $response
*/ */
public function onRequest(Request $request, Response $response) public function onRequest(Request $request, Response $response)
{ {
} }
} }
+35 -35
View File
@@ -1,35 +1,35 @@
<?php <?php
namespace Kiri\Gateway; namespace Kiri\Gateway;
class HashMap class HashMap
{ {
const HTTP = 1; const HTTP = 1;
const TCP = 2; const TCP = 2;
const UDP = 2; const UDP = 2;
public string $domain; public string $domain;
public string $path; public string $path;
public string $scheme; public string $scheme;
public string $method; public string $method;
public string $proxy_host; public string $proxy_host;
public string $proxy_port; public string $proxy_port;
public int $type = self::HTTP; public int $type = self::HTTP;
} }
+342 -343
View File
@@ -1,343 +1,342 @@
<?php <?php
/** /**
* Created by PhpStorm. * Created by PhpStorm.
* User: 向林 * User: 向林
* Date: 2016/8/9 0009 * Date: 2016/8/9 0009
* Time: 17:43 * Time: 17:43
*/ */
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Database\Connection; use Database\Connection;
use Database\Db; use Database\Db;
use Exception; use Exception;
use Kiri\Cache\Redis; use Kiri\Cache\Redis;
use Kiri\Kiri; use Kiri\Kiri;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
/** /**
* Class gii * Class gii
* *
* @package Inter\utility * @package Inter\utility
*/ */
class Gii class Gii
{ {
private ?string $tableName = NULL; private ?string $tableName = NULL;
/** @var null|Connection */ /** @var null|Connection */
private ?Connection $db; private ?Connection $db;
private InputInterface $input; private InputInterface $input;
public string $modelPath = APP_PATH . 'app/Model/'; public string $modelPath = APP_PATH . 'app/Model/';
public string $modelNamespace = 'App\\Model\\'; public string $modelNamespace = 'App\\Model\\';
public string $controllerPath = APP_PATH . 'app/Http/Controller/'; public string $controllerPath = APP_PATH . 'app/Http/Controller/';
public string $controllerNamespace = 'App\\Controller\\'; public string $controllerNamespace = 'App\\Controller\\';
public static array $createSqls = []; public static array $createSqls = [];
public array $keyword = [ public array $keyword = [
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL' 'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL'
]; ];
/** /**
* @param Connection|null $db * @param Connection|null $db
* *
* @param InputInterface $input * @param InputInterface $input
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function run(?Connection $db, InputInterface $input): array public function run(?Connection $db, InputInterface $input): array
{ {
return $this->gen($input, $db); return $this->gen($input, $db);
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
* @param $db * @param $db
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function gen(InputInterface $input, $db): array public function gen(InputInterface $input, $db): array
{ {
$this->input = $input; $this->input = $input;
$this->db = $db; $this->db = $db;
$make = $this->input->getArgument('action'); $make = $this->input->getOption('make');
if (empty($make)) { if (empty($make)) {
throw new Exception('构建类型不能为空~'); throw new Exception('构建类型不能为空~');
} }
switch (strtolower($make)) { switch (strtolower($make)) {
case 'task': case 'task':
$task = new GiiTask(); $task = new GiiTask();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'middleware': case 'middleware':
$task = new GiiMiddleware(); $task = new GiiMiddleware();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'rpc-client': case 'rpc-client':
$task = new GiiRpcClient(); $task = new GiiRpcClient();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'rpc-service': case 'rpc-service':
$task = new GiiRpcService(); $task = new GiiRpcService();
$task->setInput($this->input); $task->setInput($this->input);
return $task->generate(); return $task->generate();
case 'json-rpc': case 'json-rpc':
$task = new GiiJsonRpc(); $task = new GiiJsonRpc();
$task->setInput($this->input); $task->setInput($this->input);
return $task->create(); return $task->create();
default: default:
return $this->getModel($make, $input); return $this->getModel($make, $input);
} }
} }
/** /**
* @param $make * @param $make
* @param $input * @param $input
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
private function getModel($make, $input): array private function getModel($make, $input): array
{ {
return $this->makeByDatabases($make, $input); return $this->makeByDatabases($make, $input);
} }
/** /**
* @param $make * @param $make
* @param InputInterface $input * @param InputInterface $input
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
private function makeByDatabases($make, InputInterface $input): array private function makeByDatabases($make, InputInterface $input): array
{ {
$redis = Kiri::getDi()->get(Redis::class); if ($input->hasOption('name')) {
if ($input->hasArgument('name')) { $this->tableName = $input->getOption('name');
$this->tableName = $input->getArgument('name'); }
$redis->del('column:' . $this->tableName); return match ($make) {
} 'controller' => $this->getTable(1, 0),
return match ($make) { 'model' => $this->getTable(0, 1),
'controller' => $this->getTable(1, 0), default => [],
'model' => $this->getTable(0, 1), };
default => [], }
};
}
/**
* @param $controller
/** * @param $model
* @param $controller * @return array
* @param $model *
* @return array * @throws Exception
* */
* @throws Exception private function getTable($controller, $model): array
*/ {
private function getTable($controller, $model): array $tables = $this->getFields($this->getTables());
{ if (empty($tables)) {
$tables = $this->getFields($this->getTables()); return [];
if (empty($tables)) { }
return [];
} $fileList = [];
foreach ($tables as $key => $val) {
$fileList = []; $data = $this->createModelFile($key, $val);
foreach ($tables as $key => $val) { if ($controller == 1) {
$data = $this->createModelFile($key, $val); $fileList[] = $this->generateController($data);
if ($controller == 1) { }
$fileList[] = $this->generateController($data); if ($model == 1) {
} $fileList[] = $this->generateModel($data);
if ($model == 1) { }
$fileList[] = $this->generateModel($data); }
} return $fileList;
} }
return $fileList;
} /**
* @param array $data
/** * @return string
* @param array $data * @throws Exception
* @return string */
* @throws Exception private function generateModel(array $data): string
*/ {
private function generateModel(array $data): string $controller = new GiiModel($data['classFileName'], $data['tableName'], $data['visible'], $data['res'], $data['fields']);
{ $controller->setConnection($this->db);
$controller = new GiiModel($data['classFileName'], $data['tableName'], $data['visible'], $data['res'], $data['fields']); $controller->setModelPath($this->modelPath);
$controller->setConnection($this->db); $controller->setModelNamespace($this->modelNamespace);
$controller->setModelPath($this->modelPath); $controller->setInput($this->input);
$controller->setModelNamespace($this->modelNamespace); // $controller->setModule($this->input->getArgument('module'));
$controller->setInput($this->input); $controller->setControllerPath($this->controllerPath);
// $controller->setModule($this->input->getArgument('module')); $controller->setControllerNamespace($this->controllerNamespace);
$controller->setControllerPath($this->controllerPath); return $controller->generate();
$controller->setControllerNamespace($this->controllerNamespace); }
return $controller->generate();
} /**
* @param array $data
/** * @return string
* @param array $data * @throws Exception
* @return string */
* @throws Exception private function generateController(array $data): string
*/ {
private function generateController(array $data): string $controller = new GiiController($data['classFileName'], $data['fields']);
{ $controller->setConnection($this->db);
$controller = new GiiController($data['classFileName'], $data['fields']); $controller->setModelPath($this->modelPath);
$controller->setConnection($this->db); $controller->setInput($this->input);
$controller->setModelPath($this->modelPath); $controller->setModelNamespace($this->modelNamespace);
$controller->setInput($this->input); $controller->setControllerPath($this->controllerPath);
$controller->setModelNamespace($this->modelNamespace); $controller->setModule($this->input->getArgument('module'));
$controller->setControllerPath($this->controllerPath); $controller->setControllerNamespace($this->controllerNamespace);
$controller->setModule($this->input->getArgument('module')); return $controller->generate();
$controller->setControllerNamespace($this->controllerNamespace); }
return $controller->generate();
} /**
* @return array|string|null
/** * @throws Exception
* @return array|string|null */
* @throws Exception private function getTables(): array|string|null
*/ {
private function getTables(): array|string|null if (empty($this->tableName)) {
{ return $this->showAll();
if (empty($this->tableName)) { }
return $this->showAll(); $res = $this->tableName;
} if (is_string($res)) {
$res = $this->tableName; $res = explode(',', $this->tableName);
if (is_string($res)) { }
$res = explode(',', $this->tableName); if (empty($res)) {
} return [];
if (empty($res)) { }
return []; return $res;
} }
return $res;
} /**
* @return array
/** * @throws Exception
* @return array */
* @throws Exception private function showAll(): array
*/ {
private function showAll(): array $res = [];
{ $_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db);
$res = []; if (empty($_tables)) {
$_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db); return $res;
if (empty($_tables)) { }
return $res; foreach ($_tables as $key => $val) {
} $res[] = array_shift($val);
foreach ($_tables as $key => $val) { }
$res[] = array_shift($val); return $res;
} }
return $res;
} /**
* @param $table
/** * @return bool|int|null
* @param $table * @throws Exception
* @return bool|int|null */
* @throws Exception private function getIndex($table): bool|int|null
*/ {
private function getIndex($table): bool|int|null $data = Db::findAllBySql('SHOW INDEX FROM ' . $table, [], $this->db);
{
$data = Db::findAllBySql('SHOW INDEX FROM ' . $table, [], $this->db); return empty($data) ? NULL : $data[0];
}
return empty($data) ? NULL : $data[0];
} /**
* @param $tables
/** *
* @param $tables * @return array
* * @throws
* @return array */
* @throws private function getFields($tables): array
*/ {
private function getFields($tables): array $res = [];
{ if (!is_array($tables)) {
$res = []; $tables = [$tables];
if (!is_array($tables)) { }
$tables = [$tables]; foreach ($tables as $key => $val) {
} if (empty($val)) continue;
foreach ($tables as $key => $val) { $_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db);
if (empty($val)) continue; if (empty($_tmp)) {
$_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db); continue;
if (empty($_tmp)) { }
continue; $res[$val] = $_tmp;
} }
$res[$val] = $_tmp; return $res;
} }
return $res;
} /**
* @param $tableName
/** * @param $tables
* @param $tableName *
* @param $tables * @return array
* * @throws Exception
* @return array */
* @throws Exception public function createModelFile($tableName, $tables): array
*/ {
public function createModelFile($tableName, $tables): array $res = $visible = $fields = $keys = [];
{ foreach ($tables as $_key => $_val) {
$res = $visible = $fields = $keys = []; $keys = $tableName;
foreach ($tables as $_key => $_val) { if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') {
$keys = $tableName; $keys = $tableName;
if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') { }
$keys = $tableName; if (!isset($keys) && !($index = $this->getIndex($tableName))) {
} $keys = $index['Column_name'];
if (!isset($keys) && !($index = $this->getIndex($tableName))) { }
$keys = $index['Column_name']; if (in_array(strtoupper($_val['Field']), $this->keyword)) {
} throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"');
if (in_array(strtoupper($_val['Field']), $this->keyword)) { }
throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"'); array_push($visible, $this->createVisible($_val['Field']));
} array_push($fields, $_val);
array_push($visible, $this->createVisible($_val['Field'])); $res[] = $this->createSetFunc($_val['Field'], $_val['Comment']);
array_push($fields, $_val); }
$res[] = $this->createSetFunc($_val['Field'], $_val['Comment']);
} $classFileName = $this->getClassName($tableName);
$classFileName = $this->getClassName($tableName); return [
'classFileName' => $classFileName,
return [ 'tableName' => $keys,
'classFileName' => $classFileName, 'visible' => $visible,
'tableName' => $keys, 'fields' => $fields,
'visible' => $visible, 'res' => $res,
'fields' => $fields, ];
'res' => $res, }
];
} /**
* @param $field
/** * @return string
* @param $field * 创建变量注释
* @return string */
* 创建变量注释 private function createVisible($field): string
*/ {
private function createVisible($field): string return '
{ * @property $' . $field;
return ' }
* @property $' . $field;
} /**
* @param $field
/** * @param $comment
* @param $field * @return string
* @param $comment * 暂时不知道干嘛用的
* @return string */
* 暂时不知道干嘛用的 private function createSetFunc($field, $comment): string
*/ {
private function createSetFunc($field, $comment): string return '
{ ' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
return ' }
' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
} /**
* @param $tableName
/** * @return string
* @param $tableName * 构建类名称
* @return string */
* 构建类名称 private function getClassName($tableName): string
*/ {
private function getClassName($tableName): string $res = [];
{ $tableName = str_replace($this->db->tablePrefix,'', $tableName);
$res = []; foreach (explode('_', $tableName) as $n => $val) {
foreach (explode('_', $tableName) as $n => $val) { $res[] = ucfirst($val);
$res[] = ucfirst($val); }
} return implode('', $res);
return implode('', $res); }
}
}
}
+411 -411
View File
@@ -1,411 +1,411 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Database\Connection; use Database\Connection;
use Exception; use Exception;
use Kiri\Core\Json; use Kiri\Core\Json;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
/** /**
* Class GiiBase * Class GiiBase
* @package Gii * @package Gii
*/ */
abstract class GiiBase abstract class GiiBase
{ {
public array $fileList = []; public array $fileList = [];
protected InputInterface $input; protected InputInterface $input;
public string $modelPath = APP_PATH . 'app/Model/'; public string $modelPath = APP_PATH . 'app/Model/';
public string $modelNamespace = 'App\Model\\'; public string $modelNamespace = 'App\Model\\';
public string $controllerPath = APP_PATH . 'app/Http/Controller/'; public string $controllerPath = APP_PATH . 'app/Http/Controller/';
public string $controllerNamespace = 'App\\Controller\\'; public string $controllerNamespace = 'App\\Controller\\';
public ?string $module = null; public ?string $module = null;
public array $rules = []; public array $rules = [];
public array $type = [ public array $type = [
'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'], 'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'],
'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'], 'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'],
'date' => ['date'], 'date' => ['date'],
'time' => ['time'], 'time' => ['time'],
'year' => ['year'], 'year' => ['year'],
'datetime' => ['datetime'], 'datetime' => ['datetime'],
'timestamp' => ['timestamp'], 'timestamp' => ['timestamp'],
'float' => ['float', 'double', 'decimal',], 'float' => ['float', 'double', 'decimal',],
]; ];
public ?string $tableName = NULL; public ?string $tableName = NULL;
public ?Connection $db = null; public ?Connection $db = null;
/** /**
* @param string $modelPath * @param string $modelPath
*/ */
public function setModelPath(string $modelPath): void public function setModelPath(string $modelPath): void
{ {
$this->modelPath = $modelPath; $this->modelPath = $modelPath;
} }
/** /**
* @param string $modelNamespace * @param string $modelNamespace
*/ */
public function setModelNamespace(string $modelNamespace): void public function setModelNamespace(string $modelNamespace): void
{ {
$this->modelNamespace = $modelNamespace; $this->modelNamespace = $modelNamespace;
} }
/** /**
* @param string $controllerPath * @param string $controllerPath
*/ */
public function setControllerPath(string $controllerPath): void public function setControllerPath(string $controllerPath): void
{ {
$this->controllerPath = $controllerPath; $this->controllerPath = $controllerPath;
} }
/** /**
* @param $module * @param $module
*/ */
public function setModule($module) public function setModule($module)
{ {
$this->module = $module; $this->module = $module;
} }
/** /**
* @param string $controllerNamespace * @param string $controllerNamespace
*/ */
public function setControllerNamespace(string $controllerNamespace): void public function setControllerNamespace(string $controllerNamespace): void
{ {
$this->controllerNamespace = $controllerNamespace; $this->controllerNamespace = $controllerNamespace;
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
*/ */
public function setInput(InputInterface $input) public function setInput(InputInterface $input)
{ {
$this->input = $input; $this->input = $input;
} }
/** /**
* @param ReflectionClass $object * @param ReflectionClass $object
* @param $className * @param $className
* *
* @return string * @return string
*/ */
public function getUseContent(ReflectionClass $object, $className): string public function getUseContent(ReflectionClass $object, $className): string
{ {
if (empty($object)) { if (empty($object)) {
return ''; return '';
} }
$file = $this->getFilePath($className); $file = $this->getFilePath($className);
if (!file_exists($file)) { if (!file_exists($file)) {
return ''; return '';
} }
$content = file_get_contents($file); $content = file_get_contents($file);
$explode = explode(PHP_EOL, $content); $explode = explode(PHP_EOL, $content);
$exists = array_slice($explode, 0, $object->getStartLine()); $exists = array_slice($explode, 0, $object->getStartLine());
$_tmp = []; $_tmp = [];
foreach ($exists as $key => $val) { foreach ($exists as $key => $val) {
if (trim($val) == '/**') { if (trim($val) == '/**') {
break; break;
} }
$_tmp[] = $val; $_tmp[] = $val;
} }
return trim(implode(PHP_EOL, $_tmp)); return trim(implode(PHP_EOL, $_tmp));
} }
/** /**
* @param string $fileName * @param string $fileName
* @param ReflectionClass $class * @param ReflectionClass $class
* @return string * @return string
*/ */
protected function getImports(string $fileName, ReflectionClass $class): string protected function getImports(string $fileName, ReflectionClass $class): string
{ {
$startLine = 1; $startLine = 1;
$array = []; $array = [];
$fileOpen = fopen($fileName, 'r'); $fileOpen = fopen($fileName, 'r');
while (($content = fgets($fileOpen)) !== false) { while (($content = fgets($fileOpen)) !== false) {
if (str_starts_with($content, 'use ')) { if (str_starts_with($content, 'use ')) {
$array[] = $content; $array[] = $content;
} }
if ($startLine == $class->getStartLine()) { if ($startLine == $class->getStartLine()) {
break; break;
} }
++$startLine; ++$startLine;
} }
return implode($array); return implode($array);
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @return string * @return string
* @throws ReflectionException * @throws ReflectionException
*/ */
protected function getClassProperty(ReflectionClass $class): string protected function getClassProperty(ReflectionClass $class): string
{ {
$html = ''; $html = '';
$rc = $class->getParentClass()->getConstants(); $rc = $class->getParentClass()->getConstants();
foreach ($class->getConstants() as $key => $val) { foreach ($class->getConstants() as $key => $val) {
if (isset($rc[$key])) { if (isset($rc[$key])) {
continue; continue;
} }
if (is_numeric($val)) { if (is_numeric($val)) {
$html .= ' $html .= '
const ' . $key . ' = ' . $val . ';' . "\n"; const ' . $key . ' = ' . $val . ';' . "\n";
} else { } else {
$html .= ' $html .= '
const ' . $key . ' = \'' . $val . '\';' . "\n"; const ' . $key . ' = \'' . $val . '\';' . "\n";
} }
} }
foreach ($class->getDefaultProperties() as $key => $val) { foreach ($class->getDefaultProperties() as $key => $val) {
$property = $class->getProperty($key); $property = $class->getProperty($key);
if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') { if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') {
continue; continue;
} }
if ($property->class != $class->getName()) continue; if ($property->class != $class->getName()) continue;
if (is_array($val)) { if (is_array($val)) {
$val = '[\'' . implode('\', \'', $val) . '\']'; $val = '[\'' . implode('\', \'', $val) . '\']';
} else if (!is_numeric($val)) { } else if (!is_numeric($val)) {
$val = '\'' . $val . '\''; $val = '\'' . $val . '\'';
} }
if ($property->isProtected()) { if ($property->isProtected()) {
$debug = 'protected'; $debug = 'protected';
} else if ($property->isPrivate()) { } else if ($property->isPrivate()) {
$debug = 'private'; $debug = 'private';
} else { } else {
$debug = 'public'; $debug = 'public';
} }
if ($property->hasType()) { if ($property->hasType()) {
$type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n"; $type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n";
} else { } else {
$type = ' $' . $key . ' = ' . $val . ';' . "\n"; $type = ' $' . $key . ' = ' . $val . ';' . "\n";
} }
if ($property->isStatic()) { if ($property->isStatic()) {
$html .= ' $html .= '
' . $debug . ' static' . $type; ' . $debug . ' static' . $type;
} else { } else {
$html .= ' $html .= '
' . $debug . $type; ' . $debug . $type;
} }
} }
return $html; return $html;
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @param array $filters * @param array $filters
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
protected function getClassMethods(ReflectionClass $class, array $filters = []): string protected function getClassMethods(ReflectionClass $class, array $filters = []): string
{ {
$methods = $class->getMethods(); $methods = $class->getMethods();
$classFileName = str_replace(APP_PATH, '', $class->getFileName()); $classFileName = str_replace(APP_PATH, '', $class->getFileName());
$content = []; $content = [];
if (!empty($methods)) foreach ($methods as $key => $val) { if (!empty($methods)) foreach ($methods as $key => $val) {
if ($val->class != $class->getName()) continue; if ($val->class != $class->getName()) continue;
if (in_array($val->name, $filters)) continue; if (in_array($val->name, $filters)) continue;
$over = " $over = "
" . $val->getDocComment() . "\n"; " . $val->getDocComment() . "\n";
$attributes = $val->getAttributes(); $attributes = $val->getAttributes();
if (!empty($attributes)) { if (!empty($attributes)) {
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
$explode = explode('\\', $attribute->getName()); $explode = explode('\\', $attribute->getName());
$_array = []; $_array = [];
foreach ($attribute->getArguments() as $_key => $argument) { foreach ($attribute->getArguments() as $_key => $argument) {
$argument = $this->resolveArray($argument); $argument = $this->resolveArray($argument);
if (is_numeric($_key)) { if (is_numeric($_key)) {
$_array[] = $argument; $_array[] = $argument;
} else { } else {
$_array[] = $_key . ': ' . $argument . ''; $_array[] = $_key . ': ' . $argument . '';
} }
} }
if (empty($_array)) { if (empty($_array)) {
$end = " #[" . end($explode) . "] $end = " #[" . end($explode) . "]
"; ";
} else { } else {
$end = " #[" . end($explode) . "(" . implode(',', $_array) . ")] $end = " #[" . end($explode) . "(" . implode(',', $_array) . ")]
"; ";
} }
if (str_contains($over, $end)) { if (str_contains($over, $end)) {
$over = str_replace($end, '', $over); $over = str_replace($end, '', $over);
} }
$over .= $end; $over .= $end;
} }
} }
$func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n"; $func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n";
$content[] = $over . $func; $content[] = $over . $func;
} }
return implode(PHP_EOL, $content); return implode(PHP_EOL, $content);
} }
/** /**
* @param $argument * @param $argument
* @return string * @return string
*/ */
private function resolveArray($argument): string private function resolveArray($argument): string
{ {
if (is_array($argument)) { if (is_array($argument)) {
$__array = []; $__array = [];
foreach ($argument as $key => $value) { foreach ($argument as $key => $value) {
if (is_string($value)) { if (is_string($value)) {
if (str_contains($value, '\\') && class_exists($value)) { if (str_contains($value, '\\') && class_exists($value)) {
$explode_class = explode('\\', $value); $explode_class = explode('\\', $value);
$__array[] = end($explode_class) . '::class'; $__array[] = end($explode_class) . '::class';
} else { } else {
$__array[] = '\'' . $value . '\''; $__array[] = '\'' . $value . '\'';
} }
} else { } else {
$value = str_replace('{', '[', Json::encode($value)); $value = str_replace('{', '[', Json::encode($value));
$value = str_replace('}', ']', Json::encode($value)); $value = str_replace('}', ']', Json::encode($value));
$value = str_replace(':', '=>', Json::encode($value)); $value = str_replace(':', '=>', Json::encode($value));
$value = preg_replace('/"\d+"\=\>/', '', $value); $value = preg_replace('/"\d+"\=\>/', '', $value);
$__array[] = $value; $__array[] = $value;
} }
} }
$argument = '[' . implode(', ', $__array) . ']'; $argument = '[' . implode(', ', $__array) . ']';
} else { } else {
$argument = '\'' . $argument . '\''; $argument = '\'' . $argument . '\'';
} }
return $argument; return $argument;
} }
/** /**
* @param $fields * @param $fields
* @return mixed 返回表主键 * @return mixed 返回表主键
* 返回表主键 * 返回表主键
*/ */
public function getPrimaryKey($fields): mixed public function getPrimaryKey($fields): mixed
{ {
$condition = ['PRI', 'UNI']; $condition = ['PRI', 'UNI'];
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field['Extra'] == 'auto_increment') { if ($field['Extra'] == 'auto_increment') {
return $field['Field']; return $field['Field'];
} }
if (in_array($field['Key'], $condition)) { if (in_array($field['Key'], $condition)) {
return $field['Field']; return $field['Field'];
} }
} }
return null; return null;
} }
/** /**
* @param $className * @param $className
* @return string * @return string
*/ */
private function getFilePath($className): string private function getFilePath($className): string
{ {
if (strpos($className, '\\')) { if (strpos($className, '\\')) {
$className = str_replace('\\', '/', $className); $className = str_replace('\\', '/', $className);
} }
if (strpos($className, '\\')) { if (strpos($className, '\\')) {
$className = str_replace('\\', '/', $className); $className = str_replace('\\', '/', $className);
} }
return APP_PATH . $className; return APP_PATH . $className;
} }
/** /**
* @param ReflectionClass $object * @param ReflectionClass $object
* @param $className * @param $className
* @param $method * @param $method
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public function getFuncLineContent(ReflectionClass $object, $className, $method): string public function getFuncLineContent(ReflectionClass $object, $className, $method): string
{ {
$fun = $object->getMethod($method); $fun = $object->getMethod($method);
$content = file_get_contents($this->getFilePath($className)); $content = file_get_contents($this->getFilePath($className));
$explode = explode(PHP_EOL, $content); $explode = explode(PHP_EOL, $content);
$exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1); $exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1);
return implode(PHP_EOL, $exists); return implode(PHP_EOL, $exists);
} }
/** /**
* @return array * @return array
*/ */
protected function getModelPath(): array protected function getModelPath(): array
{ {
$dbName = $this->db->id; $dbName = $this->db->id;
if (empty($dbName) || $dbName == 'db') { if (empty($dbName) || $dbName == 'db') {
$dbName = ''; $dbName = '';
} }
$modelPath = [ $modelPath = [
'namespace' => $this->modelNamespace, 'namespace' => $this->modelNamespace,
'path' => $this->modelPath, 'path' => $this->modelPath,
]; ];
if (!is_dir($modelPath['path'])) { if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']); mkdir($modelPath['path']);
} }
if (!empty($dbName)) { if (!empty($dbName)) {
$modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName); $modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName);
$modelPath['path'] = $this->modelPath . ucfirst($dbName); $modelPath['path'] = $this->modelPath . ucfirst($dbName);
} }
if (!is_dir($modelPath['path'])) { if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']); mkdir($modelPath['path']);
} }
return $modelPath; return $modelPath;
} }
/** /**
* @param $db * @param $db
*/ */
public function setConnection($db) public function setConnection($db)
{ {
$this->db = $db; $this->db = $db;
} }
/** /**
* @param $val * @param $val
* @return string * @return string
*/ */
protected function checkIsRequired($val): string protected function checkIsRequired($val): string
{ {
return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false'; return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false';
} }
/** /**
* @return array * @return array
*/ */
public function getFileLists(): array public function getFileLists(): array
{ {
return $this->fileList; return $this->fileList;
} }
} }
+76 -76
View File
@@ -1,76 +1,76 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Exception; use Exception;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri\Kiri;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
/** /**
* Class Command * Class Command
* @package Http * @package Http
*/ */
class GiiCommand extends Command class GiiCommand extends Command
{ {
public string $command = 'sw:gii'; public string $command = 'sw:gii';
public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx'; public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx';
/** /**
* *
*/ */
protected function configure() protected function configure()
{ {
$this->setName('sw:gii') $this->setName('sw:gii')
->addArgument('action', InputArgument::REQUIRED) ->addOption('make','m', InputArgument::OPTIONAL)
->addArgument('name', InputArgument::OPTIONAL) ->addOption('name','t', InputArgument::OPTIONAL)
->addArgument('databases', InputArgument::OPTIONAL) ->addOption('databases','d', InputArgument::OPTIONAL)
->setDescription('./snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx'); ->setDescription('./snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx');
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
* @param OutputInterface $output * @param OutputInterface $output
* @return int * @return int
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function execute(InputInterface $input, OutputInterface $output): int public function execute(InputInterface $input, OutputInterface $output): int
{ {
/** @var Gii $gii */ /** @var Gii $gii */
$gii = Kiri::app()->get('gii'); $gii = Kiri::app()->get('gii');
$connections = Kiri::app()->get('db'); $connections = Kiri::app()->get('db');
if (($db = $input->getArgument('databases')) != null) { if (($db = $input->getOption('databases')) != null) {
$gii->run($connections->get($db), $input); $gii->run($connections->get($db), $input);
return 1; return 1;
} }
$action = $input->getArgument('action'); $action = $input->getOption('make');
if (!in_array($action, ['model', 'controller'])) { if (!in_array($action, ['model', 'controller'])) {
$gii->run(null, $input); $gii->run(null, $input);
return 1; return 1;
} }
$array = []; $array = [];
foreach (Config::get('databases.connections') as $key => $connection) { foreach (Config::get('databases.connections') as $key => $connection) {
$array[$key] = $gii->run($connections->get($key), $input); $array[$key] = $gii->run($connections->get($key), $input);
} }
$output->writeln(json_encode($array, JSON_UNESCAPED_UNICODE)); $output->writeln(json_encode($array, JSON_UNESCAPED_UNICODE));
return 1; return 1;
} }
} }
+536 -539
View File
File diff suppressed because it is too large Load Diff

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