Compare commits

...

63 Commits

Author SHA1 Message Date
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
132 changed files with 12713 additions and 13210 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 -1207
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\Component; 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 Component 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 -461
View File
@@ -1,461 +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 Server\Tasker\AsyncTaskExecute; {
use Swoole\Table;
use TraitApplication;
/**
* Class BaseApplication
* @package Kiri\Kiri\Base /**
*/ * @var string
abstract class BaseApplication extends Component */
{ public string $storage = APP_PATH . 'storage';
use TraitApplication; public string $envPath = APP_PATH . '.env';
/**
/** * Init constructor.
* @var string *
*/ *
public string $storage = APP_PATH . 'storage'; * @throws
*/
public string $envPath = APP_PATH . '.env'; public function __construct()
{
/** Kiri::init($this);
* Init constructor.
* $config = sweep(APP_PATH . '/config');
*
* @throws $this->moreComponents();
*/ $this->parseInt($config);
public function __construct() $this->parseEvents($config);
{ $this->initErrorHandler();
Kiri::init($this); $this->enableEnvConfig();
$this->mapping($config['mapping'] ?? []);
$config = sweep(APP_PATH . '/config');
parent::__construct();
$this->moreComponents(); }
$this->parseInt($config);
$this->parseEvents($config);
$this->initErrorHandler(); /**
$this->enableEnvConfig(); * @param array $mapping
$this->mapping($config['mapping'] ?? []); */
public function mapping(array $mapping)
parent::__construct(); {
} $di = Kiri::getDi();
foreach ($mapping as $interface => $class) {
$di->mapping($interface, $class);
/** }
* @param array $mapping }
*/
public function mapping(array $mapping)
{ /**
$di = Kiri::getDi(); * @return array
foreach ($mapping as $interface => $class) { */
$di->mapping($interface, $class); public function enableEnvConfig(): array
} {
} if (!file_exists($this->envPath)) {
return [];
}
/** $lines = $this->readLinesFromFile($this->envPath);
* @return array foreach ($lines as $line) {
*/ if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
public function enableEnvConfig(): array [$key, $value] = explode('=', $line);
{ putenv(trim($key) . '=' . trim($value));
if (!file_exists($this->envPath)) { }
return []; }
} return $lines;
$lines = $this->readLinesFromFile($this->envPath); }
foreach ($lines as $line) {
if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
[$key, $value] = explode('=', $line); /**
putenv(trim($key) . '=' . trim($value)); * Read lines from the file, auto detecting line endings.
} *
} * @param string $filePath
return $lines; *
} * @return array
*/
protected function readLinesFromFile(string $filePath): array
/** {
* Read lines from the file, auto detecting line endings. // Read file into an array of lines with auto-detected line endings
* $autodetect = ini_get('auto_detect_line_endings');
* @param string $filePath ini_set('auto_detect_line_endings', '1');
* $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
* @return array ini_set('auto_detect_line_endings', $autodetect);
*/
protected function readLinesFromFile(string $filePath): array return $lines;
{ }
// Read file into an array of lines with auto-detected line endings
$autodetect = ini_get('auto_detect_line_endings'); /**
ini_set('auto_detect_line_endings', '1'); * Determine if the line in the file is a comment, e.g. begins with a #.
$lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); *
ini_set('auto_detect_line_endings', $autodetect); * @param string $line
*
return $lines; * @return bool
} */
protected function isComment(string $line): bool
/** {
* Determine if the line in the file is a comment, e.g. begins with a #. $line = ltrim($line);
*
* @param string $line return isset($line[0]) && $line[0] === '#';
* }
* @return bool
*/ /**
protected function isComment(string $line): bool * Determine if the given line looks like it's setting a variable.
{ *
$line = ltrim($line); * @param string $line
*
return isset($line[0]) && $line[0] === '#'; * @return bool
} */
protected function looksLikeSetter(string $line): bool
/** {
* Determine if the given line looks like it's setting a variable. return str_contains($line, '=');
* }
* @param string $line
*
* @return bool /**
*/ * @param $config
protected function looksLikeSetter(string $line): bool *
{ * @throws
return str_contains($line, '='); */
} public function parseInt($config)
{
Config::sets($config);
/** if ($storage = Config::get('storage', 'storage')) {
* @param $config if (!str_contains($storage, APP_PATH)) {
* $storage = APP_PATH . $storage . '/';
* @throws }
*/ if (!is_dir($storage)) {
public function parseInt($config) mkdir($storage);
{ }
Config::sets($config); if (!is_dir($storage) || !is_writeable($storage)) {
if ($storage = Config::get('storage', 'storage')) { throw new InitException("Directory {$storage} does not have write permission");
if (!str_contains($storage, APP_PATH)) { }
$storage = APP_PATH . $storage . '/'; }
} }
if (!is_dir($storage)) {
mkdir($storage);
} /**
if (!is_dir($storage) || !is_writeable($storage)) { * @param $name
throw new InitException("Directory {$storage} does not have write permission"); * @return mixed
} * @throws ReflectionException
} * @throws NotFindClassException
} * @throws Exception
*/
public function __get($name): mixed
/** {
* @param $name if ($this->has($name)) {
* @return mixed return $this->get($name);
* @throws ReflectionException }
* @throws NotFindClassException return parent::__get($name); // TODO: Change the autogenerated stub
* @throws Exception }
*/
public function __get($name): mixed
{ /**
if ($this->has($name)) { * @param $config
return $this->get($name); *
} * @throws
return parent::__get($name); // TODO: Change the autogenerated stub */
} public function parseEvents($config)
{
if (!isset($config['events']) || !is_array($config['events'])) {
/** return;
* @param $config }
* foreach ($config['events'] as $key => $value) {
* @throws if (is_string($value)) {
*/ $value = Kiri::createObject($value);
public function parseEvents($config) }
{ $this->addEvent($key, $value);
if (!isset($config['events']) || !is_array($config['events'])) { }
return; }
}
foreach ($config['events'] as $key => $value) {
if (is_string($value)) { /**
$value = Kiri::createObject($value); * @param OnTaskInterface $execute
} * @throws ReflectionException
$this->addEvent($key, $value); */
} public function task(OnTaskInterface $execute): void
} {
di(AsyncTaskExecute::class)->execute($execute);
}
/**
* @param OnTaskInterface $execute
* @throws ReflectionException /**
*/ * @param $key
public function task(OnTaskInterface $execute): void * @param $value
{ * @throws InitException
di(AsyncTaskExecute::class)->execute($execute); * @throws Exception
} */
private function addEvent($key, $value): void
{
/** if ($value instanceof \Closure || is_object($value)) {
* @param $key $this->eventProvider->on($key, $value, 0);
* @param $value return;
* @throws InitException }
* @throws Exception
*/
private function addEvent($key, $value): void if (is_array($value)) {
{ if (is_object($value[0]) && !($value[0] instanceof \Closure)) {
$eventProvider = di(EventProvider::class); $this->eventProvider->on($key, $value, 0);
if ($value instanceof \Closure || is_object($value)) { return;
$eventProvider->on($key, $value, 0); }
return;
} if (is_string($value[0])) {
$value[0] = Kiri::createObject($value[0]);
$this->eventProvider->on($key, $value, 0);
if (is_array($value)) { return;
if (is_object($value[0]) && !($value[0] instanceof \Closure)) { }
$eventProvider->on($key, $value, 0);
return;
} foreach ($value as $item) {
if (!is_callable($item, true)) {
if (is_string($value[0])) { throw new InitException("Class does not hav callback.");
$value[0] = Kiri::createObject($value[0]); }
$eventProvider->on($key, $value, 0); $this->eventProvider->on($key, $item, 0);
return; }
} }
}
foreach ($value as $item) {
if (!is_callable($item, true)) {
throw new InitException("Class does not hav callback."); /**
} * @param $name
$eventProvider->on($key, $item, 0); * @return mixed
} * @throws Exception
} */
public function clone($name): mixed
} {
return clone $this->get($name);
}
/**
* @param $name /**
* @return mixed *
* @throws Exception * @throws Exception
*/ */
public function clone($name): mixed public function initErrorHandler()
{ {
return clone $this->get($name); $this->get('error')->register();
} }
/**
* /**
* @throws Exception * @param $name
*/ * @return mixed
public function initErrorHandler() * @throws
{ */
$this->get('error')->register(); public function get($name): mixed
} {
return di(LocalService::class)->get($name);
}
/**
* @param $name
* @return mixed /**
* @throws * @return mixed
*/ */
public function get($name): mixed public function getLocalIps(): mixed
{ {
return di(LocalService::class)->get($name); return swoole_get_local_ip();
} }
/**
/** * @return mixed
* @return mixed */
*/ public function getFirstLocal(): mixed
public function getLocalIps(): mixed {
{ return current($this->getLocalIps());
return swoole_get_local_ip(); }
}
/** /**
* @return mixed * @return Logger
*/ * @throws
public function getFirstLocal(): mixed */
{ public function getLogger(): Logger
return current($this->getLocalIps()); {
} return $this->get('logger');
}
/**
* @return Logger /**
* @throws * @return \Redis|Redis
*/ * @throws
public function getLogger(): Logger */
{ public function getRedis(): Redis|\Redis
return $this->get('logger'); {
} return Kiri::getDi()->get(Redis::class);
}
/** /**
* @return \Redis|Redis * @param $ip
* @throws * @return bool
*/ */
public function getRedis(): Redis|\Redis public function isLocal($ip): bool
{ {
return Kiri::getDi()->get(Redis::class); return $this->getFirstLocal() == $ip;
} }
/**
* @param $ip /**
* @return bool * @return ErrorHandler
*/ * @throws
public function isLocal($ip): bool */
{ public function getError(): ErrorHandler
return $this->getFirstLocal() == $ip; {
} return $this->get('error');
}
/**
* @return ErrorHandler /**
* @throws * @param $name
*/ * @return Table
public function getError(): ErrorHandler * @throws
{ */
return $this->get('error'); public function getTable($name): Table
} {
return $this->get($name);
}
/**
* @param $name
* @return Table /**
* @throws * @return Config
*/ * @throws
public function getTable($name): Table */
{ public function getConfig(): Config
return $this->get($name); {
} return $this->get('config');
}
/**
* @return Config /**
* @throws * @return Router
*/ * @throws
public function getConfig(): Config */
{ public function getRouter(): Router
return $this->get('config'); {
} return Kiri::getDi()->get(Router::class);
}
/**
* @return Router /**
* @throws * @return Server
*/ * @throws
public function getRouter(): Router */
{ public function getServer(): Server
return Kiri::getDi()->get(Router::class); {
} return $this->get('server');
}
/**
* @return Server /**
* @throws * @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
*/ * @throws
public function getServer(): Server */
{ public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
return $this->get('server'); {
} return di(ServerManager::class)->getServer();
}
/**
* @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null /**
* @throws * @return SAnnotation
*/ * @throws
public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null */
{ public function getAnnotation(): SAnnotation
return di(ServerManager::class)->getServer(); {
} return $this->get('Annotation');
}
/**
* @return SNote /**
* @throws * @return Async
*/ * @throws
public function getNote(): SNote */
{ public function getAsync(): Async
return $this->get('note'); {
} 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 $id
* @param $array * @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 $id
* @param $definition * @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 * @throws Exception
* @return bool */
*/ protected function moreComponents(): void
public function has($id): bool {
{ $this->setComponents([
return di(LocalService::class)->has($id); 'error' => ['class' => ErrorHandler::class],
} 'config' => ['class' => Config::class],
'logger' => ['class' => Logger::class],
'Annotation' => ['class' => SAnnotation::class],
/** 'databases' => ['class' => Connection::class],
* @throws Exception 'jwt' => ['class' => Jwt::class],
*/ 'async' => ['class' => Async::class],
protected function moreComponents(): void '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);
} }
} }
+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 -244
View File
@@ -1,244 +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\Di\Container;
use Kiri\Kiri; use Kiri\Events\EventDispatch;
use Psr\Container\ContainerInterface; 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;
* @property ContainerInterface|Container $container
*/ /**
class Component implements Configure * Class Component
{ * @package Kiri\Kiri\Base
* @property ContainerInterface|Container $container
/** * @property EventProvider $eventProvider
* BaseAbstract constructor. * @property EventDispatch $eventDispatch
* */
* @param array $config class Component implements Configure
* @throws Exception {
*/
public function __construct(array $config = [])
{ /**
if (!empty($config) && is_array($config)) { * BaseAbstract constructor.
Kiri::configure($this, $config); *
} * @param array $config
} * @throws Exception
*/
public function __construct(array $config = [])
/** {
* @throws Exception if (!empty($config) && is_array($config)) {
*/ Kiri::configure($this, $config);
public function init() }
{ }
}
/**
/** * @return Container|ContainerInterface
* @return Container */
*/ #[Pure] public function getContainer(): ContainerInterface|Container
#[Pure] public function getContainer(): ContainerInterface {
{ return Kiri::getDi();
return Kiri::getDi(); }
}
/**
/** * @return EventProvider
* @return string * @throws ContainerExceptionInterface
*/ * @throws NotFoundExceptionInterface
#[Pure] public static function className(): string */
{ public function getEventProvider(): EventProvider
return static::class; {
} return $this->getContainer()->get(EventProvider::class);
}
/**
* @param $name
* @param $value /**
* * @return EventDispatch
* @throws Exception */
*/ protected function getEventDispatch(): EventDispatch
public function __set($name, $value) {
{ return Kiri::getDi()->get(EventDispatch::class);
$method = 'set' . ucfirst($name); }
if (method_exists($this, $method)) {
$this->{$method}($value); /**
} else { * @throws Exception
throw new Exception('The set name ' . $name . ' not find in class ' . static::class); */
} public function init()
} {
}
/**
* @param $name
* /**
* @return mixed * @return string
* @throws Exception */
*/ #[Pure] public static function className(): string
public function __get($name): mixed {
{ return static::class;
$method = 'get' . ucfirst($name); }
if (method_exists($this, $method)) {
return $this->$method(); /**
} else { * @param $name
throw new Exception('The get name ' . $name . ' not find in class ' . static::class); * @param $value
} *
} * @throws Exception
*/
public function __set($name, $value)
/** {
* @param $message $method = 'set' . ucfirst($name);
* @param string $model if (method_exists($this, $method)) {
* @return bool $this->{$method}($value);
* @throws Exception } else {
*/ throw new Exception('The set name ' . $name . ' not find in class ' . static::class);
public function addError($message, string $model = 'app'): bool }
{ }
if ($message instanceof \Throwable) {
$this->error(jTraceEx($message)); /**
} else { * @param $name
if (!is_string($message)) { *
$message = json_encode($message, JSON_UNESCAPED_UNICODE); * @return mixed
} * @throws Exception
$this->error($message); */
} public function __get($name): mixed
return FALSE; {
} $method = 'get' . ucfirst($name);
if (method_exists($this, $method)) {
return $this->$method();
/** } else {
* @return Logger throw new Exception('The get name ' . $name . ' not find in class ' . static::class);
* @throws Exception }
*/ }
private function logger(): Logger
{
return Kiri::getDi()->get(Logger::class); /**
} * @param $message
* @param string $model
* @return bool
/** * @throws Exception
* @param mixed $message */
* @param string $method public function addError($message, string $model = 'app'): bool
* @param string $file {
* @throws Exception if ($message instanceof \Throwable) {
*/ $this->error($message = jTraceEx($message));
public function debug(mixed $message, string $method = '', string $file = '') } else {
{ if (!is_string($message)) {
if (!is_string($message)) { $message = json_encode($message, JSON_UNESCAPED_UNICODE);
$message = print_r($message, true); }
} $this->error($message);
// $message = "\033[35m" . $message . "\033[0m"; }
Kiri::app()->getLogger()->fail($message, $model);
$context = []; return FALSE;
if (!empty($method)) $context['method'] = $method; }
if (!empty($file)) $context['file'] = $file;
$this->logger()->debug($message, $context); /**
} * @return Logger
* @throws Exception
*/
/** private function logger(): Logger
* @param mixed $message {
* @param string $method return Kiri::getDi()->get(Logger::class);
* @param string $file }
* @throws Exception
*/
public function info(mixed $message, string $method = '', string $file = '') /**
{ * @param mixed $message
if (!is_string($message)) { * @param string $method
$message = print_r($message, true); * @param string $file
} * @throws Exception
// $message = "\033[34m" . $message . "\033[0m"; */
public function debug(mixed $message, string $method = '', string $file = '')
$context = []; {
if (!empty($method)) $context['method'] = $method; if (!is_string($message)) {
if (!empty($file)) $context['file'] = $file; $message = print_r($message, true);
}
$this->logger()->info($message, $context); $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 /**
*/ * @param mixed $message
public function success(mixed $message, string $method = '', string $file = '') * @param string $method
{ * @param string $file
if (!is_string($message)) { * @throws Exception
$message = print_r($message, true); */
} public function info(mixed $message, string $method = '', string $file = '')
{
// $message = "\033[36m" . $message . "\033[0m"; if (!is_string($message)) {
$message = print_r($message, true);
$context = []; }
if (!empty($method)) $context['method'] = $method; $context = [];
if (!empty($file)) $context['file'] = $file; if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file;
$this->logger()->notice($message, $context);
} $this->logger()->info($message, $context);
}
/**
* @param mixed $message /**
* @param string $method * @param mixed $message
* @param string $file * @param string $method
* @throws Exception * @param string $file
*/ * @throws Exception
public function warning(mixed $message, string $method = '', string $file = '') */
{ public function success(mixed $message, string $method = '', string $file = '')
if (!is_string($message)) { {
$message = print_r($message, true); if (!is_string($message)) {
} $message = print_r($message, true);
}
// $message = "\033[33m" . $message . "\033[0m"; $context = [];
if (!empty($method)) $context['method'] = $method;
$context = []; if (!empty($file)) $context['file'] = $file;
if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file; $this->logger()->notice($message, $context);
}
$this->logger()->critical($message, $context);
}
/**
* @param mixed $message
/** * @param string $method
* @param mixed $message * @param string $file
* @param null $method * @throws Exception
* @param null $file */
* @throws Exception public function warning(mixed $message, string $method = '', string $file = '')
*/ {
public function error(mixed $message, $method = null, $file = null) if (!is_string($message)) {
{ $message = print_r($message, true);
if ($message instanceof \Throwable) { }
$message = $message->getMessage() . " on line " . $message->getLine() . " at file " . $message->getFile();
} $context = [];
if (!empty($method)) $context['method'] = $method;
$context = []; if (!empty($file)) $context['file'] = $file;
if (is_string($method)) {
$message = (empty($method) ? '' : $method . ': ') . $message; $this->logger()->critical($message, $context);
} else { }
if (is_null($method)) {
$method = [];
} /**
$context = $method; * @param mixed $message
} * @param null $method
// $message = "\033[41;37m" . $message . "\033[0m"; * @param null $file
* @throws Exception
if (!empty($method)) $context['method'] = $method; */
if (!empty($file)) $context['file'] = $file; public function error(mixed $message, $method = null, $file = null)
{
$this->logger()->error($message, $context); 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 . ' ' . PHP_EOL . 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 -44
View File
@@ -1,44 +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; use Server\Tasker\AsyncTaskExecute;
/** /**
* Class Async * Class Async
* @package Kiri * @package Kiri
*/ */
class Async extends Component class Async extends Component
{ {
private static array $_absences = []; private static array $_absences = [];
/** /**
* @param string $name * @param string $name
* @param string $handler * @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 string $name
* @param array $params * @param array $params
* @throws Exception * @throws Exception
*/ */
public function dispatch(string $name, array $params = []) public function dispatch(string $name, array $params = [])
{ {
$context = di(AsyncTaskExecute::class); $context = di(AsyncTaskExecute::class);
$context->execute(static::$_absences[$name], $params); $context->execute(static::$_absences[$name], $params);
} }
} }
+171 -171
View File
@@ -1,171 +1,171 @@
<?php <?php
namespace Kiri\Cache\Base; namespace Kiri\Cache\Base;
use Exception; use Exception;
use Kiri\Abstracts\Logger; use Kiri\Abstracts\Logger;
use Kiri\Exception\RedisConnectException; use Kiri\Exception\RedisConnectException;
use Kiri\Kiri; use Kiri\Kiri;
use Kiri\Pool\StopHeartbeatCheck; use Kiri\Pool\StopHeartbeatCheck;
use RedisException; 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; public string $host;
public int $port; public int $port;
public int $database = 0; public int $database = 0;
public string $auth = ''; public string $auth = '';
public string $prefix = ''; public string $prefix = '';
public int $timeout = 30; public int $timeout = 30;
public int $read_timeout = 30; public int $read_timeout = 30;
public array $pool = []; public array $pool = [];
private int $_timer = -1; private int $_timer = -1;
private int $_last = 0; private int $_last = 0;
/** /**
* @param array $config * @param array $config
*/ */
public function __construct(array $config) public function __construct(array $config)
{ {
$this->host = $config['host']; $this->host = $config['host'];
$this->port = $config['port']; $this->port = $config['port'];
$this->database = $config['databases']; $this->database = $config['databases'];
$this->auth = $config['auth']; $this->auth = $config['auth'];
$this->prefix = $config['prefix']; $this->prefix = $config['prefix'];
$this->timeout = $config['timeout']; $this->timeout = $config['timeout'];
$this->read_timeout = $config['read_timeout']; $this->read_timeout = $config['read_timeout'];
$this->pool = $config['pool']; $this->pool = $config['pool'];
} }
public function init() public function init()
{ {
$this->heartbeat_check(); $this->heartbeat_check();
} }
/** /**
* *
*/ */
public function heartbeat_check(): void public function heartbeat_check(): void
{ {
if (env('state', 'start') == 'exit') { if (env('state', 'start') == 'exit') {
return; return;
} }
if ($this->_timer === -1) { if ($this->_timer === -1) {
$this->_timer = Timer::tick(1000, fn() => $this->waite()); $this->_timer = Timer::tick(1000, fn() => $this->waite());
} }
} }
/** /**
* @throws Exception * @throws Exception
*/ */
private function waite(): void private function waite(): void
{ {
try { try {
if (env('state', 'start') == 'exit') { if (env('state', 'start') == 'exit') {
Kiri::getDi()->get(Logger::class)->critical('timer end'); Kiri::getDi()->get(Logger::class)->critical('timer end');
$this->stopHeartbeatCheck(); $this->stopHeartbeatCheck();
} }
if (time() - $this->_last > intval($this->pool['tick'] ?? 60)) { if (time() - $this->_last > intval($this->pool['tick'] ?? 60)) {
$this->stopHeartbeatCheck(); $this->stopHeartbeatCheck();
$this->pdo = null; $this->pdo = null;
} }
} catch (\Throwable $throwable) { } catch (\Throwable $throwable) {
error($throwable); error($throwable);
} }
} }
/** /**
* *
*/ */
public function stopHeartbeatCheck(): void public function stopHeartbeatCheck(): void
{ {
if ($this->_timer > -1) { if ($this->_timer > -1) {
Timer::clear($this->_timer); Timer::clear($this->_timer);
} }
$this->_timer = -1; $this->_timer = -1;
} }
/** /**
* @param string $name * @param string $name
* @param array $arguments * @param array $arguments
* @return mixed * @return mixed
* @throws RedisConnectException|RedisException * @throws RedisConnectException|RedisException
*/ */
public function __call(string $name, array $arguments) public function __call(string $name, array $arguments)
{ {
if (!method_exists($this, $name)) { if (!method_exists($this, $name)) {
return $this->_pdo()->{$name}(...$arguments); return $this->_pdo()->{$name}(...$arguments);
} }
return $this->{$name}(...$arguments); return $this->{$name}(...$arguments);
} }
/** /**
* @return \Redis * @return \Redis
* @throws RedisConnectException * @throws RedisConnectException
* @throws RedisException * @throws RedisException
*/ */
public function _pdo(): \Redis public function _pdo(): \Redis
{ {
if ($this->_timer === -1) { if ($this->_timer === -1) {
$this->heartbeat_check(); $this->heartbeat_check();
} }
if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) { if (!($this->pdo instanceof \Redis) || !$this->pdo->ping('isOk')) {
$this->pdo = $this->newClient(); $this->pdo = $this->newClient();
} }
return $this->pdo; return $this->pdo;
} }
/** /**
* @return \Redis * @return \Redis
* @throws RedisConnectException * @throws RedisConnectException
*/ */
private function newClient(): \Redis private function newClient(): \Redis
{ {
$redis = new \Redis(); $redis = new \Redis();
if (!$redis->connect($this->host, $this->port, $this->timeout)) { if (!$redis->connect($this->host, $this->port, $this->timeout)) {
throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port)); throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $this->host, $this->port));
} }
if (!empty($this->auth) && !$redis->auth($this->auth)) { 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)); throw new RedisConnectException(sprintf('Redis Error: %s, Host %s, Auth %s', $redis->getLastError(), $this->host, $this->auth));
} }
if ($this->read_timeout < 0) { if ($this->read_timeout < 0) {
$this->read_timeout = 0; $this->read_timeout = 0;
} }
$redis->select($this->database); $redis->select($this->database);
if ($this->read_timeout > 0) { if ($this->read_timeout > 0) {
$redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout); $redis->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout);
} }
$redis->setOption(\Redis::OPT_PREFIX, $this->prefix); $redis->setOption(\Redis::OPT_PREFIX, $this->prefix);
return $redis; 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 -172
View File
@@ -1,172 +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 Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Core\Json; use Kiri\Core\Json;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri\Kiri;
use Kiri\Pool\Redis as PoolRedis; use Kiri\Pool\Redis as PoolRedis;
use Note\Inject; use Kiri\Annotation\Inject;
use Server\Events\OnWorkerExit; 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_HOST = 'host'; const REDIS_OPTION_TIMEOUT = 'timeout';
const REDIS_OPTION_PORT = 'port'; const REDIS_OPTION_POOL = 'pool';
const REDIS_OPTION_PREFIX = 'prefix'; const REDIS_OPTION_POOL_TICK = 'tick';
const REDIS_OPTION_AUTH = 'auth'; const REDIS_OPTION_POOL_MIN = 'min';
const REDIS_OPTION_DATABASES = 'databases'; const REDIS_OPTION_POOL_MAX = 'max';
const REDIS_OPTION_TIMEOUT = 'timeout';
const REDIS_OPTION_POOL = 'pool';
const REDIS_OPTION_POOL_TICK = 'tick'; /**
const REDIS_OPTION_POOL_MIN = 'min'; * @throws ConfigException
const REDIS_OPTION_POOL_MAX = 'max'; * @throws Exception
*/
public function init()
/** {
* @throws ConfigException $connections = Kiri::getDi()->get(PoolRedis::class);
* @throws Exception
*/ $config = $this->get_config();
public function init()
{ $length = Config::get('cache.redis.pool.max', 10);
$connections = Kiri::getDi()->get(PoolRedis::class);
$this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0);
$config = $this->get_config();
$connections->initConnections('Redis:' . $config['host'], true, $length);
$length = Config::get('cache.redis.pool.max', 10); }
$this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0);
/**
$connections->initConnections('Redis:' . $config['host'], true, $length); * @param $name
} * @param $arguments
* @return mixed
* @throws
/** */
* @param $name public function __call($name, $arguments): mixed
* @param $arguments {
* @return mixed $time = microtime(true);
* @throws if (method_exists($this, $name)) {
*/ $data = $this->{$name}(...$arguments);
public function __call($name, $arguments): mixed } else {
{ $data = $this->proxy($name, $arguments);
$time = microtime(true); }
if (method_exists($this, $name)) { if (microtime(true) - $time >= 0.02) {
$data = $this->{$name}(...$arguments); $this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time));
} else { }
$data = $this->proxy($name, $arguments); return $data;
} }
if (microtime(true) - $time >= 0.02) {
$this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time));
} /**
return $data; * @param $key
} * @param int $timeout
* @return bool
*/
/** public function waite($key, int $timeout = 5): bool
* @param $key {
* @param int $timeout $time = time();
* @return bool|int while (!$this->setNx($key, 1)) {
* @throws Exception if (time()- $time >= $timeout) {
*/ return FALSE;
public function lock($key, int $timeout = 5): bool|int }
{ usleep(1000);
$script = <<<SCRIPT }
local _nx = redis.call('setnx',KEYS[1], ARGV[1]) $this->expire($key, $timeout);
if (_nx ~= 0) then return TRUE;
redis.call('expire',KEYS[1], ARGV[1]) }
return 1
end
return 0 /**
SCRIPT; * @param $key
return $this->eval($script, ['{lock}:' . $key, $timeout], 1); * @param int $timeout
} * @return bool|int
* @throws Exception
*/
/** public function lock($key, int $timeout = 5): bool|int
* @param $key {
* @return int $script = <<<SCRIPT
* @throws Exception local _nx = redis.call('setnx',KEYS[1], ARGV[1])
*/ if (_nx ~= 0) then
public function unlock($key): int redis.call('expire',KEYS[1], ARGV[1])
{ return 1
return $this->del('{lock}:' . $key); end
} return 0
SCRIPT;
return $this->eval($script, ['{lock}:' . $key, $timeout], 1);
/** }
* @throws ConfigException
* @throws Exception
*/ /**
public function release() * @param $key
{ * @return int
$connections = Kiri::getDi()->get(PoolRedis::class); * @throws Exception
$connections->release($this->get_config(), true); */
} public function unlock($key): int
{
/** return $this->del('{lock}:' . $key);
* 销毁连接池 }
* @throws ConfigException
* @throws Exception
*/ /**
public function destroy() * @throws ConfigException
{ * @throws Exception
$connections = Kiri::getDi()->get(PoolRedis::class); */
$connections->connection_clear($this->get_config(), true); public function release()
} {
$connections = Kiri::getDi()->get(PoolRedis::class);
/** $connections->release($this->get_config(), true);
* @param $name }
* @param $arguments
* @return mixed /**
* @throws ConfigException * 销毁连接池
* @throws Exception * @throws ConfigException
*/ * @throws Exception
public function proxy($name, $arguments): mixed */
{ public function destroy()
$connections = Kiri::getDi()->get(PoolRedis::class); {
$connections = Kiri::getDi()->get(PoolRedis::class);
$config = $this->get_config(); $connections->connection_clear($this->get_config(), true);
}
$client = $connections->get($config, true);
if (!($client instanceof Base\Redis)) { /**
throw new Exception('Redis connections more.'); * @param $name
} * @param $arguments
$response = $client->{$name}(...$arguments); * @return mixed
$this->release(); * @throws ConfigException
return $response; * @throws Exception
} */
public function proxy($name, $arguments): mixed
/** {
* @return array $connections = Kiri::getDi()->get(PoolRedis::class);
* @throws ConfigException
*/ $config = $this->get_config();
public function get_config(): array
{ $client = $connections->get($config, true);
return Config::get('cache.redis', null, 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 -18
View File
@@ -1,18 +1,18 @@
<?php <?php
namespace Kiri\Core; namespace Kiri\Core;
class Network class Network
{ {
/** /**
* @return string * @return string
*/ */
public static function local(): string public static function local(): string
{ {
return current(swoole_get_local_ip()); 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 -460
View File
@@ -1,460 +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 Kiri\Abstracts\Component; use Kiri\Annotation\Inject;
use Note\Inject; use Closure;
use Closure; use Exception;
use Exception; 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 Component 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];
*/ }
private function resolveDependencies($class): ReflectionClass $reflect = new ReflectionClass($class);
{ if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) {
if (isset($this->_reflection[$class])) { return $this->_reflection[$class] = $reflect;
return $this->_reflection[$class]; }
} $construct = NoteManager::resolveTarget($reflect);
$reflect = new ReflectionClass($class); if (!empty($construct) && $construct->getNumberOfParameters() > 0) {
if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) { $this->_constructs[$class] = $construct;
return $this->_reflection[$class] = $reflect; }
} return $this->_reflection[$class] = $reflect;
$construct = NoteManager::resolveTarget($reflect); }
if (!empty($construct) && $construct->getNumberOfParameters() > 0) {
$this->_constructs[$class] = $construct;
} /**
return $this->_reflection[$class] = $reflect; * @param ReflectionClass|string $class
} * @return ReflectionMethod[]
* @throws ReflectionException
*/
/** public function getReflectMethods(ReflectionClass|string $class): array
* @param ReflectionClass|string $class {
* @return ReflectionMethod[] if (is_string($class)) {
* @throws ReflectionException $class = $this->getReflect($class);
*/ }
public function getReflectMethods(ReflectionClass|string $class): array return NoteManager::getMethods($class);
{ }
if (is_string($class)) {
$class = $this->getReflect($class);
} /**
return NoteManager::getMethods($class); * @param ReflectionClass|string $class
} * @param string $method
* @return ReflectionMethod|null
* @throws ReflectionException
/** */
* @param ReflectionClass|string $class public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
* @param string $method {
* @return ReflectionMethod|null return $this->getReflectMethods($class)[$method] ?? null;
* @throws ReflectionException }
*/
public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
{ /**
return $this->getReflectMethods($class)[$method] ?? null; * @param string $className
} * @param string $method
* @return array|null
* @throws ReflectionException
/** */
* @param string $className public function getMethodParameters(string $className, string $method): ?array
* @param string $method {
* @return array|null if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) {
* @throws ReflectionException return $this->_parameters[$className][$method];
*/ }
public function getMethodParameters(string $className, string $method): ?array $reflectMethod = $this->getReflectMethod($this->getReflect($className), $method);
{ if (!($reflectMethod instanceof ReflectionMethod)) {
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) { throw new ReflectionException("Class does not have a function $className::$method");
return $this->_parameters[$className][$method]; }
} $className = $reflectMethod->getDeclaringClass()->getName();
$reflectMethod = $this->getReflectMethod($this->getReflect($className), $method); if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) {
if (!($reflectMethod instanceof ReflectionMethod)) { return $this->_parameters[$className][$reflectMethod->getName()];
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()];
} /**
return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod)); * @param $class
} * @param $method
* @param $parameters
* @return mixed
/** */
* @param $class private function setParameters($class, $method, $parameters): mixed
* @param $method {
* @param $parameters if (!isset($this->_parameters[$class])) {
* @return mixed $this->_parameters[$class] = [];
*/ }
private function setParameters($class, $method, $parameters): mixed return $this->_parameters[$class][$method] = $parameters;
{ }
if (!isset($this->_parameters[$class])) {
$this->_parameters[$class] = [];
} /**
if (!isset($this->_parameters[$class][$method])) { * @param Closure $reflectionMethod
$this->_parameters[$class][$method] = []; * @return array
} * @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
public function getFunctionParameters(Closure $reflectionMethod): array * @return array
{ */
return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod)); private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array
} {
if ($reflectionMethod->getNumberOfParameters() < 1) {
return [];
/** }
* @param ReflectionMethod|ReflectionFunction $reflectionMethod $params = [];
* @return array foreach ($reflectionMethod->getParameters() as $key => $parameter) {
* @throws ReflectionException if ($parameter->isDefaultValueAvailable()) {
*/ $params[$key] = $parameter->getDefaultValue();
private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array } else if ($parameter->getType() === null) {
{ $params[$key] = $parameter->getType();
if ($reflectionMethod->getNumberOfParameters() < 1) { } else {
return []; $type = $parameter->getType()->getName();
} if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) {
$params = []; $type = Kiri::getDi()->get($type);
foreach ($reflectionMethod->getParameters() as $key => $parameter) { }
if ($parameter->isDefaultValueAvailable()) { $params[$key] = match ($parameter->getType()) {
$params[$key] = $parameter->getDefaultValue(); 'string' => '',
} else if ($parameter->getType() === null) { 'int', 'float' => 0,
$params[$key] = $parameter->getType(); '', null, 'object', 'mixed' => NULL,
} else { 'bool' => false,
$type = $parameter->getType()->getName(); default => $type
if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) { };
$type = Kiri::getDi()->get($type); }
} }
$params[$key] = match ($parameter->getType()) { return $params;
'string' => '', }
'int', 'float' => 0,
'', null, 'object', 'mixed' => NULL,
'bool' => false, /**
default => $type * @param $class
}; * @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])) { {
return $this->resolveDependencies($class); if (is_array($class) && isset($class['class'])) {
} $class = $class['class'];
return $this->_reflection[$class]; } else if (is_object($class)) {
} $class = $class::class;
}
/** unset(
* @param $class $this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class]
*/ );
public function unset($class) }
{
if (is_array($class) && isset($class['class'])) { /**
$class = $class['class']; * @return $this
} else if (is_object($class)) { */
$class = $class::class; public function flush(): static
} {
unset( $this->_reflection = [];
$this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class] $this->_singletons = [];
); $this->_constructs = [];
} return $this;
}
/**
* @return $this /**
*/ * @param $old
public function flush(): static * @param $newParam
{ *
$this->_reflection = []; * @return mixed
$this->_singletons = []; */
$this->_constructs = []; private function mergeParam($old, $newParam): array
return $this; {
} if (empty($old)) {
return $newParam;
/** } else if (empty($newParam)) {
* @param $old return $old;
* @param $newParam }
* foreach ($newParam as $key => $val) {
* @return mixed $old[$key] = $val;
*/ }
private function mergeParam($old, $newParam): array return $old;
{ }
if (empty($old)) {
return $newParam; /**
} else if (empty($newParam)) { * @param string $id
return $old; * @return bool
} */
foreach ($newParam as $key => $val) { public function has(string $id): bool
$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 -53
View File
@@ -1,53 +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; use Psr\Log\LoggerInterface;
/** /**
* Class LoggerAspect * Class LoggerAspect
* @package Kiri\Error * @package Kiri\Error
*/ */
class LoggerAspect implements OnAspectInterface class LoggerAspect implements OnAspectInterface
{ {
/** /**
* @param OnJoinPointInterface $joinPoint * @param OnJoinPointInterface $joinPoint
* @return mixed * @return mixed
* @throws Exception * @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 * @param $startTime
* @throws Exception * @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);
$logger = Kiri::getDi()->get(LoggerInterface::class); $logger = Kiri::getDi()->get(LoggerInterface::class);
$logger->debug(sprintf('run %s use time %6f', $request->getUri()->__toString(), $runTime)); $logger->debug(sprintf('run %s use time %6f', $request->getUri()->__toString(), $runTime));
} }
} }
+84 -84
View File
@@ -1,84 +1,84 @@
<?php <?php
namespace Kiri\Error; namespace Kiri\Error;
use Exception; use Exception;
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 Server\Abstracts\BaseProcess;
use Swoole\Coroutine; use Swoole\Coroutine;
use Swoole\Process; use Swoole\Process;
/** /**
* 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 * @param Process $process
* @throws ComponentException * @throws ComponentException
*/ */
public function process(Process $process): void public function process(Process $process): void
{ {
// TODO: Implement onHandler() method. // TODO: Implement onHandler() method.
$this->message($process); $this->message($process);
} }
/** /**
* @param Process $process * @param Process $process
* @throws ComponentException * @throws ComponentException
* @throws Exception * @throws Exception
*/ */
public function message(Process $process) public function message(Process $process)
{ {
if ($this->isStop()) { if ($this->isStop()) {
return; return;
} }
$message = Json::decode($process->read()); $message = Json::decode($process->read());
if (!empty($message)) { if (!empty($message)) {
Kiri::writeFile($this->getDirName($message), $message[0], FILE_APPEND); 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 * @param $message
* @return string * @return string
* @throws Exception * @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 * @param $dirName
* @throws Exception * @throws Exception
*/ */
private function checkLogFile($dirName) private function checkLogFile($dirName)
{ {
$files = new \DirectoryIterator(storage(null, $dirName)); $files = new \DirectoryIterator(storage(null, $dirName));
if ($files->getSize() < 15) { if ($files->getSize() < 15) {
return; 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 -238
View File
@@ -1,238 +1,238 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Kiri; namespace Kiri;
use Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
/** /**
* Class Event * Class Event
* @package Kiri * @package Kiri
*/ */
class Event extends Component class Event extends Component
{ {
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 -232
View File
@@ -1,232 +1,235 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Exception; use Exception;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Core\Json; use Kiri\Core\Json;
use Kiri\Error\Logger; use Kiri\Error\Logger;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri\Kiri;
use Note\Inject; use Kiri\Annotation\Inject;
use Swoole\Coroutine; use Swoole\Coroutine;
use Swoole\Process; use Swoole\Process;
use Swoole\Timer; use Swoole\Timer;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; 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 bool $isReloading = FALSE;
public ?array $dirs = []; public bool $isReloadingOut = FALSE;
public ?array $dirs = [];
public int $events;
public int $events;
public int $int = -1;
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 $source = NULL;
protected mixed $pipes = [];
protected mixed $pipes = [];
protected ?Coroutine\Channel $channel = null;
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');
}
/**
* @throws ConfigException /**
* @throws \ReflectionException * @throws ConfigException
* @throws Exception * @throws \ReflectionException
*/ * @throws Exception
protected function initCore() */
{ protected function initCore()
$this->dirs = Config::get('inotify', [APP_PATH . 'app']); {
if (!extension_loaded('inotify')) { set_error_handler([$this, 'errorHandler']);
$this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]); $this->dirs = Config::get('inotify', [APP_PATH . 'app']);
} else { if (!extension_loaded('inotify')) {
$this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]); $this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]);
} } else {
$this->clearOtherService(); $this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]);
$this->setProcessName(); }
} $this->clearOtherService();
$this->setProcessName();
}
/**
* @throws ConfigException
*/ /**
public function setProcessName() * @throws ConfigException
{ */
swoole_async_set(['enable_coroutine' => false]); public function setProcessName()
set_error_handler([$this, 'errorHandler']); {
if (Kiri::getPlatform()->isLinux()) { swoole_async_set(['enable_coroutine' => FALSE]);
swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather'); if (Kiri::getPlatform()->isLinux()) {
} swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather');
} }
}
/**
* @throws Exception /**
*/ * @throws Exception
public function clearOtherService() */
{ public function clearOtherService()
if (file_exists(storage('.manager.pid'))) { {
$pid = (int)file_get_contents(storage('.manager.pid')); if (file_exists(storage('.manager.pid'))) {
if ($pid > 0 && Process::kill($pid, 0)) { $pid = (int)file_get_contents(storage('.manager.pid'));
Process::kill($pid, 15) && Process::wait(true); if ($pid > 0 && Process::kill($pid, 0)) {
} Process::kill($pid, 15) && Process::wait(TRUE);
} }
file_put_contents(storage('.manager.pid'), getmypid()); }
} file_put_contents(storage('.manager.pid'), getmypid());
}
/**
* @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) {
$error[0] = 500; if ($error[0] === 0) {
} $error[0] = 500;
$data = Json::to(500, $error[1], $path); }
$data = Json::to(500, $error[1], $path);
$this->logger->error($data, 'error');
} $this->logger->error($data, 'error');
}
/**
* @param InputInterface $input /**
* @param OutputInterface $output * @param InputInterface $input
* @return int * @param OutputInterface $output
* @throws ConfigException * @return int
* @throws Exception * @throws ConfigException
*/ * @throws Exception
public function execute(InputInterface $input, OutputInterface $output): int */
{ public function execute(InputInterface $input, OutputInterface $output): int
$this->initCore(); {
$this->initCore();
$this->trigger_reload();
$this->trigger_reload();
Timer::tick(1000, fn() => $this->healthCheck()); Timer::tick(1000, fn() => $this->healthCheck());
Process::signal(SIGTERM, [$this, 'onSignal']); Process::signal(SIGTERM, [$this, 'onSignal']);
Process::signal(SIGKILL, [$this, 'onSignal']); Process::signal(SIGKILL, [$this, 'onSignal']);
$this->driver->start(); $this->driver->start();
return 0; return 0;
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function healthCheck() public function healthCheck()
{ {
$pid = (int)file_get_contents(storage('.swoole.pid')); $pid = (int)file_get_contents(storage('.swoole.pid'));
if (empty($pid)) { if ($this->int == 1) {
$this->logger->warning('service is shutdown you need reload.'); return;
$this->trigger_reload(); }
} else if (!Process::kill($pid, 0)) { if (empty($pid)) {
$this->logger->warning('service is shutdown you need reload.'); $this->logger->warning('service is shutdown you need reload.');
$this->trigger_reload(); $this->trigger_reload();
} } else if (!Process::kill($pid, 0)) {
} $this->logger->warning('service is shutdown you need reload.');
$this->trigger_reload();
}
/** }
* @param $data
* @throws Exception
*/ /**
public function onSignal($data) * @param $data
{ * @throws Exception
if (!$data) { */
return; public function onSignal($data)
} {
Timer::clearAll(); if (!$data) {
$this->driver->clear(); return;
$this->stopServer(); }
$this->stopManager(); Timer::clearAll();
while ($ret = Process::wait(true)) { $this->driver->clear();
echo "PID={$ret['pid']}\n"; $this->stopServer();
sleep(1); $this->stopManager();
} while ($ret = Process::wait(TRUE)) {
} echo "PID={$ret['pid']}\n";
sleep(1);
}
/** }
* @throws Exception
*/
protected function stopServer() /**
{ * @throws Exception
$pid = file_get_contents(storage('.swoole.pid')); */
if (!empty($pid) && Process::kill($pid, 0)) { protected function stopServer()
Process::kill($pid, SIGTERM); {
} $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); 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() *
{ * @throws Exception
if ($this->int == 1) { */
return; public function trigger_reload()
} {
$this->int = 1; if ($this->int == 1) {
$this->logger->warning('change reload'); return;
}
$this->stopServer(); $this->int = 1;
$this->stopManager(); $this->logger->warning('change reload');
$this->process = new Process(function (Process $process) { $this->stopServer();
$process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "restart"]); $this->stopManager();
});
$this->process = new Process(function (Process $process) {
$this->process->start(); $process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "start"]);
$this->int = -1; });
}
$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->getMessage(), '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 -634
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 -217
View File
@@ -1,217 +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, [$config]); return Kiri::getDi()->create(PDO::class, [$config]);
}; };
} }
/** /**
* @param $name * @param $name
* @param $isMaster * @param $isMaster
* @param $max * @param $max
* @throws Exception * @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 $coroutineName
* @param $isMaster * @param $isMaster
* @throws Exception * @throws Exception
*/ */
public function release($coroutineName, $isMaster) public function release($coroutineName, $isMaster)
{ {
$coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster); $coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster);
/** @var PDO $client */ /** @var PDO $client */
if (!($client = Context::getContext($coroutineName)) instanceof PDO) { if (!($client = Context::getContext($coroutineName)) instanceof PDO) {
return; return;
} }
if ($client->inTransaction()) { if ($client->inTransaction()) {
return; return;
} }
$this->getPool()->push($coroutineName, $client); $this->getPool()->push($coroutineName, $client);
Context::remove($coroutineName); Context::remove($coroutineName);
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @return bool * @return bool
*/ */
private function hasClient($coroutineName): bool private function hasClient($coroutineName): bool
{ {
return Context::hasContext($coroutineName); return Context::hasContext($coroutineName);
} }
/** /**
* batch release * batch release
* @throws Exception * @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 string $name
* @param mixed $client * @param mixed $client
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function checkCanUse(string $name, mixed $client): bool public function checkCanUse(string $name, mixed $client): bool
{ {
try { try {
if (empty($client) || !($client instanceof PDO)) { if (empty($client) || !($client instanceof PDO)) {
$result = false; $result = false;
} else { } else {
$result = true; $result = true;
} }
} catch (Error | Throwable $exception) { } catch (Error | Throwable $exception) {
$result = $this->addError($exception, 'mysql'); $result = $this->addError($exception, 'mysql');
} finally { } finally {
return $result; return $result;
} }
} }
/** /**
* @param $coroutineName * @param $coroutineName
* @param bool $isMaster * @param bool $isMaster
* @throws Exception * @throws Exception
*/ */
public function disconnect($coroutineName, bool $isMaster = false) public function disconnect($coroutineName, bool $isMaster = false)
{ {
Context::remove($coroutineName); Context::remove($coroutineName);
$coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster); $coroutineName = $this->name('Mysql:' . $coroutineName, $isMaster);
$this->getPool()->clean($coroutineName); $this->getPool()->clean($coroutineName);
} }
/** /**
* @return Pool * @return Pool
* @throws Exception * @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 -122
View File
@@ -1,122 +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, [$config]); return Kiri::getDi()->create(\Kiri\Cache\Base\Redis::class, [$config]);
}; };
} }
/** /**
* @param array $config * @param array $config
* @param bool $isMaster * @param bool $isMaster
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function release(array $config, bool $isMaster = false) public function release(array $config, bool $isMaster = false)
{ {
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster); $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
if (!Context::hasContext($coroutineName)) { if (!Context::hasContext($coroutineName)) {
return; return;
} }
$this->getPool()->push($coroutineName, Context::getContext($coroutineName)); $this->getPool()->push($coroutineName, Context::getContext($coroutineName));
Context::remove($coroutineName); Context::remove($coroutineName);
} }
/** /**
* @param array $config * @param array $config
* @param bool $isMaster * @param bool $isMaster
* @throws Exception * @throws Exception
*/ */
public function destroy(array $config, bool $isMaster = false) public function destroy(array $config, bool $isMaster = false)
{ {
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster); $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
$this->getPool()->clean($coroutineName); $this->getPool()->clean($coroutineName);
Context::remove($coroutineName); Context::remove($coroutineName);
} }
/** /**
* @param array $config * @param array $config
* @param bool $isMaster * @param bool $isMaster
* @throws Exception * @throws Exception
*/ */
public function connection_clear(array $config, bool $isMaster = false) public function connection_clear(array $config, bool $isMaster = false)
{ {
$coroutineName = $this->name('Redis:' . $config['host'], $isMaster); $coroutineName = $this->name('Redis:' . $config['host'], $isMaster);
$this->getPool()->clean($coroutineName); $this->getPool()->clean($coroutineName);
} }
/** /**
* @return Pool * @return Pool
* @throws Exception * @throws Exception
*/ */
public function getPool(): Pool public function getPool(): Pool
{ {
return Kiri::getDi()->get(Pool::class); return Kiri::getDi()->get(Pool::class);
} }
/** /**
* @param $name * @param $name
* @param $isMaster * @param $isMaster
* @param $max * @param $max
* @throws Exception * @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);
} }
} }
+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 -344
View File
@@ -1,344 +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) {
$tableName = str_replace($this->db->tablePrefix,'', $tableName); $res[] = ucfirst($val);
foreach (explode('_', $tableName) as $n => $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 -536
View File
File diff suppressed because it is too large Load Diff
+113 -113
View File
@@ -1,113 +1,113 @@
<?php <?php
namespace Gii; namespace Gii;
class GiiJsonRpc extends GiiBase class GiiJsonRpc extends GiiBase
{ {
/** /**
* @return array * @return array
*/ */
public function create(): array public function create(): array
{ {
return [ return [
$this->createInterface($this->input->getArgument('name')), $this->createInterface($this->input->getArgument('name')),
$this->createProducers($this->input->getArgument('name')), $this->createProducers($this->input->getArgument('name')),
$this->createConsumer($this->input->getArgument('name')), $this->createConsumer($this->input->getArgument('name')),
]; ];
} }
private function createInterface($name): string private function createInterface($name): string
{ {
$html = '<?php $html = '<?php
namespace Rpc; namespace Rpc;
interface ' . ucfirst($name) . 'RpcInterface interface ' . ucfirst($name) . 'RpcInterface
{ {
}'; }';
$name = ucfirst($name) . 'RpcInterface.php'; $name = ucfirst($name) . 'RpcInterface.php';
if (!is_dir(APP_PATH . '/rpc/')) { if (!is_dir(APP_PATH . '/rpc/')) {
mkdir(APP_PATH . '/rpc/'); mkdir(APP_PATH . '/rpc/');
} }
file_put_contents(APP_PATH . '/rpc/' . $name, $html); file_put_contents(APP_PATH . '/rpc/' . $name, $html);
return $name; return $name;
} }
private function createProducers($name): string private function createProducers($name): string
{ {
$html = '<?php $html = '<?php
namespace Rpc\Producers; namespace Rpc\Producers;
use Note\Target; use Kiri\Annotation\Target;
use Note\Mapping; use Kiri\Annotation\Mapping;
use Rpc\\' . ucfirst($name) . 'RpcInterface; use Rpc\\' . ucfirst($name) . 'RpcInterface;
use Exception; use Exception;
use Kiri\Rpc\JsonRpcConsumers; use Kiri\Rpc\JsonRpcConsumers;
#[Target] #[Target]
#[Mapping(' . ucfirst($name) . 'RpcInterface::class)] #[Mapping(' . ucfirst($name) . 'RpcInterface::class)]
class ' . ucfirst($name) . 'RpcService extends JsonRpcConsumers implements ' . ucfirst($name) . 'RpcInterface class ' . ucfirst($name) . 'RpcService extends JsonRpcConsumers implements ' . ucfirst($name) . 'RpcInterface
{ {
protected string $name = \'' . $name . '\'; protected string $name = \'' . $name . '\';
}'; }';
$name = ucfirst($name) . 'RpcService.php'; $name = ucfirst($name) . 'RpcService.php';
if (!is_dir(APP_PATH . '/rpc/Producers/')) { if (!is_dir(APP_PATH . '/rpc/Producers/')) {
mkdir(APP_PATH . '/rpc/Producers/'); mkdir(APP_PATH . '/rpc/Producers/');
} }
file_put_contents(APP_PATH . '/rpc/Producers/' . $name, $html); file_put_contents(APP_PATH . '/rpc/Producers/' . $name, $html);
return $name; return $name;
} }
private function createConsumer($name): string private function createConsumer($name): string
{ {
$html = '<?php $html = '<?php
namespace Rpc\Consumers; namespace Rpc\Consumers;
use Note\Target; use Kiri\Annotation\Target;
use Kiri\Rpc\Note\JsonRpc; use Kiri\Rpc\Annotation\JsonRpc;
use Http\Handler\Controller; use Http\Handler\Controller;
use Rpc\\' . ucfirst($name) . 'RpcInterface; use Rpc\\' . ucfirst($name) . 'RpcInterface;
#[Target] #[Target]
#[JsonRpc(service: \'' . $name . '\', version: \'2.0\')] #[JsonRpc(service: \'' . $name . '\', version: \'2.0\')]
class ' . ucfirst($name) . 'RpcConsumer extends Controller implements ' . ucfirst($name) . 'RpcInterface class ' . ucfirst($name) . 'RpcConsumer extends Controller implements ' . ucfirst($name) . 'RpcInterface
{ {
}'; }';
$name = ucfirst($name) . 'RpcConsumer.php'; $name = ucfirst($name) . 'RpcConsumer.php';
if (!is_dir(APP_PATH . '/rpc/Consumers/')) { if (!is_dir(APP_PATH . '/rpc/Consumers/')) {
mkdir(APP_PATH . '/rpc/Consumers/'); mkdir(APP_PATH . '/rpc/Consumers/');
} }
file_put_contents(APP_PATH . '/rpc/Consumers/' . $name, $html); file_put_contents(APP_PATH . '/rpc/Consumers/' . $name, $html);
return $name; return $name;
} }
} }

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