This commit is contained in:
2022-01-09 03:50:38 +08:00
parent 08dc3e262b
commit 5e02a79bf0
113 changed files with 12713 additions and 12703 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 -46
View File
@@ -1,46 +1,46 @@
{ {
"name": "game-worker/kiri-core", "name": "game-worker/kiri-core",
"description": "test framework", "description": "test framework",
"authors": [ "authors": [
{ {
"name": "XiangLin", "name": "XiangLin",
"email": "as2252258@163.com" "email": "as2252258@163.com"
} }
], ],
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": ">=8.1", "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.*",
"composer-runtime-api": "^2.0", "composer-runtime-api": "^2.0",
"psr/container": "^2.0", "psr/container": "^2.0",
"psr/http-server-middleware": "1.0.1", "psr/http-server-middleware": "1.0.1",
"game-worker/kiri-event": "~v2.0", "game-worker/kiri-event": "~v2.0",
"ext-inotify": "*" "ext-inotify": "*"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Kiri\\": "kiri-engine/", "Kiri\\": "kiri-engine/",
"Kiri\\Gateway\\": "kiri-gateway/", "Kiri\\Gateway\\": "kiri-gateway/",
"Kiri\\Websocket\\": "kiri-websocket-server/", "Kiri\\Websocket\\": "kiri-websocket-server/",
"Gii\\": "kiri-gii/", "Gii\\": "kiri-gii/",
"Kiri\\Annotation\\": "kiri-annotation/", "Kiri\\Annotation\\": "kiri-annotation/",
"Kiri\\Task\\": "kiri-task/" "Kiri\\Task\\": "kiri-task/"
}, },
"files": [ "files": [
"error.php", "error.php",
"function.php" "function.php"
] ]
} }
} }
+31 -31
View File
@@ -1,31 +1,31 @@
<?php <?php
define('SUCCESS', 0); define('SUCCESS', 0);
define('NO_AUTH', 401); define('NO_AUTH', 401);
define('ERROR_MESSAGES', [ define('ERROR_MESSAGES', [
SUCCESS => 'ok', SUCCESS => 'ok',
NO_AUTH => '' NO_AUTH => ''
]); ]);
if (!function_exists('message')) { if (!function_exists('message')) {
/** /**
* @param $code * @param $code
* @param $replace * @param $replace
* @param string $default * @param string $default
* @return mixed|string * @return mixed|string
*/ */
function message($code, $replace, $default = '') function message($code, $replace, $default = '')
{ {
if (!isset(ERROR_MESSAGES[$code])) { if (!isset(ERROR_MESSAGES[$code])) {
if (!empty($default)) { if (!empty($default)) {
return $default; return $default;
} }
return 'unknown error'; return 'unknown error';
} }
return sprintf(ERROR_MESSAGES[$code], $replace); return sprintf(ERROR_MESSAGES[$code], $replace);
} }
} }
+1234 -1234
View File
File diff suppressed because it is too large Load Diff
+86 -86
View File
@@ -1,86 +1,86 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
use DirectoryIterator; use DirectoryIterator;
use Exception; use Exception;
use ReflectionException; use ReflectionException;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
/** /**
* Class Annotation * Class Annotation
* @package Annotation * @package Annotation
*/ */
class Annotation extends Component class Annotation extends Component
{ {
private Loader $_loader; private Loader $_loader;
/** /**
* *
*/ */
public function init(): void public function init(): void
{ {
$this->_loader = new Loader(); $this->_loader = new Loader();
} }
/** /**
* @return Loader * @return Loader
*/ */
public function getLoader(): Loader public function getLoader(): Loader
{ {
return $this->_loader; return $this->_loader;
} }
/** /**
* @param Loader $loader * @param Loader $loader
* @return Loader * @return Loader
*/ */
public function setLoader(Loader $loader): Loader public function setLoader(Loader $loader): Loader
{ {
return $this->_loader = $loader; return $this->_loader = $loader;
} }
/** /**
* @param object $class * @param object $class
* @throws ReflectionException * @throws ReflectionException
*/ */
public function injectProperty(object $class) public function injectProperty(object $class)
{ {
$this->_loader->injectProperty($class::class, $class); $this->_loader->injectProperty($class::class, $class);
} }
/** /**
* @param string $path * @param string $path
* @param string $namespace * @param string $namespace
* @param array $exclude * @param array $exclude
* @return static * @return static
* @throws Exception * @throws Exception
*/ */
public function read(string $path, string $namespace = 'App', array $exclude = []): static public function read(string $path, string $namespace = 'App', array $exclude = []): static
{ {
$this->_loader->_scanDir(new DirectoryIterator($path), $namespace, $exclude); $this->_loader->_scanDir(new DirectoryIterator($path), $namespace, $exclude);
return $this; return $this;
} }
/** /**
* @param string $dir * @param string $dir
* @param array $exclude * @param array $exclude
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function runtime(string $dir, array $exclude = []): array public function runtime(string $dir, array $exclude = []): array
{ {
return $this->_loader->loadByDirectory($dir, $exclude); return $this->_loader->loadByDirectory($dir, $exclude);
} }
} }
+37 -37
View File
@@ -1,37 +1,37 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement '); defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement ');
/** /**
* Class Aspect * Class Aspect
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends Attribute
{ {
/** /**
* Aspect constructor. * Aspect constructor.
* @param string $aspect * @param string $aspect
*/ */
public function __construct(public string $aspect) public function __construct(public string $aspect)
{ {
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = ''): bool public function execute(mixed $class, mixed $method = ''): bool
{ {
return true; return true;
} }
} }
+27 -27
View File
@@ -1,27 +1,27 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
/** /**
* Class Attribute * Class Attribute
* @package Annotation * @package Annotation
*/ */
abstract class Attribute implements IAnnotation abstract class Attribute implements IAnnotation
{ {
/** /**
* @param static $class * @param static $class
* @param mixed|string $method * @param mixed|string $method
* @return mixed * @return mixed
*/ */
#[\ReturnTypeWillChange] #[\ReturnTypeWillChange]
public function execute(mixed $class, mixed $method = ''): mixed public function execute(mixed $class, mixed $method = ''): mixed
{ {
// TODO: Implement execute() method. // TODO: Implement execute() method.
return true; return true;
} }
} }
+46 -46
View File
@@ -1,46 +1,46 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Kiri; use Kiri\Kiri;
/** /**
* Class Event * Class Event
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Event extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Event extends Attribute
{ {
/** /**
* Event constructor. * Event constructor.
* @param string $name * @param string $name
* @param array $params * @param array $params
*/ */
public function __construct(public string $name, public array $params = []) public function __construct(public string $name, public array $params = [])
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
$pro = Kiri::getDi()->get(EventProvider::class); $pro = Kiri::getDi()->get(EventProvider::class);
if (is_string($class)) { if (is_string($class)) {
$class = Kiri::getDi()->get($class); $class = Kiri::getDi()->get($class);
} }
$pro->on($this->name, [$class, $method]); $pro->on($this->name, [$class, $method]);
return true; return true;
} }
} }
+19 -19
View File
@@ -1,19 +1,19 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
interface IAnnotation interface IAnnotation
{ {
/** /**
* @param mixed $class * @param mixed $class
* @param mixed $method * @param mixed $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed; public function execute(mixed $class, mixed $method = ''): mixed;
} }
+104 -104
View File
@@ -1,104 +1,104 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
use Exception; use Exception;
use Kiri\Core\Str; use Kiri\Core\Str;
use Kiri\Kiri; use Kiri\Kiri;
use ReflectionException; use ReflectionException;
use ReflectionProperty; use ReflectionProperty;
/** /**
* Class Inject * Class Inject
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_PROPERTY)] class Inject extends Attribute #[\Attribute(\Attribute::TARGET_PROPERTY)] class Inject extends Attribute
{ {
/** /**
* Inject constructor. * Inject constructor.
* @param string $value * @param string $value
* @param array $construct * @param array $construct
*/ */
public function __construct(public string $value, public array $construct = []) public function __construct(public string $value, public array $construct = [])
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return bool * @return bool
* @throws ReflectionException * @throws ReflectionException
* @throws Exception * @throws Exception
*/ */
public function execute(mixed $class, mixed $method = null): bool public function execute(mixed $class, mixed $method = null): bool
{ {
if (!($method = $this->getProperty($class, $method))) { if (!($method = $this->getProperty($class, $method))) {
return false; return false;
} }
/** @var ReflectionProperty $class */ /** @var ReflectionProperty $class */
$injectValue = static::parseInjectValue(); $injectValue = static::parseInjectValue();
if ($method->isPrivate() || $method->isProtected()) { if ($method->isPrivate() || $method->isProtected()) {
$this->setter($class, $method, $injectValue); $this->setter($class, $method, $injectValue);
} else { } else {
$class->{$method->getName()} = $injectValue; $class->{$method->getName()} = $injectValue;
} }
return true; return true;
} }
/** /**
* @param $class * @param $class
* @param $method * @param $method
* @param $injectValue * @param $injectValue
*/ */
private function setter($class, $method, $injectValue) private function setter($class, $method, $injectValue)
{ {
$method = 'set' . ucfirst(Str::convertUnderline($method->getName())); $method = 'set' . ucfirst(Str::convertUnderline($method->getName()));
if (!method_exists($class, $method)) { if (!method_exists($class, $method)) {
return; return;
} }
$class->$method($injectValue); $class->$method($injectValue);
} }
/** /**
* @param $class * @param $class
* @param $method * @param $method
* @return ReflectionProperty|bool * @return ReflectionProperty|bool
*/ */
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);
} }
} }
} }
+225 -225
View File
@@ -1,225 +1,225 @@
<?php <?php
namespace Kiri\Annotation; 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 Annotation * @package Annotation
*/ */
class Loader extends Component class Loader extends Component
{ {
private array $_directory = []; private array $_directory = [];
private array $_methods = []; private array $_methods = [];
/** /**
* @param $path * @param $path
* @param $namespace * @param $namespace
* @throws Exception * @throws Exception
*/ */
public function loader($path, $namespace) public function loader($path, $namespace)
{ {
$this->_scanDir(new DirectoryIterator($path), $namespace); $this->_scanDir(new DirectoryIterator($path), $namespace);
} }
/** /**
* @param string $class * @param string $class
* @param object $handler * @param object $handler
* @return $this * @return $this
* @throws ReflectionException * @throws ReflectionException
* @throws Exception * @throws Exception
*/ */
public function injectProperty(string $class, object $handler): static public function injectProperty(string $class, object $handler): static
{ {
$di = Kiri::getDi(); $di = Kiri::getDi();
$reflect = $di->getReflect($class); $reflect = $di->getReflect($class);
$di->propertyInject($reflect, $handler); $di->propertyInject($reflect, $handler);
return $this; return $this;
} }
/** /**
* @param string $class * @param string $class
* @param string $method * @param string $method
* @return mixed * @return mixed
*/ */
public function getMethod(string $class, string $method = ''): array public function getMethod(string $class, string $method = ''): array
{ {
if (!isset($this->_methods[$class])) { if (!isset($this->_methods[$class])) {
return []; return [];
} }
$properties = $this->_methods[$class]; $properties = $this->_methods[$class];
if (!empty($method) && isset($properties[$method])) { if (!empty($method) && isset($properties[$method])) {
return $properties[$method]; return $properties[$method];
} }
return $properties; return $properties;
} }
/** /**
* @param DirectoryIterator $paths * @param DirectoryIterator $paths
* @param $namespace * @param $namespace
* @param array $exclude * @param array $exclude
* @throws Exception * @throws Exception
*/ */
public function _scanDir(DirectoryIterator $paths, $namespace, array $exclude = []) public function _scanDir(DirectoryIterator $paths, $namespace, array $exclude = [])
{ {
foreach ($paths as $path) { foreach ($paths as $path) {
if ($path->isDot() || str_starts_with($path->getFilename(), '.')) { if ($path->isDot() || str_starts_with($path->getFilename(), '.')) {
continue; continue;
} }
if ($this->inExclude($exclude, $path->getRealPath())) { if ($this->inExclude($exclude, $path->getRealPath())) {
continue; continue;
} }
if ($path->isDir()) { if ($path->isDir()) {
$iterator = new DirectoryIterator($path->getRealPath()); $iterator = new DirectoryIterator($path->getRealPath());
$directory = rtrim($path->getRealPath(), '/'); $directory = rtrim($path->getRealPath(), '/');
if (!isset($this->_directory[$directory])) { if (!isset($this->_directory[$directory])) {
$this->_directory[$directory] = []; $this->_directory[$directory] = [];
} }
$this->_scanDir($iterator, $namespace); $this->_scanDir($iterator, $namespace);
} else { } else {
$this->readFile($path, $namespace); $this->readFile($path, $namespace);
} }
} }
} }
/** /**
* @param DirectoryIterator $path * @param DirectoryIterator $path
* @param $namespace * @param $namespace
* @throws Exception * @throws Exception
*/ */
private function readFile(DirectoryIterator $path, $namespace) private function readFile(DirectoryIterator $path, $namespace)
{ {
try { try {
if ($path->getExtension() !== 'php') { if ($path->getExtension() !== 'php') {
return; return;
} }
$replace = $this->getReflect($path, $namespace); $replace = $this->getReflect($path, $namespace);
if (!$replace || !$replace->getAttributes(Target::class)) { if (!$replace || !$replace->getAttributes(Target::class)) {
return; return;
} }
$this->appendFileToDirectory($path->getRealPath(), $replace->getName()); $this->appendFileToDirectory($path->getRealPath(), $replace->getName());
} catch (Throwable $throwable) { } catch (Throwable $throwable) {
$this->error(jTraceEx($throwable), 'throwable'); $this->error(jTraceEx($throwable), 'throwable');
} }
} }
/** /**
* @param DirectoryIterator $path * @param DirectoryIterator $path
* @param string $namespace * @param string $namespace
* @return ReflectionClass|null * @return ReflectionClass|null
*/ */
private function getReflect(DirectoryIterator $path, string $namespace): ?ReflectionClass private function getReflect(DirectoryIterator $path, string $namespace): ?ReflectionClass
{ {
$class = $this->explodeFileName($path, $namespace); $class = $this->explodeFileName($path, $namespace);
if (!class_exists($class)) { if (!class_exists($class)) {
return null; return null;
} }
return Kiri::getDi()->getReflect($class); return Kiri::getDi()->getReflect($class);
} }
/** /**
* @param string $path * @param string $path
* @param array $exclude * @param array $exclude
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function loadByDirectory(string $path, array $exclude = []): array public function loadByDirectory(string $path, array $exclude = []): array
{ {
try { try {
$path = '/' . trim($path, '/'); $path = '/' . trim($path, '/');
$paths = []; $paths = [];
foreach ($this->_directory as $key => $_path) { foreach ($this->_directory as $key => $_path) {
$key = '/' . trim($key, '/'); $key = '/' . trim($key, '/');
if (!str_starts_with($key, $path) || $this->inExclude($exclude, $path)) { if (!str_starts_with($key, $path) || $this->inExclude($exclude, $path)) {
continue; continue;
} }
unset($this->_directory[$key]); unset($this->_directory[$key]);
foreach ($_path as $item) { foreach ($_path as $item) {
$paths[] = $item; $paths[] = $item;
} }
} }
return $paths; return $paths;
} catch (Throwable $exception) { } catch (Throwable $exception) {
$this->addError($exception, 'throwable'); $this->addError($exception, 'throwable');
return []; return [];
} }
} }
/** /**
* @param array $exclude * @param array $exclude
* @param $path * @param $path
* @return bool * @return bool
*/ */
private function inExclude(array $exclude, $path): bool private function inExclude(array $exclude, $path): bool
{ {
if (empty($exclude)) { if (empty($exclude)) {
return false; return false;
} }
foreach ($exclude as $value) { foreach ($exclude as $value) {
if (str_starts_with($path, $value)) { if (str_starts_with($path, $value)) {
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* @param DirectoryIterator $path * @param DirectoryIterator $path
* @param string $namespace * @param string $namespace
* @return string * @return string
*/ */
private function explodeFileName(DirectoryIterator $path, string $namespace): string private function explodeFileName(DirectoryIterator $path, string $namespace): string
{ {
$replace = str_replace(APP_PATH, '', $path->getRealPath()); $replace = str_replace(APP_PATH, '', $path->getRealPath());
$replace = str_replace('.php', '', $replace); $replace = str_replace('.php', '', $replace);
$replace = str_replace(DIRECTORY_SEPARATOR, '\\', $replace); $replace = str_replace(DIRECTORY_SEPARATOR, '\\', $replace);
$explode = explode('\\', $replace); $explode = explode('\\', $replace);
array_shift($explode); array_shift($explode);
return $namespace . '\\' . implode('\\', $explode); return $namespace . '\\' . implode('\\', $explode);
} }
/** /**
* @param string $filePath * @param string $filePath
* @param string $className * @param string $className
*/ */
public function appendFileToDirectory(string $filePath, string $className) public function appendFileToDirectory(string $filePath, string $className)
{ {
$array = explode('/', $filePath); $array = explode('/', $filePath);
unset($array[count($array) - 1]); unset($array[count($array) - 1]);
$array = '/' . trim(implode('/', $array), '/'); $array = '/' . trim(implode('/', $array), '/');
$this->_directory[$array][] = $className; $this->_directory[$array][] = $className;
} }
} }
+31 -31
View File
@@ -1,31 +1,31 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
use Kiri\Kiri; use Kiri\Kiri;
#[\Attribute(\Attribute::TARGET_CLASS)] class Mapping extends Attribute #[\Attribute(\Attribute::TARGET_CLASS)] class Mapping extends Attribute
{ {
/** /**
* @param string $class * @param string $class
*/ */
public function __construct(public string $class) public function __construct(public string $class)
{ {
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|string $method * @param mixed|string $method
* @return mixed * @return mixed
*/ */
public function execute(mixed $class, mixed $method = ''): mixed public function execute(mixed $class, mixed $method = ''): mixed
{ {
Kiri::getDi()->mapping($this->class, $class); Kiri::getDi()->mapping($this->class, $class);
return parent::execute($class, $method); return parent::execute($class, $method);
} }
} }
+34 -34
View File
@@ -1,34 +1,34 @@
<?php <?php
namespace Kiri\Annotation\Route; namespace Kiri\Annotation\Route;
use Kiri\Annotation\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Document * Class Document
* @package Annotation\Route * @package Annotation\Route
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Document extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Document extends Attribute
{ {
const INTEGER = 'int'; const INTEGER = 'int';
const STRING = 'string'; const STRING = 'string';
const BOOLEAN = 'bool'; const BOOLEAN = 'bool';
const FLOAT = 'float'; const FLOAT = 'float';
const ALIAS = [ const ALIAS = [
self::INTEGER => '整数', self::INTEGER => '整数',
self::STRING => '字符串', self::STRING => '字符串',
self::BOOLEAN => '布尔值', self::BOOLEAN => '布尔值',
self::FLOAT => '浮点', self::FLOAT => '浮点',
]; ];
public function __construct(array $request, array $response) public function __construct(array $request, array $response)
{ {
} }
} }
+53 -53
View File
@@ -1,53 +1,53 @@
<?php <?php
namespace Kiri\Annotation\Route; namespace Kiri\Annotation\Route;
use Kiri\Annotation\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 Annotation\Route * @package Annotation\Route
*/ */
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Middleware extends Attribute #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Middleware extends Attribute
{ {
/** /**
* Interceptor constructor. * Interceptor constructor.
* @param string|array $middleware * @param string|array $middleware
* @throws * @throws
*/ */
public function __construct(public string|array $middleware) public function __construct(public string|array $middleware)
{ {
if (is_string($this->middleware)) { if (is_string($this->middleware)) {
$this->middleware = [$this->middleware]; $this->middleware = [$this->middleware];
} }
$array = []; $array = [];
foreach ($this->middleware as $value) { foreach ($this->middleware as $value) {
if (!in_array(MiddlewareInterface::class, class_implements($value))) { if (!in_array(MiddlewareInterface::class, class_implements($value))) {
throw new \Exception('The middleware'); throw new \Exception('The middleware');
} }
$array[] = $value; $array[] = $value;
} }
$this->middleware = $array; $this->middleware = $array;
} }
/** /**
* @param mixed $class * @param mixed $class
* @param mixed|null $method * @param mixed|null $method
* @return $this * @return $this
* @throws \ReflectionException * @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);
} }
} }
+41 -41
View File
@@ -1,41 +1,41 @@
<?php <?php
namespace Kiri\Annotation\Route; namespace Kiri\Annotation\Route;
use Kiri\Annotation\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);
} }
} }
+31 -31
View File
@@ -1,31 +1,31 @@
<?php <?php
namespace Kiri\Annotation\Route; namespace Kiri\Annotation\Route;
use Kiri\Annotation\Attribute; use Kiri\Annotation\Attribute;
/** /**
* Class Socket * Class Socket
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_METHOD)] class Socket extends Attribute #[\Attribute(\Attribute::TARGET_METHOD)] class Socket extends Attribute
{ {
const CLOSE = 'CLOSE'; const CLOSE = 'CLOSE';
const MESSAGE = 'MESSAGE'; const MESSAGE = 'MESSAGE';
const HANDSHAKE = 'HANDSHAKE'; const HANDSHAKE = 'HANDSHAKE';
/** /**
* Socket constructor. * Socket constructor.
* @param string $event * @param string $event
* @param string|null $uri * @param string|null $uri
* @param string $version * @param string $version
*/ */
public function __construct(string $event, ?string $uri = null, string $version = 'v.1.0') public function __construct(string $event, ?string $uri = null, string $version = 'v.1.0')
{ {
} }
} }
+28 -28
View File
@@ -1,28 +1,28 @@
<?php <?php
namespace Kiri\Annotation; namespace Kiri\Annotation;
/** /**
* Class Target * Class Target
* @package Annotation * @package Annotation
*/ */
#[\Attribute(\Attribute::TARGET_CLASS)] class Target extends Attribute #[\Attribute(\Attribute::TARGET_CLASS)] class Target extends Attribute
{ {
const WORKER = 'worker'; const WORKER = 'worker';
const ALL = 'any'; const ALL = 'any';
const PROCESS = 'process'; const PROCESS = 'process';
const TASK = 'task'; const TASK = 'task';
/** /**
* @param string $only * @param string $only
*/ */
public function __construct(string $only = Target::ALL) public function __construct(string $only = Target::ALL)
{ {
} }
} }
+44 -44
View File
@@ -1,44 +1,44 @@
<?php <?php
namespace Kiri\Annotation; 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 Annotation * @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 -12
View File
@@ -1,12 +1,12 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
abstract class AbstractServer extends Component abstract class AbstractServer extends Component
{ {
public string $name = 'http'; public string $name = 'http';
} }
+451 -451
View File
@@ -1,451 +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 Database\Connection; use Database\Connection;
use Exception; use Exception;
use Http\Handler\Router; use Http\Handler\Router;
use Kafka\KafkaProvider; use Kafka\KafkaProvider;
use Kiri\{Async, Kiri}; use Kiri\{Async, Kiri};
use Kiri\Annotation\Annotation as SAnnotation; use Kiri\Annotation\Annotation as SAnnotation;
use Kiri\Cache\Redis; use Kiri\Cache\Redis;
use Kiri\Di\LocalService; use Kiri\Di\LocalService;
use Kiri\Error\{ErrorHandler, Logger}; use Kiri\Error\{ErrorHandler, Logger};
use Kiri\Exception\{InitException, NotFindClassException}; use Kiri\Exception\{InitException, NotFindClassException};
use ReflectionException; use ReflectionException;
use Server\{Contract\OnTaskInterface, Server, ServerManager, Tasker\AsyncTaskExecute}; use Server\{Contract\OnTaskInterface, Server, ServerManager, Tasker\AsyncTaskExecute};
use Swoole\Table; use Swoole\Table;
/** /**
* Class BaseApplication * Class BaseApplication
* @package Kiri\Kiri\Base * @package Kiri\Kiri\Base
*/ */
abstract class BaseApplication extends Component abstract class BaseApplication extends Component
{ {
use TraitApplication; use TraitApplication;
/** /**
* @var string * @var string
*/ */
public string $storage = APP_PATH . 'storage'; public string $storage = APP_PATH . 'storage';
public string $envPath = APP_PATH . '.env'; public string $envPath = APP_PATH . '.env';
/** /**
* Init constructor. * Init constructor.
* *
* *
* @throws * @throws
*/ */
public function __construct() public function __construct()
{ {
Kiri::init($this); Kiri::init($this);
$config = sweep(APP_PATH . '/config'); $config = sweep(APP_PATH . '/config');
$this->moreComponents(); $this->moreComponents();
$this->parseInt($config); $this->parseInt($config);
$this->parseEvents($config); $this->parseEvents($config);
$this->initErrorHandler(); $this->initErrorHandler();
$this->enableEnvConfig(); $this->enableEnvConfig();
$this->mapping($config['mapping'] ?? []); $this->mapping($config['mapping'] ?? []);
parent::__construct(); parent::__construct();
} }
/** /**
* @param array $mapping * @param array $mapping
*/ */
public function mapping(array $mapping) public function mapping(array $mapping)
{ {
$di = Kiri::getDi(); $di = Kiri::getDi();
foreach ($mapping as $interface => $class) { foreach ($mapping as $interface => $class) {
$di->mapping($interface, $class); $di->mapping($interface, $class);
} }
} }
/** /**
* @return array * @return array
*/ */
public function enableEnvConfig(): array public function enableEnvConfig(): array
{ {
if (!file_exists($this->envPath)) { if (!file_exists($this->envPath)) {
return []; return [];
} }
$lines = $this->readLinesFromFile($this->envPath); $lines = $this->readLinesFromFile($this->envPath);
foreach ($lines as $line) { foreach ($lines as $line) {
if (!$this->isComment($line) && $this->looksLikeSetter($line)) { if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
[$key, $value] = explode('=', $line); [$key, $value] = explode('=', $line);
putenv(trim($key) . '=' . trim($value)); putenv(trim($key) . '=' . trim($value));
} }
} }
return $lines; return $lines;
} }
/** /**
* Read lines from the file, auto detecting line endings. * Read lines from the file, auto detecting line endings.
* *
* @param string $filePath * @param string $filePath
* *
* @return array * @return array
*/ */
protected function readLinesFromFile(string $filePath): array protected function readLinesFromFile(string $filePath): array
{ {
// Read file into an array of lines with auto-detected line endings // Read file into an array of lines with auto-detected line endings
$autodetect = ini_get('auto_detect_line_endings'); $autodetect = ini_get('auto_detect_line_endings');
ini_set('auto_detect_line_endings', '1'); ini_set('auto_detect_line_endings', '1');
$lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
ini_set('auto_detect_line_endings', $autodetect); ini_set('auto_detect_line_endings', $autodetect);
return $lines; return $lines;
} }
/** /**
* Determine if the line in the file is a comment, e.g. begins with a #. * Determine if the line in the file is a comment, e.g. begins with a #.
* *
* @param string $line * @param string $line
* *
* @return bool * @return bool
*/ */
protected function isComment(string $line): bool protected function isComment(string $line): bool
{ {
$line = ltrim($line); $line = ltrim($line);
return isset($line[0]) && $line[0] === '#'; return isset($line[0]) && $line[0] === '#';
} }
/** /**
* Determine if the given line looks like it's setting a variable. * Determine if the given line looks like it's setting a variable.
* *
* @param string $line * @param string $line
* *
* @return bool * @return bool
*/ */
protected function looksLikeSetter(string $line): bool protected function looksLikeSetter(string $line): bool
{ {
return str_contains($line, '='); return str_contains($line, '=');
} }
/** /**
* @param $config * @param $config
* *
* @throws * @throws
*/ */
public function parseInt($config) public function parseInt($config)
{ {
Config::sets($config); Config::sets($config);
if ($storage = Config::get('storage', 'storage')) { if ($storage = Config::get('storage', 'storage')) {
if (!str_contains($storage, APP_PATH)) { if (!str_contains($storage, APP_PATH)) {
$storage = APP_PATH . $storage . '/'; $storage = APP_PATH . $storage . '/';
} }
if (!is_dir($storage)) { if (!is_dir($storage)) {
mkdir($storage); mkdir($storage);
} }
if (!is_dir($storage) || !is_writeable($storage)) { if (!is_dir($storage) || !is_writeable($storage)) {
throw new InitException("Directory {$storage} does not have write permission"); throw new InitException("Directory {$storage} does not have write permission");
} }
} }
} }
/** /**
* @param $name * @param $name
* @return mixed * @return mixed
* @throws ReflectionException * @throws ReflectionException
* @throws NotFindClassException * @throws NotFindClassException
* @throws Exception * @throws Exception
*/ */
public function __get($name): mixed public function __get($name): mixed
{ {
if ($this->has($name)) { if ($this->has($name)) {
return $this->get($name); return $this->get($name);
} }
return parent::__get($name); // TODO: Change the autogenerated stub return parent::__get($name); // TODO: Change the autogenerated stub
} }
/** /**
* @param $config * @param $config
* *
* @throws * @throws
*/ */
public function parseEvents($config) public function parseEvents($config)
{ {
if (!isset($config['events']) || !is_array($config['events'])) { if (!isset($config['events']) || !is_array($config['events'])) {
return; return;
} }
foreach ($config['events'] as $key => $value) { foreach ($config['events'] as $key => $value) {
if (is_string($value)) { if (is_string($value)) {
$value = Kiri::createObject($value); $value = Kiri::createObject($value);
} }
$this->addEvent($key, $value); $this->addEvent($key, $value);
} }
} }
/** /**
* @param OnTaskInterface $execute * @param OnTaskInterface $execute
* @throws ReflectionException * @throws ReflectionException
*/ */
public function task(OnTaskInterface $execute): void public function task(OnTaskInterface $execute): void
{ {
di(AsyncTaskExecute::class)->execute($execute); di(AsyncTaskExecute::class)->execute($execute);
} }
/** /**
* @param $key * @param $key
* @param $value * @param $value
* @throws InitException * @throws InitException
* @throws Exception * @throws Exception
*/ */
private function addEvent($key, $value): void private function addEvent($key, $value): void
{ {
if ($value instanceof \Closure || is_object($value)) { if ($value instanceof \Closure || is_object($value)) {
$this->eventProvider->on($key, $value, 0); $this->eventProvider->on($key, $value, 0);
return; return;
} }
if (is_array($value)) { if (is_array($value)) {
if (is_object($value[0]) && !($value[0] instanceof \Closure)) { if (is_object($value[0]) && !($value[0] instanceof \Closure)) {
$this->eventProvider->on($key, $value, 0); $this->eventProvider->on($key, $value, 0);
return; return;
} }
if (is_string($value[0])) { if (is_string($value[0])) {
$value[0] = Kiri::createObject($value[0]); $value[0] = Kiri::createObject($value[0]);
$this->eventProvider->on($key, $value, 0); $this->eventProvider->on($key, $value, 0);
return; return;
} }
foreach ($value as $item) { foreach ($value as $item) {
if (!is_callable($item, true)) { if (!is_callable($item, true)) {
throw new InitException("Class does not hav callback."); throw new InitException("Class does not hav callback.");
} }
$this->eventProvider->on($key, $item, 0); $this->eventProvider->on($key, $item, 0);
} }
} }
} }
/** /**
* @param $name * @param $name
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function clone($name): mixed public function clone($name): mixed
{ {
return clone $this->get($name); return clone $this->get($name);
} }
/** /**
* *
* @throws Exception * @throws Exception
*/ */
public function initErrorHandler() public function initErrorHandler()
{ {
$this->get('error')->register(); $this->get('error')->register();
} }
/** /**
* @param $name * @param $name
* @return mixed * @return mixed
* @throws * @throws
*/ */
public function get($name): mixed public function get($name): mixed
{ {
return di(LocalService::class)->get($name); return di(LocalService::class)->get($name);
} }
/** /**
* @return mixed * @return mixed
*/ */
public function getLocalIps(): mixed public function getLocalIps(): mixed
{ {
return swoole_get_local_ip(); return swoole_get_local_ip();
} }
/** /**
* @return mixed * @return mixed
*/ */
public function getFirstLocal(): mixed public function getFirstLocal(): mixed
{ {
return current($this->getLocalIps()); return current($this->getLocalIps());
} }
/** /**
* @return Logger * @return Logger
* @throws * @throws
*/ */
public function getLogger(): Logger public function getLogger(): Logger
{ {
return $this->get('logger'); return $this->get('logger');
} }
/** /**
* @return \Redis|Redis * @return \Redis|Redis
* @throws * @throws
*/ */
public function getRedis(): Redis|\Redis public function getRedis(): Redis|\Redis
{ {
return Kiri::getDi()->get(Redis::class); return Kiri::getDi()->get(Redis::class);
} }
/** /**
* @param $ip * @param $ip
* @return bool * @return bool
*/ */
public function isLocal($ip): bool public function isLocal($ip): bool
{ {
return $this->getFirstLocal() == $ip; return $this->getFirstLocal() == $ip;
} }
/** /**
* @return ErrorHandler * @return ErrorHandler
* @throws * @throws
*/ */
public function getError(): ErrorHandler public function getError(): ErrorHandler
{ {
return $this->get('error'); return $this->get('error');
} }
/** /**
* @param $name * @param $name
* @return Table * @return Table
* @throws * @throws
*/ */
public function getTable($name): Table public function getTable($name): Table
{ {
return $this->get($name); return $this->get($name);
} }
/** /**
* @return Config * @return Config
* @throws * @throws
*/ */
public function getConfig(): Config public function getConfig(): Config
{ {
return $this->get('config'); return $this->get('config');
} }
/** /**
* @return Router * @return Router
* @throws * @throws
*/ */
public function getRouter(): Router public function getRouter(): Router
{ {
return Kiri::getDi()->get(Router::class); return Kiri::getDi()->get(Router::class);
} }
/** /**
* @return Server * @return Server
* @throws * @throws
*/ */
public function getServer(): Server public function getServer(): Server
{ {
return $this->get('server'); return $this->get('server');
} }
/** /**
* @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null * @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
* @throws * @throws
*/ */
public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
{ {
return di(ServerManager::class)->getServer(); return di(ServerManager::class)->getServer();
} }
/** /**
* @return SAnnotation * @return SAnnotation
* @throws * @throws
*/ */
public function getAnnotation(): SAnnotation public function getAnnotation(): SAnnotation
{ {
return $this->get('Annotation'); return $this->get('Annotation');
} }
/** /**
* @return Async * @return Async
* @throws * @throws
*/ */
public function getAsync(): Async public function getAsync(): Async
{ {
return $this->get('async'); return $this->get('async');
} }
/** /**
* @param $array * @param $array
*/ */
private function setComponents($array): void private function setComponents($array): void
{ {
di(LocalService::class)->setComponents($array); di(LocalService::class)->setComponents($array);
} }
/** /**
* @param $id * @param $id
* @param $definition * @param $definition
*/ */
public function set($id, $definition): void public function set($id, $definition): void
{ {
di(LocalService::class)->set($id, $definition); di(LocalService::class)->set($id, $definition);
} }
/** /**
* @param $id * @param $id
* @return bool * @return bool
*/ */
public function has($id): bool public function has($id): bool
{ {
return di(LocalService::class)->has($id); return di(LocalService::class)->has($id);
} }
/** /**
* @throws Exception * @throws Exception
*/ */
protected function moreComponents(): void protected function moreComponents(): void
{ {
$this->setComponents([ $this->setComponents([
'error' => ['class' => ErrorHandler::class], 'error' => ['class' => ErrorHandler::class],
'config' => ['class' => Config::class], 'config' => ['class' => Config::class],
'logger' => ['class' => Logger::class], 'logger' => ['class' => Logger::class],
'Annotation' => ['class' => SAnnotation::class], 'Annotation' => ['class' => SAnnotation::class],
'databases' => ['class' => Connection::class], 'databases' => ['class' => Connection::class],
'jwt' => ['class' => Jwt::class], 'jwt' => ['class' => Jwt::class],
'async' => ['class' => Async::class], 'async' => ['class' => Async::class],
'kafka-container' => ['class' => KafkaProvider::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 -260
View File
@@ -1,260 +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\Events\EventDispatch; use Kiri\Events\EventDispatch;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Kiri; use Kiri\Kiri;
use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface; use Psr\Container\NotFoundExceptionInterface;
/** /**
* Class Component * Class Component
* @package Kiri\Kiri\Base * @package Kiri\Kiri\Base
* @property ContainerInterface|Container $container * @property ContainerInterface|Container $container
* @property EventProvider $eventProvider * @property EventProvider $eventProvider
* @property EventDispatch $eventDispatch * @property EventDispatch $eventDispatch
*/ */
class Component implements Configure class Component implements Configure
{ {
/** /**
* BaseAbstract constructor. * BaseAbstract constructor.
* *
* @param array $config * @param array $config
* @throws Exception * @throws Exception
*/ */
public function __construct(array $config = []) public function __construct(array $config = [])
{ {
if (!empty($config) && is_array($config)) { if (!empty($config) && is_array($config)) {
Kiri::configure($this, $config); Kiri::configure($this, $config);
} }
} }
/** /**
* @return Container|ContainerInterface * @return Container|ContainerInterface
*/ */
#[Pure] public function getContainer(): ContainerInterface|Container #[Pure] public function getContainer(): ContainerInterface|Container
{ {
return Kiri::getDi(); return Kiri::getDi();
} }
/** /**
* @return EventProvider * @return EventProvider
* @throws ContainerExceptionInterface * @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface * @throws NotFoundExceptionInterface
*/ */
public function getEventProvider(): EventProvider public function getEventProvider(): EventProvider
{ {
return $this->getContainer()->get(EventProvider::class); return $this->getContainer()->get(EventProvider::class);
} }
/** /**
* @return EventDispatch * @return EventDispatch
*/ */
protected function getEventDispatch(): EventDispatch protected function getEventDispatch(): EventDispatch
{ {
return Kiri::getDi()->get(EventDispatch::class); return Kiri::getDi()->get(EventDispatch::class);
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function init() public function init()
{ {
} }
/** /**
* @return string * @return string
*/ */
#[Pure] public static function className(): string #[Pure] public static function className(): string
{ {
return static::class; return static::class;
} }
/** /**
* @param $name * @param $name
* @param $value * @param $value
* *
* @throws Exception * @throws Exception
*/ */
public function __set($name, $value) public function __set($name, $value)
{ {
$method = 'set' . ucfirst($name); $method = 'set' . ucfirst($name);
if (method_exists($this, $method)) { if (method_exists($this, $method)) {
$this->{$method}($value); $this->{$method}($value);
} else { } else {
throw new Exception('The set name ' . $name . ' not find in class ' . static::class); throw new Exception('The set name ' . $name . ' not find in class ' . static::class);
} }
} }
/** /**
* @param $name * @param $name
* *
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function __get($name): mixed public function __get($name): mixed
{ {
$method = 'get' . ucfirst($name); $method = 'get' . ucfirst($name);
if (method_exists($this, $method)) { if (method_exists($this, $method)) {
return $this->$method(); return $this->$method();
} else { } else {
throw new Exception('The get name ' . $name . ' not find in class ' . static::class); throw new Exception('The get name ' . $name . ' not find in class ' . static::class);
} }
} }
/** /**
* @param $message * @param $message
* @param string $model * @param string $model
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function addError($message, string $model = 'app'): bool public function addError($message, string $model = 'app'): bool
{ {
if ($message instanceof \Throwable) { if ($message instanceof \Throwable) {
$this->error($message = jTraceEx($message)); $this->error($message = jTraceEx($message));
} else { } else {
if (!is_string($message)) { if (!is_string($message)) {
$message = json_encode($message, JSON_UNESCAPED_UNICODE); $message = json_encode($message, JSON_UNESCAPED_UNICODE);
} }
$this->error($message); $this->error($message);
} }
Kiri::app()->getLogger()->fail($message, $model); Kiri::app()->getLogger()->fail($message, $model);
return FALSE; return FALSE;
} }
/** /**
* @return Logger * @return Logger
* @throws Exception * @throws Exception
*/ */
private function logger(): Logger private function logger(): Logger
{ {
return Kiri::getDi()->get(Logger::class); return Kiri::getDi()->get(Logger::class);
} }
/** /**
* @param mixed $message * @param mixed $message
* @param string $method * @param string $method
* @param string $file * @param string $file
* @throws Exception * @throws Exception
*/ */
public function debug(mixed $message, string $method = '', string $file = '') public function debug(mixed $message, string $method = '', string $file = '')
{ {
if (!is_string($message)) { if (!is_string($message)) {
$message = print_r($message, true); $message = print_r($message, true);
} }
$context = []; $context = [];
if (!empty($method)) $context['method'] = $method; if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file; if (!empty($file)) $context['file'] = $file;
$this->logger()->debug($message, $context); $this->logger()->debug($message, $context);
} }
/** /**
* @param mixed $message * @param mixed $message
* @param string $method * @param string $method
* @param string $file * @param string $file
* @throws Exception * @throws Exception
*/ */
public function info(mixed $message, string $method = '', string $file = '') public function info(mixed $message, string $method = '', string $file = '')
{ {
if (!is_string($message)) { if (!is_string($message)) {
$message = print_r($message, true); $message = print_r($message, true);
} }
$context = []; $context = [];
if (!empty($method)) $context['method'] = $method; if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file; if (!empty($file)) $context['file'] = $file;
$this->logger()->info($message, $context); $this->logger()->info($message, $context);
} }
/** /**
* @param mixed $message * @param mixed $message
* @param string $method * @param string $method
* @param string $file * @param string $file
* @throws Exception * @throws Exception
*/ */
public function success(mixed $message, string $method = '', string $file = '') public function success(mixed $message, string $method = '', string $file = '')
{ {
if (!is_string($message)) { if (!is_string($message)) {
$message = print_r($message, true); $message = print_r($message, true);
} }
$context = []; $context = [];
if (!empty($method)) $context['method'] = $method; if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file; if (!empty($file)) $context['file'] = $file;
$this->logger()->notice($message, $context); $this->logger()->notice($message, $context);
} }
/** /**
* @param mixed $message * @param mixed $message
* @param string $method * @param string $method
* @param string $file * @param string $file
* @throws Exception * @throws Exception
*/ */
public function warning(mixed $message, string $method = '', string $file = '') public function warning(mixed $message, string $method = '', string $file = '')
{ {
if (!is_string($message)) { if (!is_string($message)) {
$message = print_r($message, true); $message = print_r($message, true);
} }
$context = []; $context = [];
if (!empty($method)) $context['method'] = $method; if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file; if (!empty($file)) $context['file'] = $file;
$this->logger()->critical($message, $context); $this->logger()->critical($message, $context);
} }
/** /**
* @param mixed $message * @param mixed $message
* @param null $method * @param null $method
* @param null $file * @param null $file
* @throws Exception * @throws Exception
*/ */
public function error(mixed $message, $method = null, $file = null) public function error(mixed $message, $method = null, $file = null)
{ {
if ($message instanceof \Throwable) { if ($message instanceof \Throwable) {
$message = $message->getMessage() . " on line " . $message->getLine() . " at file " . $message->getFile(); $message = $message->getMessage() . " on line " . $message->getLine() . " at file " . $message->getFile();
} }
$context = []; $context = [];
if (is_string($method)) { if (is_string($method)) {
$message = (empty($method) ? '' : $method . ': ') . $message; $message = (empty($method) ? '' : $method . ': ') . $message;
} else { } else {
if (is_null($method)) { if (is_null($method)) {
$method = []; $method = [];
} }
$context = $method; $context = $method;
} }
if (!empty($method)) $context['method'] = $method; if (!empty($method)) $context['method'] = $method;
if (!empty($file)) $context['file'] = $file; if (!empty($file)) $context['file'] = $file;
$this->logger()->error($message, $context); $this->logger()->error($message, $context);
} }
} }
+128 -128
View File
@@ -1,128 +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 Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
/** /**
* Class Config * Class Config
* @package Kiri\Kiri\Base * @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 static mixed $data = [];
/** /**
* @return mixed * @return mixed
*/ */
public static function getData(): mixed public static function getData(): mixed
{ {
return static::$data; return static::$data;
} }
/** /**
* @param $key * @param $key
* @param $value * @param $value
* @return mixed * @return mixed
*/ */
public static function setData($key, $value): mixed public static function setData($key, $value): mixed
{ {
return static::$data[$key] = $value; return static::$data[$key] = $value;
} }
/** /**
* @param array $configs * @param array $configs
*/ */
public static function sets(array $configs) public static function sets(array $configs)
{ {
if (empty($configs)) { if (empty($configs)) {
return; return;
} }
static::$data = $configs; static::$data = $configs;
} }
/** /**
* @param $key * @param $key
* @param bool $try * @param bool $try
* @param mixed|null $default * @param mixed|null $default
* @return mixed * @return mixed
* @throws ConfigException * @throws ConfigException
*/ */
public static function get($key, mixed $default = null, bool $try = FALSE): mixed public static function get($key, mixed $default = null, bool $try = FALSE): mixed
{ {
$instance = static::$data; $instance = static::$data;
if (!str_contains($key, '.')) { if (!str_contains($key, '.')) {
return $instance[$key] ?? $default; return $instance[$key] ?? $default;
} }
foreach (explode('.', $key) as $value) { foreach (explode('.', $key) as $value) {
if (empty($value)) { if (empty($value)) {
continue; continue;
} }
if (!isset($instance[$value])) { if (!isset($instance[$value])) {
if ($try) { if ($try) {
throw new ConfigException(sprintf(self::ERROR_MESSAGE, $key)); throw new ConfigException(sprintf(self::ERROR_MESSAGE, $key));
} }
return $default; return $default;
} }
if (!is_array($instance[$value])) { if (!is_array($instance[$value])) {
return $instance[$value]; return $instance[$value];
} }
$instance = $instance[$value]; $instance = $instance[$value];
} }
return empty($instance) ? $default : $instance; return empty($instance) ? $default : $instance;
} }
/** /**
* @param $key * @param $key
* @param $value * @param $value
* @return mixed * @return mixed
*/ */
public static function set($key, $value): mixed public static function set($key, $value): mixed
{ {
$explode = explode('.', $key); $explode = explode('.', $key);
$parent = &static::$data; $parent = &static::$data;
foreach ($explode as $item) { foreach ($explode as $item) {
if (!isset($parent[$item])) { if (!isset($parent[$item])) {
$parent[$item] = []; $parent[$item] = [];
} }
$parent = &$parent[$item]; $parent = &$parent[$item];
} }
$parent = $value; $parent = $value;
unset($parent); unset($parent);
return static::$data; return static::$data;
} }
/** /**
* @param $key * @param $key
* @param bool $must_not_null * @param bool $must_not_null
* @return bool * @return bool
*/ */
public static function has($key, bool $must_not_null = false): bool public static function has($key, bool $must_not_null = false): bool
{ {
if (!isset(static::$data[$key])) { if (!isset(static::$data[$key])) {
return false; return false;
} }
$config = static::$data[$key]; $config = static::$data[$key];
if ($must_not_null === false) { if ($must_not_null === false) {
return true; return true;
} }
return !empty($config); 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 -229
View File
@@ -1,229 +1,229 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use DirectoryIterator; use DirectoryIterator;
use Exception; use Exception;
use Kiri\Events\EventProvider; use Kiri\Events\EventProvider;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri\Kiri;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use ReflectionException; use ReflectionException;
use Server\Events\OnWorkerStop; use Server\Events\OnWorkerStop;
/** /**
* *
*/ */
class Logger implements LoggerInterface class Logger implements LoggerInterface
{ {
const EMERGENCY = 'emergency'; const EMERGENCY = 'emergency';
const ALERT = 'alert'; const ALERT = 'alert';
const CRITICAL = 'critical'; const CRITICAL = 'critical';
const ERROR = 'error'; const ERROR = 'error';
const WARNING = 'warning'; const WARNING = 'warning';
const NOTICE = 'notice'; const NOTICE = 'notice';
const INFO = 'info'; const INFO = 'info';
const DEBUG = 'debug'; const DEBUG = 'debug';
private array $_loggers = []; private array $_loggers = [];
const LOGGER_LEVELS = [Logger::EMERGENCY, Logger::ALERT, Logger::CRITICAL, Logger::ERROR, Logger::WARNING, Logger::NOTICE, Logger::INFO, Logger::DEBUG]; const LOGGER_LEVELS = [Logger::EMERGENCY, Logger::ALERT, Logger::CRITICAL, Logger::ERROR, Logger::WARNING, Logger::NOTICE, Logger::INFO, Logger::DEBUG];
/** /**
* @return void * @return void
* @throws ReflectionException * @throws ReflectionException
*/ */
public function init() public function init()
{ {
Kiri::getDi()->get(EventProvider::class)->on(OnWorkerStop::class, [$this, 'onAfterRequest']); Kiri::getDi()->get(EventProvider::class)->on(OnWorkerStop::class, [$this, 'onAfterRequest']);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
* *
* 紧急情况 * 紧急情况
*/ */
public function emergency($message, array $context = []) public function emergency($message, array $context = [])
{ {
// TODO: Implement emergency() method. // TODO: Implement emergency() method.
$this->log(Logger::EMERGENCY, $message, $context); $this->log(Logger::EMERGENCY, $message, $context);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
* *
* 应该警惕的 * 应该警惕的
*/ */
public function alert($message, array $context = []) public function alert($message, array $context = [])
{ {
// TODO: Implement alert() method. // TODO: Implement alert() method.
$this->log(Logger::ALERT, $message, $context); $this->log(Logger::ALERT, $message, $context);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
* *
* 关键性的日志 * 关键性的日志
*/ */
public function critical($message, array $context = []) public function critical($message, array $context = [])
{ {
// TODO: Implement critical() method. // TODO: Implement critical() method.
$this->log(Logger::CRITICAL, $message, $context); $this->log(Logger::CRITICAL, $message, $context);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
*/ */
public function error($message, array $context = []) public function error($message, array $context = [])
{ {
// TODO: Implement error() method. // TODO: Implement error() method.
$this->log(Logger::ERROR, $message, $context); $this->log(Logger::ERROR, $message, $context);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
*/ */
public function warning($message, array $context = []) public function warning($message, array $context = [])
{ {
// TODO: Implement warning() method. // TODO: Implement warning() method.
$this->log(Logger::WARNING, $message, $context); $this->log(Logger::WARNING, $message, $context);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
*/ */
public function notice($message, array $context = []) public function notice($message, array $context = [])
{ {
// TODO: Implement notice() method. // TODO: Implement notice() method.
$this->log(Logger::NOTICE, $message, $context); $this->log(Logger::NOTICE, $message, $context);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
*/ */
public function info($message, array $context = []) public function info($message, array $context = [])
{ {
// TODO: Implement info() method. // TODO: Implement info() method.
$this->log(Logger::INFO, $message, $context); $this->log(Logger::INFO, $message, $context);
} }
/** /**
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
*/ */
public function debug($message, array $context = []) public function debug($message, array $context = [])
{ {
// TODO: Implement debug() method. // TODO: Implement debug() method.
$this->log(Logger::DEBUG, $message, $context); $this->log(Logger::DEBUG, $message, $context);
} }
/** /**
* @param mixed $level * @param mixed $level
* @param string $message * @param string $message
* @param array $context * @param array $context
* @throws ConfigException * @throws ConfigException
*/ */
public function log($level, $message, array $context = []) public function log($level, $message, array $context = [])
{ {
// TODO: Implement log() method. // TODO: Implement log() method.
$levels = Config::get('log.level', Logger::LOGGER_LEVELS); $levels = Config::get('log.level', Logger::LOGGER_LEVELS);
if (!in_array($level, $levels) || str_contains($message, 'Event::rshutdown')) { if (!in_array($level, $levels) || str_contains($message, 'Event::rshutdown')) {
return; return;
} }
$_string = '[' . now() . '] production.' . $level . ': ' . $this->_string($message, $context); $_string = '[' . now() . '] production.' . $level . ': ' . $this->_string($message, $context);
file_put_contents('php://output', $_string); file_put_contents('php://output', $_string);
$this->_loggers[] = $_string; $this->_loggers[] = $_string;
} }
/** /**
* @param OnWorkerStop $param * @param OnWorkerStop $param
* @throws Exception * @throws Exception
*/ */
public function onAfterRequest(OnWorkerStop $param) public function onAfterRequest(OnWorkerStop $param)
{ {
$loggers = implode(PHP_EOL, $this->_loggers); $loggers = implode(PHP_EOL, $this->_loggers);
$this->_loggers = []; $this->_loggers = [];
if (!empty($loggers)) { if (!empty($loggers)) {
$filename = storage('log-' . date('Y-m-d') . '.log', 'log/'); $filename = storage('log-' . date('Y-m-d') . '.log', 'log/');
file_put_contents($filename, $loggers); file_put_contents($filename, $loggers);
} }
} }
/** /**
* @return void * @return void
* @throws Exception * @throws Exception
*/ */
public function flush() public function flush()
{ {
$this->removeFile(storage()); $this->removeFile(storage());
} }
/** /**
* @param string $dirname * @param string $dirname
* @return void * @return void
*/ */
private function removeFile(string $dirname) private function removeFile(string $dirname)
{ {
$paths = new DirectoryIterator($dirname); $paths = new DirectoryIterator($dirname);
/** @var DirectoryIterator $path */ /** @var DirectoryIterator $path */
foreach ($paths as $path) { foreach ($paths as $path) {
if ($path->isDot() || str_starts_with($path->getFilename(), '.')) { if ($path->isDot() || str_starts_with($path->getFilename(), '.')) {
continue; continue;
} }
if ($path->isDir()) { if ($path->isDir()) {
$directory = rtrim($path->getRealPath(), '/'); $directory = rtrim($path->getRealPath(), '/');
$this->removeFile($directory); $this->removeFile($directory);
} }
@unlink($path->getRealPath()); @unlink($path->getRealPath());
} }
} }
/** /**
* @param $message * @param $message
* @param $context * @param $context
* @return string * @return string
*/ */
private function _string($message, $context): string private function _string($message, $context): string
{ {
if (!empty($context)) { if (!empty($context)) {
return $message . ' ' . PHP_EOL . print_r($context, TRUE) . PHP_EOL; return $message . ' ' . PHP_EOL . print_r($context, TRUE) . PHP_EOL;
} }
return $message . 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 -32
View File
@@ -1,32 +1,32 @@
<?php <?php
namespace Kiri\Abstracts; namespace Kiri\Abstracts;
use Kiri\Annotation\Annotation as SAnnotation; use Kiri\Annotation\Annotation as SAnnotation;
use Database\Connection; use Database\Connection;
use Database\DatabasesProviders; use Database\DatabasesProviders;
use Http\Handler\Router; use Http\Handler\Router;
use Server\Server; use Server\Server;
use Kiri\Async; use Kiri\Async;
use Kiri\Error\Logger; use Kiri\Error\Logger;
use Kiri\Jwt\JWTAuth; use Kiri\Jwt\JWTAuth;
/** /**
* Trait TraitApplication * Trait TraitApplication
* @package Kiri\Abstracts * @package Kiri\Abstracts
* @property Router $router * @property Router $router
* @property Server $server * @property Server $server
* @property DatabasesProviders $db * @property DatabasesProviders $db
* @property Async $async * @property Async $async
* @property Logger $logger * @property Logger $logger
* @property JWTAuth $jwt * @property JWTAuth $jwt
* @property SAnnotation $annotation * @property SAnnotation $annotation
* @property BaseGoto $goto * @property BaseGoto $goto
* @property Connection $databases * @property Connection $databases
*/ */
trait TraitApplication trait TraitApplication
{ {
} }
+253 -253
View File
@@ -1,253 +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, Config, Kernel}; use Kiri\Abstracts\{BaseApplication, Config, Kernel};
use Kiri\Crontab\CrontabProviders; use Kiri\Crontab\CrontabProviders;
use Kiri\Events\{OnAfterCommandExecute, OnBeforeCommandExecute}; use Kiri\Events\{OnAfterCommandExecute, OnBeforeCommandExecute};
use Kiri\FileListen\HotReload; use Kiri\FileListen\HotReload;
use ReflectionException; use ReflectionException;
use Server\ServerProviders; use Server\ServerProviders;
use stdClass; use stdClass;
use Swoole\Process; use Swoole\Process;
use Swoole\Timer; use Swoole\Timer;
use Symfony\Component\Console\{Application as ConsoleApplication, use Symfony\Component\Console\{Application as ConsoleApplication,
Command\Command, Command\Command,
Input\ArgvInput, Input\ArgvInput,
Input\InputInterface, Input\InputInterface,
Output\ConsoleOutput, Output\ConsoleOutput,
Output\OutputInterface Output\OutputInterface
}; };
/** /**
* 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>> */ /** @var array<array<Process>> */
private 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 string $class
* @param Process $process * @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 * @param string $class
* @return Process|null * @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 = $container->get(ConsoleApplication::class);
$console->add($container->get(HotReload::class)); $console->add($container->get(HotReload::class));
} }
/** /**
* @param Closure|array $closure * @param Closure|array $closure
* @return $this * @return $this
* @throws Exception * @throws Exception
*/ */
public function middleware(Closure|array $closure): static public function middleware(Closure|array $closure): static
{ {
return $this; return $this;
} }
/** /**
* @param bool $useTree * @param bool $useTree
* @return $this * @return $this
* @throws Exception * @throws Exception
*/ */
public function setUseTree(bool $useTree): static public function setUseTree(bool $useTree): static
{ {
return $this; return $this;
} }
/** /**
* @param string $service * @param string $service
* @return $this * @return $this
* @throws * @throws
*/ */
public function import(string $service): static public function import(string $service): static
{ {
if (!class_exists($service)) { if (!class_exists($service)) {
return $this; return $this;
} }
$class = Kiri::getDi()->get($service); $class = Kiri::getDi()->get($service);
if (method_exists($class, 'onImport')) { if (method_exists($class, 'onImport')) {
$class->onImport($this); $class->onImport($this);
} }
return $this; return $this;
} }
/** /**
* @param Kernel $kernel * @param Kernel $kernel
* @return $this * @return $this
*/ */
public function commands(Kernel $kernel): static public function commands(Kernel $kernel): static
{ {
foreach ($kernel->getCommands() as $command) { foreach ($kernel->getCommands() as $command) {
$this->register($command); $this->register($command);
} }
return $this; return $this;
} }
/** /**
* @param string $command * @param string $command
* @throws * @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 * @param array $argv
* @return void * @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_preemptive_scheduler', 'On');
ini_set('swoole.enable_library', 'On'); ini_set('swoole.enable_library', 'On');
[$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 * @param $argv
* @return array * @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 ReflectionException
* @throws Exception * @throws Exception
*/ */
private function enableFileChange(Command $class, $input, $output): void private function enableFileChange(Command $class, $input, $output): void
{ {
fire(new OnBeforeCommandExecute()); fire(new OnBeforeCommandExecute());
if (!($class instanceof HotReload)) { if (!($class instanceof HotReload)) {
scan_directory(directory('app'), 'App'); scan_directory(directory('app'), 'App');
} }
$this->container->setBindings(OutputInterface::class, $output); $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 $className
* @param null $abstracts * @param null $abstracts
* @return stdClass * @return stdClass
* @throws Exception * @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 -186
View File
@@ -1,186 +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 Kiri\Annotation\Inject; use Kiri\Annotation\Inject;
use Server\Events\OnWorkerExit; use Server\Events\OnWorkerExit;
use Swoole\Timer; use Swoole\Timer;
/** /**
* Class Redis * Class Redis
* @package Kiri\Kiri\Cache * @package Kiri\Kiri\Cache
* @mixin \Redis * @mixin \Redis
*/ */
class Redis extends Component class Redis extends Component
{ {
const REDIS_OPTION_HOST = 'host'; const REDIS_OPTION_HOST = 'host';
const REDIS_OPTION_PORT = 'port'; const REDIS_OPTION_PORT = 'port';
const REDIS_OPTION_PREFIX = 'prefix'; const REDIS_OPTION_PREFIX = 'prefix';
const REDIS_OPTION_AUTH = 'auth'; const REDIS_OPTION_AUTH = 'auth';
const REDIS_OPTION_DATABASES = 'databases'; const REDIS_OPTION_DATABASES = 'databases';
const REDIS_OPTION_TIMEOUT = 'timeout'; const REDIS_OPTION_TIMEOUT = 'timeout';
const REDIS_OPTION_POOL = 'pool'; const REDIS_OPTION_POOL = 'pool';
const REDIS_OPTION_POOL_TICK = 'tick'; const REDIS_OPTION_POOL_TICK = 'tick';
const REDIS_OPTION_POOL_MIN = 'min'; const REDIS_OPTION_POOL_MIN = 'min';
const REDIS_OPTION_POOL_MAX = 'max'; const REDIS_OPTION_POOL_MAX = 'max';
/** /**
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function init() public function init()
{ {
$connections = Kiri::getDi()->get(PoolRedis::class); $connections = Kiri::getDi()->get(PoolRedis::class);
$config = $this->get_config(); $config = $this->get_config();
$length = Config::get('cache.redis.pool.max', 10); $length = Config::get('cache.redis.pool.max', 10);
$this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0); $this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0);
$connections->initConnections('Redis:' . $config['host'], true, $length); $connections->initConnections('Redis:' . $config['host'], true, $length);
} }
/** /**
* @param $name * @param $name
* @param $arguments * @param $arguments
* @return mixed * @return mixed
* @throws * @throws
*/ */
public function __call($name, $arguments): mixed public function __call($name, $arguments): mixed
{ {
$time = microtime(true); $time = microtime(true);
if (method_exists($this, $name)) { if (method_exists($this, $name)) {
$data = $this->{$name}(...$arguments); $data = $this->{$name}(...$arguments);
} else { } else {
$data = $this->proxy($name, $arguments); $data = $this->proxy($name, $arguments);
} }
if (microtime(true) - $time >= 0.02) { if (microtime(true) - $time >= 0.02) {
$this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time)); $this->warning('Redis:' . Json::encode([$name, $arguments]) . (microtime(true) - $time));
} }
return $data; return $data;
} }
/** /**
* @param $key * @param $key
* @param int $timeout * @param int $timeout
* @return bool * @return bool
*/ */
public function waite($key, int $timeout = 5): bool public function waite($key, int $timeout = 5): bool
{ {
$time = time(); $time = time();
while (!$this->setNx($key, 1)) { while (!$this->setNx($key, 1)) {
if (time()- $time >= $timeout) { if (time()- $time >= $timeout) {
return FALSE; return FALSE;
} }
usleep(1000); usleep(1000);
} }
$this->expire($key, $timeout); $this->expire($key, $timeout);
return TRUE; return TRUE;
} }
/** /**
* @param $key * @param $key
* @param int $timeout * @param int $timeout
* @return bool|int * @return bool|int
* @throws Exception * @throws Exception
*/ */
public function lock($key, int $timeout = 5): bool|int public function lock($key, int $timeout = 5): bool|int
{ {
$script = <<<SCRIPT $script = <<<SCRIPT
local _nx = redis.call('setnx',KEYS[1], ARGV[1]) local _nx = redis.call('setnx',KEYS[1], ARGV[1])
if (_nx ~= 0) then if (_nx ~= 0) then
redis.call('expire',KEYS[1], ARGV[1]) redis.call('expire',KEYS[1], ARGV[1])
return 1 return 1
end end
return 0 return 0
SCRIPT; SCRIPT;
return $this->eval($script, ['{lock}:' . $key, $timeout], 1); return $this->eval($script, ['{lock}:' . $key, $timeout], 1);
} }
/** /**
* @param $key * @param $key
* @return int * @return int
* @throws Exception * @throws Exception
*/ */
public function unlock($key): int public function unlock($key): int
{ {
return $this->del('{lock}:' . $key); return $this->del('{lock}:' . $key);
} }
/** /**
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function release() public function release()
{ {
$connections = Kiri::getDi()->get(PoolRedis::class); $connections = Kiri::getDi()->get(PoolRedis::class);
$connections->release($this->get_config(), true); $connections->release($this->get_config(), true);
} }
/** /**
* 销毁连接池 * 销毁连接池
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function destroy() public function destroy()
{ {
$connections = Kiri::getDi()->get(PoolRedis::class); $connections = Kiri::getDi()->get(PoolRedis::class);
$connections->connection_clear($this->get_config(), true); $connections->connection_clear($this->get_config(), true);
} }
/** /**
* @param $name * @param $name
* @param $arguments * @param $arguments
* @return mixed * @return mixed
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public function proxy($name, $arguments): mixed public function proxy($name, $arguments): mixed
{ {
$connections = Kiri::getDi()->get(PoolRedis::class); $connections = Kiri::getDi()->get(PoolRedis::class);
$config = $this->get_config(); $config = $this->get_config();
$client = $connections->get($config, true); $client = $connections->get($config, true);
if (!($client instanceof Base\Redis)) { if (!($client instanceof Base\Redis)) {
throw new Exception('Redis connections more.'); throw new Exception('Redis connections more.');
} }
$response = $client->{$name}(...$arguments); $response = $client->{$name}(...$arguments);
$this->release(); $this->release();
return $response; return $response;
} }
/** /**
* @return array * @return array
* @throws ConfigException * @throws ConfigException
*/ */
public function get_config(): array public function get_config(): array
{ {
return Config::get('cache.redis', null, true); return Config::get('cache.redis', null, true);
} }
} }
+209 -209
View File
@@ -1,209 +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 (is_null($coroutineId)) { if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid(); $coroutineId = Coroutine::getCid();
} }
if (Coroutine::getCid() !== -1) { if (Coroutine::getCid() !== -1) {
return Coroutine::getContext($coroutineId)[$id] = $context; return Coroutine::getContext($coroutineId)[$id] = $context;
} }
return static::$_contents[$id] = $context; return static::$_contents[$id] = $context;
} }
/** /**
* @param $id * @param $id
* @param int $value * @param int $value
* @param null $coroutineId * @param null $coroutineId
* @return bool|int * @return bool|int
*/ */
public static function increment($id, int $value = 1, $coroutineId = null): bool|int public static function increment($id, int $value = 1, $coroutineId = null): bool|int
{ {
if (is_null($coroutineId)) { if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid(); $coroutineId = Coroutine::getCid();
} }
if (!isset(Coroutine::getContext($coroutineId)[$id])) { if (!isset(Coroutine::getContext($coroutineId)[$id])) {
Coroutine::getContext($coroutineId)[$id] = 0; Coroutine::getContext($coroutineId)[$id] = 0;
} }
return Coroutine::getContext($coroutineId)[$id] += $value; return Coroutine::getContext($coroutineId)[$id] += $value;
} }
/** /**
* @param $id * @param $id
* @param int $value * @param int $value
* @param null $coroutineId * @param null $coroutineId
* @return bool|int * @return bool|int
*/ */
public static function decrement($id, int $value = 1, $coroutineId = null): bool|int public static function decrement($id, int $value = 1, $coroutineId = null): bool|int
{ {
if (is_null($coroutineId)) { if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid(); $coroutineId = Coroutine::getCid();
} }
if (!isset(Coroutine::getContext($coroutineId)[$id])) { if (!isset(Coroutine::getContext($coroutineId)[$id])) {
Coroutine::getContext($coroutineId)[$id] = 0; Coroutine::getContext($coroutineId)[$id] = 0;
} }
return Coroutine::getContext($coroutineId)[$id] -= $value; return Coroutine::getContext($coroutineId)[$id] -= $value;
} }
/** /**
* @param $id * @param $id
* @param null $default * @param null $default
* @param null $coroutineId * @param null $coroutineId
* @return mixed * @return mixed
*/ */
public static function getContext($id, $default = null, $coroutineId = null): mixed public static function getContext($id, $default = null, $coroutineId = null): mixed
{ {
if (Coroutine::getCid() === -1) { if (Coroutine::getCid() === -1) {
return static::loadByStatic($id, $default); return static::loadByStatic($id, $default);
} }
return static::loadByContext($id, $default, $coroutineId); return static::loadByContext($id, $default, $coroutineId);
} }
/** /**
* @param $id * @param $id
* @param null $default * @param null $default
* @param null $coroutineId * @param null $coroutineId
* @return mixed * @return mixed
*/ */
private static function loadByContext($id, $default = null, $coroutineId = null): mixed private static function loadByContext($id, $default = null, $coroutineId = null): mixed
{ {
if (is_null($coroutineId)) { if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid(); $coroutineId = Coroutine::getCid();
} }
return Coroutine::getContext($coroutineId)[$id] ?? $default; return Coroutine::getContext($coroutineId)[$id] ?? $default;
} }
/** /**
* @param $id * @param $id
* @param null $default * @param null $default
* @return mixed * @return mixed
*/ */
private static function loadByStatic($id, $default = null): mixed private static function loadByStatic($id, $default = null): mixed
{ {
return static::$_contents[$id] ?? $default; return static::$_contents[$id] ?? $default;
} }
/** /**
* @param null $coroutineId * @param null $coroutineId
* @return mixed * @return mixed
*/ */
public static function getAllContext($coroutineId = null): mixed public static function getAllContext($coroutineId = null): mixed
{ {
if (Coroutine::getCid() === -1) { if (Coroutine::getCid() === -1) {
return Coroutine::getContext($coroutineId) ?? []; return Coroutine::getContext($coroutineId) ?? [];
} else { } else {
return static::$_contents ?? []; return static::$_contents ?? [];
} }
} }
/** /**
* @param string $id * @param string $id
* @param null $coroutineId * @param null $coroutineId
*/ */
public static function remove(string $id, $coroutineId = null) public static function remove(string $id, $coroutineId = null)
{ {
if (is_null($coroutineId)) { if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid(); $coroutineId = Coroutine::getCid();
} }
if (!static::hasContext($id, $coroutineId)) { if (!static::hasContext($id, $coroutineId)) {
return; return;
} }
if (Coroutine::getCid() === -1) { if (Coroutine::getCid() === -1) {
unset(static::$_contents[$id]); unset(static::$_contents[$id]);
} else { } else {
unset(Coroutine::getContext($coroutineId)[$id]); unset(Coroutine::getContext($coroutineId)[$id]);
} }
} }
/** /**
* @param $id * @param $id
* @param null $key * @param null $key
* @param null $coroutineId * @param null $coroutineId
* @return bool * @return bool
*/ */
public static function hasContext($id, $key = null, $coroutineId = null): bool public static function hasContext($id, $key = null, $coroutineId = null): bool
{ {
if (Coroutine::getCid() === -1) { if (Coroutine::getCid() === -1) {
return static::searchByStatic($id, $key); return static::searchByStatic($id, $key);
} }
return static::searchByCoroutine($id, $key, $coroutineId); return static::searchByCoroutine($id, $key, $coroutineId);
} }
/** /**
* @param $id * @param $id
* @param null $key * @param null $key
* @return bool * @return bool
*/ */
private static function searchByStatic($id, $key = null): bool private static function searchByStatic($id, $key = null): bool
{ {
if (!isset(static::$_contents[$id])) { if (!isset(static::$_contents[$id])) {
return false; return false;
} }
$value = static::$_contents[$id]; $value = static::$_contents[$id];
if (!empty($key) && is_array($value)) { if (!empty($key) && is_array($value)) {
return isset($value[$key]); return isset($value[$key]);
} }
return true; return true;
} }
/** /**
* @param $id * @param $id
* @param null $key * @param null $key
* @param null $coroutineId * @param null $coroutineId
* @return bool * @return bool
*/ */
private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool
{ {
if (is_null($coroutineId)) { if (is_null($coroutineId)) {
$coroutineId = Coroutine::getCid(); $coroutineId = Coroutine::getCid();
} }
if (!isset(Coroutine::getContext($coroutineId)[$id])) { if (!isset(Coroutine::getContext($coroutineId)[$id])) {
return false; return false;
} }
$value = Coroutine::getContext($coroutineId)[$id]; $value = Coroutine::getContext($coroutineId)[$id];
if ($key !== null && is_array($value)) { if ($key !== null && is_array($value)) {
return isset($value[$key]); return isset($value[$key]);
} }
return true; return true;
} }
/** /**
* @return bool * @return bool
*/ */
public static function inCoroutine(): bool public static function inCoroutine(): bool
{ {
return Coroutine::getCid() !== -1; 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 -104
View File
@@ -1,104 +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((string)$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;
} }
return date('t', $time); return date('t', $time);
} }
/** /**
* @param $startTime * @param $startTime
* @param null $endTime * @param null $endTime
* @return string * @return string
*/ */
public static function mtime($startTime, $endTime = null) public static function mtime($startTime, $endTime = null)
{ {
if ($endTime === null) { if ($endTime === null) {
$endTime = microtime(true); $endTime = microtime(true);
} }
return sprintf('%.7f', $endTime - $startTime); return sprintf('%.7f', $endTime - $startTime);
} }
} }
+58 -58
View File
@@ -1,58 +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 * @throws Exception
*/ */
public function __construct($params) public function __construct($params)
{ {
parent::__construct([]); parent::__construct([]);
$this->params = $params; $this->params = $params;
} }
/** /**
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function toArray(): array public function toArray(): array
{ {
return $this->params; return $this->params;
} }
/** /**
* @param $name * @param $name
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function get($name): mixed public function get($name): mixed
{ {
$array = $this->toArray(); $array = $this->toArray();
if (!isset($array[$name])) { if (!isset($array[$name])) {
return null; return null;
} }
return $array[$name]; return $array[$name];
} }
} }
+101 -101
View File
@@ -1,101 +1,101 @@
<?php <?php
namespace Kiri\Core; namespace Kiri\Core;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use ReturnTypeWillChange; use ReturnTypeWillChange;
class HashMap implements \ArrayAccess class HashMap implements \ArrayAccess
{ {
/** /**
* @var array * @var array
*/ */
private array $lists = []; private array $lists = [];
/** /**
* @param string $key * @param string $key
* @param $value * @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 * @param string $key
* @return mixed * @return mixed
*/ */
#[Pure] public function get(string $key): mixed #[Pure] public function get(string $key): mixed
{ {
if (!$this->has($key)) { if (!$this->has($key)) {
return null; 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)) { if (!$this->has($key)) {
return; return;
} }
unset($this->lists[$key]); unset($this->lists[$key]);
} }
/** /**
* @param string $key * @param string $key
* @return bool * @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 * @param mixed $offset
* @return bool * @return bool
*/ */
public function offsetExists(mixed $offset): bool public function offsetExists(mixed $offset): bool
{ {
return isset($this->lists[$offset]); return isset($this->lists[$offset]);
} }
/** /**
* @param mixed $offset * @param mixed $offset
* @return mixed * @return mixed
*/ */
#[Pure] public function offsetGet(mixed $offset): mixed #[Pure] public function offsetGet(mixed $offset): mixed
{ {
return $this->get($offset); return $this->get($offset);
} }
/** /**
* @param mixed $offset * @param mixed $offset
* @param mixed $value * @param mixed $value
*/ */
#[ReturnTypeWillChange] #[ReturnTypeWillChange]
public function offsetSet(mixed $offset, mixed $value) public function offsetSet(mixed $offset, mixed $value)
{ {
$this->put($offset, $value); $this->put($offset, $value);
} }
/** /**
* @param mixed $offset * @param mixed $offset
*/ */
#[ReturnTypeWillChange] #[ReturnTypeWillChange]
public function offsetUnset(mixed $offset) public function offsetUnset(mixed $offset)
{ {
unset($this->lists[$offset]); unset($this->lists[$offset]);
} }
} }
+219 -219
View File
@@ -1,219 +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 * @throws Exception
*/ */
public static function toArray($xml): mixed public static function toArray($xml): mixed
{ {
if (empty($xml)) { if (empty($xml)) {
return []; return [];
} else if (is_array($xml)) { } else if (is_array($xml)) {
return $xml; return $xml;
} }
if (!($_xml = Xml::isXml($xml))) { if (!($_xml = Xml::isXml($xml))) {
return static::jsonToArray($xml); return static::jsonToArray($xml);
} }
return $_xml; return $_xml;
} }
/** /**
* @param $xml * @param $xml
* @return mixed * @return mixed
*/ */
public static function jsonToArray($xml): mixed public static function jsonToArray($xml): mixed
{ {
$_xml = json_decode($xml, true); $_xml = json_decode($xml, true);
if (is_null($_xml)) { if (is_null($_xml)) {
return []; return [];
} }
return $_xml; return $_xml;
} }
/** /**
* @param $xml * @param $xml
* @return mixed * @return mixed
*/ */
public static function xmlToArray($xml): mixed public static function xmlToArray($xml): mixed
{ {
if (is_array($xml)) { if (is_array($xml)) {
return $xml; return $xml;
} }
if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) { if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) {
return json_decode(json_encode($data), TRUE); return json_decode(json_encode($data), TRUE);
} }
if (!is_null($json = json_decode($xml, TRUE))) { if (!is_null($json = json_decode($xml, TRUE))) {
return $json; return $json;
} }
return $xml; return $xml;
} }
/** /**
* @param $parameter * @param $parameter
* @return array|false|string * @return array|false|string
* @throws Exception * @throws Exception
*/ */
public static function toString($parameter): bool|array|string public static function toString($parameter): bool|array|string
{ {
if (!is_string($parameter)) { if (!is_string($parameter)) {
$parameter = ArrayAccess::toArray($parameter); $parameter = ArrayAccess::toArray($parameter);
if (is_array($parameter)) { if (is_array($parameter)) {
$parameter = Json::encode($parameter); $parameter = Json::encode($parameter);
} }
} }
return $parameter; return $parameter;
} }
/** /**
* @param mixed $json * @param mixed $json
* @return bool|string * @return bool|string
*/ */
public static function toJson(mixed $json): bool|string public static function toJson(mixed $json): bool|string
{ {
if (is_object($json)) { if (is_object($json)) {
$json = get_object_vars($json); $json = get_object_vars($json);
} }
if (is_array($json)) { if (is_array($json)) {
return json_encode($json, JSON_UNESCAPED_UNICODE); return json_encode($json, JSON_UNESCAPED_UNICODE);
} }
$matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><!.*?><\/\4>)+<\/\2>/'; $matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><!.*?><\/\4>)+<\/\2>/';
if (preg_match($matchQuote, $json)) { if (preg_match($matchQuote, $json)) {
$json = self::xmlToArray($json); $json = self::xmlToArray($json);
} else { } else {
$json = json_decode($json, true); $json = json_decode($json, true);
} }
if (!is_array($json)) { if (!is_array($json)) {
$json = []; $json = [];
} }
return json_encode($json, JSON_UNESCAPED_UNICODE); return json_encode($json, JSON_UNESCAPED_UNICODE);
} }
/** /**
* @param int $length * @param int $length
* @return string * @return string
* *
* 随机字符串 * 随机字符串
*/ */
public static function random($length = 20): string public static function random($length = 20): string
{ {
$res = []; $res = [];
$str = 'abcdefghijklmnopqrstuvwxyz'; $str = 'abcdefghijklmnopqrstuvwxyz';
$str .= strtoupper($str) . '1234567890'; $str .= strtoupper($str) . '1234567890';
for ($i = 0; $i < $length; $i++) { for ($i = 0; $i < $length; $i++) {
$rand = substr($str, rand(0, strlen($str) - 2), 1); $rand = substr($str, rand(0, strlen($str) - 2), 1);
if (empty($rand)) { if (empty($rand)) {
$rand = substr($str, strlen($str) - 3, 1); $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 array $array
* @param $key * @param $key
* @param string $type * @param string $type
* @return string * @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); ksort($array, SORT_ASC);
$string = []; $string = [];
foreach ($array as $hashKey => $val) { foreach ($array as $hashKey => $val) {
if (empty($val)) { if (empty($val)) {
continue; continue;
} }
$string[] = $hashKey . '=' . $val; $string[] = $hashKey . '=' . $val;
} }
$string[] = 'key=' . $key; $string[] = 'key=' . $key;
$string = implode('&', $string); $string = implode('&', $string);
if ($type == 'MD5') { if ($type == 'MD5') {
return strtoupper(md5($string)); return strtoupper(md5($string));
} else { } else {
return hash('sha256', $string); return hash('sha256', $string);
} }
} }
/** /**
* @param $email * @param $email
* @param string $Subject * @param string $Subject
* @param $messageContent * @param $messageContent
*/ */
public static function sendEmail($email, string $Subject, $messageContent) public static function sendEmail($email, string $Subject, $messageContent)
{ {
if (!class_exists('\Swift_Mailer')) { if (!class_exists('\Swift_Mailer')) {
return; return;
} }
$mailer = new \Swift_Mailer((new \Swift_SmtpTransport($email['host'], $email['port'])) $mailer = new \Swift_Mailer((new \Swift_SmtpTransport($email['host'], $email['port']))
->setUsername($email['username'])->setPassword($email['password'])); ->setUsername($email['username'])->setPassword($email['password']));
$message = (new \Swift_Message($Subject)) $message = (new \Swift_Message($Subject))
->setFrom([$email['send']['address'] => $email['send']['nickname']]) ->setFrom([$email['send']['address'] => $email['send']['nickname']])
->setBody('Here is the message itself'); ->setBody('Here is the message itself');
foreach ($email['receive'] as $item) { foreach ($email['receive'] as $item) {
$message->setTo([$item['address'], $item['address'] => $item['nickname']]); $message->setTo([$item['address'], $item['address'] => $item['nickname']]);
} }
$mailer->send($messageContent); $mailer->send($messageContent);
} }
} }
+121 -121
View File
@@ -1,121 +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, bool $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|array $message * @param string|array $message
* @param array|int $data * @param array|int $data
* @param int $count * @param int $count
* @param array $exPageInfo * @param array $exPageInfo
* @return string|bool * @return string|bool
*/ */
public static function to($code, string|array $message = '', array|int $data = [], int $count = 0, array $exPageInfo = []): string|bool public static function to($code, string|array $message = '', array|int $data = [], int $count = 0, array $exPageInfo = []): string|bool
{ {
$params['code'] = $code; $params['code'] = $code;
if (!is_string($message)) { if (!is_string($message)) {
$params['message'] = 'System success.'; $params['message'] = 'System success.';
$params['param'] = $message; $params['param'] = $message;
if (!empty($data)) { if (!empty($data)) {
$params['exPageInfo'] = $data; $params['exPageInfo'] = $data;
} }
} 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 -450
View File
@@ -1,450 +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\Annotation\Inject; use Kiri\Annotation\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 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
*/ */
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
*/ */
public function make($class, array $constrict = [], array $config = []): mixed public function make($class, array $constrict = [], array $config = []): mixed
{ {
if ($this->isInterface($class)) { if ($this->isInterface($class)) {
$class = $this->_interfaces[$class]; $class = $this->_interfaces[$class];
} }
if (!isset($this->_singletons[$class])) { if (!isset($this->_singletons[$class])) {
$this->_singletons[$class] = $this->resolve($class, $constrict, $config); $this->_singletons[$class] = $this->resolve($class, $constrict, $config);
} }
return $this->_singletons[$class]; return $this->_singletons[$class];
} }
/** /**
* @param string $interface * @param string $interface
* @param string $class * @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 * @param $class
* @return bool * @return bool
*/ */
public function isInterface($class): bool public function isInterface($class): bool
{ {
$reflect = $this->getReflect($class); $reflect = $this->getReflect($class);
if ($reflect->isInterface()) { if ($reflect->isInterface()) {
return true; return true;
} }
return false; return false;
} }
/** /**
* @param string $interface * @param string $interface
* @param $object * @param $object
*/ */
public function setBindings(string $interface, $object) public function setBindings(string $interface, $object)
{ {
if (is_string($object)) { if (is_string($object)) {
$this->_interfaces[$interface] = $object; $this->_interfaces[$interface] = $object;
} else { } else {
$className = get_class($object); $className = get_class($object);
$this->_interfaces[$interface] = $className; $this->_interfaces[$interface] = $className;
$this->_singletons[$className] = $object; $this->_singletons[$className] = $object;
} }
} }
/** /**
* @param $class * @param $class
* @param array $constrict * @param array $constrict
* @param array $config * @param array $config
* @return object * @return object
* @throws * @throws
*/ */
public function create($class, array $constrict = [], array $config = []): object public function create($class, array $constrict = [], array $config = []): object
{ {
return $this->resolve($class, $constrict, $config); return $this->resolve($class, $constrict, $config);
} }
/** /**
* @param $class * @param $class
* @param $constrict * @param $constrict
* @param $config * @param $config
* *
* @return object * @return object
* @throws Exception * @throws Exception
*/ */
private function resolve($class, $constrict, $config): object private function resolve($class, $constrict, $config): object
{ {
$reflect = $this->resolveDependencies($class); $reflect = $this->resolveDependencies($class);
if (!$reflect->isInstantiable()) { if (!$reflect->isInstantiable()) {
throw new ReflectionException('Class ' . $class . ' cannot be instantiated'); throw new ReflectionException('Class ' . $class . ' cannot be instantiated');
} }
$object = $this->newInstance($reflect, $constrict); $object = $this->newInstance($reflect, $constrict);
$this->propertyInject($reflect, $object); $this->propertyInject($reflect, $object);
return $this->onAfterInit($object, $config); return $this->onAfterInit($object, $config);
} }
/** /**
* @param ReflectionClass $reflect * @param ReflectionClass $reflect
* @param $dependencies * @param $dependencies
* @return object * @return object
* @throws ReflectionException * @throws ReflectionException
*/ */
private function newInstance(ReflectionClass $reflect, $dependencies): object private function newInstance(ReflectionClass $reflect, $dependencies): object
{ {
if (!isset($this->_constructs[$reflect->getName()])) { if (!isset($this->_constructs[$reflect->getName()])) {
return $reflect->newInstance(); return $reflect->newInstance();
} }
$construct = $this->_constructs[$reflect->getName()]; $construct = $this->_constructs[$reflect->getName()];
if ($construct->getNumberOfParameters() < 1) { if ($construct->getNumberOfParameters() < 1) {
return $reflect->newInstance(); return $reflect->newInstance();
} }
$parameters = $this->mergeParam($this->resolveMethodParameters($construct), $dependencies); $parameters = $this->mergeParam($this->resolveMethodParameters($construct), $dependencies);
return $reflect->newInstanceArgs($parameters); return $reflect->newInstanceArgs($parameters);
} }
/** /**
* @param ReflectionClass $reflect * @param ReflectionClass $reflect
* @param $object * @param $object
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function propertyInject(ReflectionClass $reflect, $object): mixed public function propertyInject(ReflectionClass $reflect, $object): mixed
{ {
foreach (AnnotationManager::getPropertyAnnotation($reflect) as $property => $inject) { foreach (AnnotationManager::getPropertyAnnotation($reflect) as $property => $inject) {
/** @var Inject $inject */ /** @var Inject $inject */
$inject->execute($object, $property); $inject->execute($object, $property);
} }
return $object; return $object;
} }
/** /**
* @param $className * @param $className
* @param $method * @param $method
* @return array * @return array
*/ */
public function getMethodAttribute($className, $method = null): array public function getMethodAttribute($className, $method = null): array
{ {
$methods = AnnotationManager::getMethodAnnotation($this->getReflect($className)); $methods = AnnotationManager::getMethodAnnotation($this->getReflect($className));
if (!empty($method)) { if (!empty($method)) {
return $methods[$method] ?? []; return $methods[$method] ?? [];
} }
return $methods; return $methods;
} }
/** /**
* @param string $class * @param string $class
* @param string|null $property * @param string|null $property
* @return ReflectionProperty|ReflectionProperty[]|null * @return ReflectionProperty|ReflectionProperty[]|null
*/ */
public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array
{ {
$lists = AnnotationManager::getProperty($this->getReflect($class)); $lists = AnnotationManager::getProperty($this->getReflect($class));
if (empty($lists)) { if (empty($lists)) {
return null; return null;
} }
if (!empty($property)) { if (!empty($property)) {
return $lists[$property] ?? null; return $lists[$property] ?? null;
} }
return $lists; return $lists;
} }
/** /**
* @param $object * @param $object
* @param $config * @param $config
* @return mixed * @return mixed
*/ */
private function onAfterInit($object, $config): mixed private function onAfterInit($object, $config): mixed
{ {
Kiri::configure($object, $config); Kiri::configure($object, $config);
if (method_exists($object, 'init') && is_callable([$object, 'init'])) { if (method_exists($object, 'init') && is_callable([$object, 'init'])) {
call_user_func([$object, 'init']); call_user_func([$object, 'init']);
} }
return $object; return $object;
} }
/** /**
* @param $class * @param $class
* @return ReflectionClass * @return ReflectionClass
*/ */
private function resolveDependencies($class): ReflectionClass private function resolveDependencies($class): ReflectionClass
{ {
if (isset($this->_reflection[$class])) { if (isset($this->_reflection[$class])) {
return $this->_reflection[$class]; return $this->_reflection[$class];
} }
$reflect = new ReflectionClass($class); $reflect = new ReflectionClass($class);
if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) { if ($reflect->isAbstract() || $reflect->isTrait() || $reflect->isInterface()) {
return $this->_reflection[$class] = $reflect; return $this->_reflection[$class] = $reflect;
} }
$construct = AnnotationManager::resolveTarget($reflect); $construct = AnnotationManager::resolveTarget($reflect);
if (!empty($construct) && $construct->getNumberOfParameters() > 0) { if (!empty($construct) && $construct->getNumberOfParameters() > 0) {
$this->_constructs[$class] = $construct; $this->_constructs[$class] = $construct;
} }
return $this->_reflection[$class] = $reflect; return $this->_reflection[$class] = $reflect;
} }
/** /**
* @param ReflectionClass|string $class * @param ReflectionClass|string $class
* @return ReflectionMethod[] * @return ReflectionMethod[]
* @throws ReflectionException * @throws ReflectionException
*/ */
public function getReflectMethods(ReflectionClass|string $class): array public function getReflectMethods(ReflectionClass|string $class): array
{ {
if (is_string($class)) { if (is_string($class)) {
$class = $this->getReflect($class); $class = $this->getReflect($class);
} }
return AnnotationManager::getMethods($class); return AnnotationManager::getMethods($class);
} }
/** /**
* @param ReflectionClass|string $class * @param ReflectionClass|string $class
* @param string $method * @param string $method
* @return ReflectionMethod|null * @return ReflectionMethod|null
* @throws ReflectionException * @throws ReflectionException
*/ */
public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
{ {
return $this->getReflectMethods($class)[$method] ?? null; return $this->getReflectMethods($class)[$method] ?? null;
} }
/** /**
* @param string $className * @param string $className
* @param string $method * @param string $method
* @return array|null * @return array|null
* @throws ReflectionException * @throws ReflectionException
*/ */
public function getMethodParameters(string $className, string $method): ?array public function getMethodParameters(string $className, string $method): ?array
{ {
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) { if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$method])) {
return $this->_parameters[$className][$method]; return $this->_parameters[$className][$method];
} }
$reflectMethod = $this->getReflectMethod($this->getReflect($className), $method); $reflectMethod = $this->getReflectMethod($this->getReflect($className), $method);
if (!($reflectMethod instanceof ReflectionMethod)) { if (!($reflectMethod instanceof ReflectionMethod)) {
throw new ReflectionException("Class does not have a function $className::$method"); throw new ReflectionException("Class does not have a function $className::$method");
} }
$className = $reflectMethod->getDeclaringClass()->getName(); $className = $reflectMethod->getDeclaringClass()->getName();
if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) { if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) {
return $this->_parameters[$className][$reflectMethod->getName()]; return $this->_parameters[$className][$reflectMethod->getName()];
} }
return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod)); return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod));
} }
/** /**
* @param $class * @param $class
* @param $method * @param $method
* @param $parameters * @param $parameters
* @return mixed * @return mixed
*/ */
private function setParameters($class, $method, $parameters): mixed private function setParameters($class, $method, $parameters): mixed
{ {
if (!isset($this->_parameters[$class])) { if (!isset($this->_parameters[$class])) {
$this->_parameters[$class] = []; $this->_parameters[$class] = [];
} }
return $this->_parameters[$class][$method] = $parameters; return $this->_parameters[$class][$method] = $parameters;
} }
/** /**
* @param Closure $reflectionMethod * @param Closure $reflectionMethod
* @return array * @return array
* @throws ReflectionException * @throws ReflectionException
*/ */
public function getFunctionParameters(Closure $reflectionMethod): array public function getFunctionParameters(Closure $reflectionMethod): array
{ {
return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod)); return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod));
} }
/** /**
* @param ReflectionMethod|ReflectionFunction $reflectionMethod * @param ReflectionMethod|ReflectionFunction $reflectionMethod
* @return array * @return array
*/ */
private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array
{ {
if ($reflectionMethod->getNumberOfParameters() < 1) { if ($reflectionMethod->getNumberOfParameters() < 1) {
return []; return [];
} }
$params = []; $params = [];
foreach ($reflectionMethod->getParameters() as $key => $parameter) { foreach ($reflectionMethod->getParameters() as $key => $parameter) {
if ($parameter->isDefaultValueAvailable()) { if ($parameter->isDefaultValueAvailable()) {
$params[$key] = $parameter->getDefaultValue(); $params[$key] = $parameter->getDefaultValue();
} else if ($parameter->getType() === null) { } else if ($parameter->getType() === null) {
$params[$key] = $parameter->getType(); $params[$key] = $parameter->getType();
} else { } else {
$type = $parameter->getType()->getName(); $type = $parameter->getType()->getName();
if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) { if (is_string($type) && class_exists($type) || isset($this->_interfaces[$type])) {
$type = Kiri::getDi()->get($type); $type = Kiri::getDi()->get($type);
} }
$params[$key] = match ($parameter->getType()) { $params[$key] = match ($parameter->getType()) {
'string' => '', 'string' => '',
'int', 'float' => 0, 'int', 'float' => 0,
'', null, 'object', 'mixed' => NULL, '', null, 'object', 'mixed' => NULL,
'bool' => false, 'bool' => false,
default => $type default => $type
}; };
} }
} }
return $params; return $params;
} }
/** /**
* @param $class * @param $class
* @return ReflectionClass|null * @return ReflectionClass|null
*/ */
public function getReflect($class): ?ReflectionClass public function getReflect($class): ?ReflectionClass
{ {
if (!isset($this->_reflection[$class])) { if (!isset($this->_reflection[$class])) {
return $this->resolveDependencies($class); return $this->resolveDependencies($class);
} }
return $this->_reflection[$class]; return $this->_reflection[$class];
} }
/** /**
* @param $class * @param $class
*/ */
public function unset($class) public function unset($class)
{ {
if (is_array($class) && isset($class['class'])) { if (is_array($class) && isset($class['class'])) {
$class = $class['class']; $class = $class['class'];
} else if (is_object($class)) { } else if (is_object($class)) {
$class = $class::class; $class = $class::class;
} }
unset( unset(
$this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class] $this->_reflection[$class], $this->_singletons[$class], $this->_constructs[$class]
); );
} }
/** /**
* @return $this * @return $this
*/ */
public function flush(): static public function flush(): static
{ {
$this->_reflection = []; $this->_reflection = [];
$this->_singletons = []; $this->_singletons = [];
$this->_constructs = []; $this->_constructs = [];
return $this; return $this;
} }
/** /**
* @param $old * @param $old
* @param $newParam * @param $newParam
* *
* @return mixed * @return mixed
*/ */
private function mergeParam($old, $newParam): array private function mergeParam($old, $newParam): array
{ {
if (empty($old)) { if (empty($old)) {
return $newParam; return $newParam;
} else if (empty($newParam)) { } else if (empty($newParam)) {
return $old; return $old;
} }
foreach ($newParam as $key => $val) { foreach ($newParam as $key => $val) {
$old[$key] = $val; $old[$key] = $val;
} }
return $old; return $old;
} }
/** /**
* @param string $id * @param string $id
* @return bool * @return bool
*/ */
public function has(string $id): bool public function has(string $id): bool
{ {
return isset($this->_singletons[$id]) || isset($this->_interfaces[$id]); 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 -303
View File
@@ -1,303 +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 AnnotationManager class AnnotationManager
{ {
private static array $_classTarget = []; private static array $_classTarget = [];
private static array $_classMethodAnnotation = []; private static array $_classMethodAnnotation = [];
private static array $_classMethod = []; private static array $_classMethod = [];
private static array $_classPropertyAnnotation = []; private static array $_classPropertyAnnotation = [];
private static array $_classProperty = []; private static array $_classProperty = [];
private static array $_mapping = []; private static array $_mapping = [];
/** /**
* @return void * @return void
*/ */
public static function clear() public static function clear()
{ {
static::$_classTarget = []; static::$_classTarget = [];
static::$_classMethodAnnotation = []; static::$_classMethodAnnotation = [];
static::$_classMethod = []; static::$_classMethod = [];
static::$_classPropertyAnnotation = []; static::$_classPropertyAnnotation = [];
static::$_classProperty = []; static::$_classProperty = [];
static::$_mapping = []; static::$_mapping = [];
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
*/ */
public static function setTargetAnnotation(ReflectionClass $class) public static function setTargetAnnotation(ReflectionClass $class)
{ {
$className = $class->getName(); $className = $class->getName();
if (!isset(static::$_classTarget[$className])) { if (!isset(static::$_classTarget[$className])) {
static::$_classTarget[$className] = []; static::$_classTarget[$className] = [];
} }
foreach ($class->getAttributes() as $attribute) { foreach ($class->getAttributes() as $attribute) {
if (!class_exists($attribute->getName())) { if (!class_exists($attribute->getName())) {
continue; continue;
} }
$instance = $attribute->newInstance(); $instance = $attribute->newInstance();
static::$_classTarget[$className][] = $instance; static::$_classTarget[$className][] = $instance;
self::setMappingClass($attribute, $className); self::setMappingClass($attribute, $className);
} }
} }
/** /**
* @param ReflectionAttribute $attribute * @param ReflectionAttribute $attribute
* @param string $class * @param string $class
*/ */
public static function setMappingClass(ReflectionAttribute $attribute, string $class) public static function setMappingClass(ReflectionAttribute $attribute, string $class)
{ {
if (!isset(static::$_mapping[$attribute->getName()])) { if (!isset(static::$_mapping[$attribute->getName()])) {
static::$_mapping[$attribute->getName()] = []; static::$_mapping[$attribute->getName()] = [];
} }
if (!isset(static::$_mapping[$attribute->getName()][$class])) { if (!isset(static::$_mapping[$attribute->getName()][$class])) {
static::$_mapping[$attribute->getName()][$class] = []; static::$_mapping[$attribute->getName()][$class] = [];
} }
} }
/** /**
* @param ReflectionAttribute $attribute * @param ReflectionAttribute $attribute
* @param string $class * @param string $class
* @param string $method * @param string $method
* @param mixed $instance * @param mixed $instance
*/ */
public static function setMappingMethod(ReflectionAttribute $attribute, string $class, string $method, mixed $instance) public static function setMappingMethod(ReflectionAttribute $attribute, string $class, string $method, mixed $instance)
{ {
self::setMappingClass($attribute, $class); self::setMappingClass($attribute, $class);
if (!isset(static::$_mapping[$attribute->getName()][$class]['method'])) { if (!isset(static::$_mapping[$attribute->getName()][$class]['method'])) {
static::$_mapping[$attribute->getName()][$class]['method'] = []; static::$_mapping[$attribute->getName()][$class]['method'] = [];
} }
static::$_mapping[$attribute->getName()][$class]['method'][] = [$method => $instance]; static::$_mapping[$attribute->getName()][$class]['method'][] = [$method => $instance];
} }
/** /**
* @param ReflectionAttribute $attribute * @param ReflectionAttribute $attribute
* @param string $class * @param string $class
* @param string $property * @param string $property
* @param $instance * @param $instance
*/ */
public static function setMappingProperty(ReflectionAttribute $attribute, string $class, string $property, $instance) public static function setMappingProperty(ReflectionAttribute $attribute, string $class, string $property, $instance)
{ {
self::setMappingClass($attribute, $class); self::setMappingClass($attribute, $class);
$mapping = static::$_mapping[$attribute->getName()][$class]; $mapping = static::$_mapping[$attribute->getName()][$class];
if (!isset($mapping['property'])) { if (!isset($mapping['property'])) {
$mapping['property'] = []; $mapping['property'] = [];
} }
$mapping['property'][] = [$property => $instance]; $mapping['property'][] = [$property => $instance];
static::$_mapping[$attribute->getName()][$class] = $mapping; static::$_mapping[$attribute->getName()][$class] = $mapping;
} }
/** /**
* @param mixed $class * @param mixed $class
* @return array * @return array
*/ */
public static function getTargetAnnotation(mixed $class): array public static function getTargetAnnotation(mixed $class): array
{ {
if (!is_string($class)) { if (!is_string($class)) {
$class = $class::class; $class = $class::class;
} }
return static::$_classTarget[$class] ?? []; return static::$_classTarget[$class] ?? [];
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
*/ */
public static function setMethodAnnotation(ReflectionClass $class) public static function setMethodAnnotation(ReflectionClass $class)
{ {
$className = $class->getName(); $className = $class->getName();
static::$_classMethodAnnotation[$className] = static::$_classMethod[$className] = []; static::$_classMethodAnnotation[$className] = static::$_classMethod[$className] = [];
foreach ($class->getMethods() as $ReflectionMethod) { foreach ($class->getMethods() as $ReflectionMethod) {
static::$_classMethod[$className][$ReflectionMethod->getName()] = $ReflectionMethod; static::$_classMethod[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
static::$_classMethodAnnotation[$className][$ReflectionMethod->getName()] = []; static::$_classMethodAnnotation[$className][$ReflectionMethod->getName()] = [];
foreach ($ReflectionMethod->getAttributes() as $attribute) { foreach ($ReflectionMethod->getAttributes() as $attribute) {
if (!class_exists($attribute->getName())) { if (!class_exists($attribute->getName())) {
continue; continue;
} }
$instance = $attribute->newInstance(); $instance = $attribute->newInstance();
static::$_classMethodAnnotation[$className][$ReflectionMethod->getName()][] = $instance; static::$_classMethodAnnotation[$className][$ReflectionMethod->getName()][] = $instance;
self::setMappingMethod($attribute, $className, $ReflectionMethod->getName(), $instance); self::setMappingMethod($attribute, $className, $ReflectionMethod->getName(), $instance);
} }
} }
} }
/** /**
* @param string $class * @param string $class
* @param string $method * @param string $method
* @return bool * @return bool
*/ */
public static function hasMethod(string $class, string $method): bool public static function hasMethod(string $class, string $method): bool
{ {
return isset(static::$_classMethod[$class]) && isset(static::$_classMethod[$class][$method]); return isset(static::$_classMethod[$class]) && isset(static::$_classMethod[$class][$method]);
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @return array * @return array
*/ */
#[Pure] public static function getMethodAnnotation(ReflectionClass $class): array #[Pure] public static function getMethodAnnotation(ReflectionClass $class): array
{ {
return static::$_classMethodAnnotation[$class->getName()] ?? []; return static::$_classMethodAnnotation[$class->getName()] ?? [];
} }
/** /**
* @param \ReflectionClass $reflect * @param \ReflectionClass $reflect
* @return \ReflectionMethod|null * @return \ReflectionMethod|null
*/ */
public static function resolveTarget(ReflectionClass $reflect): ?\ReflectionMethod public static function resolveTarget(ReflectionClass $reflect): ?\ReflectionMethod
{ {
AnnotationManager::setPropertyAnnotation($reflect); AnnotationManager::setPropertyAnnotation($reflect);
AnnotationManager::setTargetAnnotation($reflect); AnnotationManager::setTargetAnnotation($reflect);
AnnotationManager::setMethodAnnotation($reflect); AnnotationManager::setMethodAnnotation($reflect);
return $reflect->getConstructor(); return $reflect->getConstructor();
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
*/ */
public static function setPropertyAnnotation(ReflectionClass $class) public static function setPropertyAnnotation(ReflectionClass $class)
{ {
$className = $class->getName(); $className = $class->getName();
static::$_classProperty[$className] = static::$_classPropertyAnnotation[$className] = []; static::$_classProperty[$className] = static::$_classPropertyAnnotation[$className] = [];
foreach ($class->getProperties(ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PUBLIC | foreach ($class->getProperties(ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PUBLIC |
ReflectionProperty::IS_PROTECTED) as $ReflectionMethod) { ReflectionProperty::IS_PROTECTED) as $ReflectionMethod) {
static::$_classProperty[$className][$ReflectionMethod->getName()] = $ReflectionMethod; static::$_classProperty[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
foreach ($ReflectionMethod->getAttributes() as $attribute) { foreach ($ReflectionMethod->getAttributes() as $attribute) {
if (!class_exists($attribute->getName())) { if (!class_exists($attribute->getName())) {
continue; continue;
} }
$instance = $attribute->newInstance(); $instance = $attribute->newInstance();
static::$_classPropertyAnnotation[$className][$ReflectionMethod->getName()] = $instance; static::$_classPropertyAnnotation[$className][$ReflectionMethod->getName()] = $instance;
self::setMappingProperty($attribute, $className, $ReflectionMethod->getName(), $instance); self::setMappingProperty($attribute, $className, $ReflectionMethod->getName(), $instance);
} }
} }
} }
/** /**
* @param string $attribute * @param string $attribute
* @param string|null $class * @param string|null $class
* @return array[] * @return array[]
*/ */
public static function getAttributeTrees(string $attribute, string $class = null): array public static function getAttributeTrees(string $attribute, string $class = null): array
{ {
$mapping = static::$_mapping[$attribute] ?? []; $mapping = static::$_mapping[$attribute] ?? [];
if (empty($mapping) || empty($class)) { if (empty($mapping) || empty($class)) {
return $mapping; return $mapping;
} }
return $mapping[$class] ?? []; return $mapping[$class] ?? [];
} }
/** /**
* @param string $attribute * @param string $attribute
* @param string $class * @param string $class
* @param string|null $method * @param string|null $method
* @return array * @return array
*/ */
public static function getSpecify_annotation(string $attribute, string $class, string $method = null): mixed public static function getSpecify_annotation(string $attribute, string $class, string $method = null): mixed
{ {
$class = self::getAttributeTrees($attribute, $class); $class = self::getAttributeTrees($attribute, $class);
if (empty($class) || !isset($class['method'])) { if (empty($class) || !isset($class['method'])) {
return null; return null;
} }
if (empty($method)) { if (empty($method)) {
return $class['method']; return $class['method'];
} }
foreach ($class['method'] as $value) { foreach ($class['method'] as $value) {
$key = key($value); $key = key($value);
if ($method == $key) { if ($method == $key) {
return $value[$key]; return $value[$key];
} }
} }
return null; return null;
} }
/** /**
* @param string $attribute * @param string $attribute
* @param string $class * @param string $class
* @param string $method * @param string $method
* @return mixed * @return mixed
*/ */
public static function getPropertyByAnnotation(string $attribute, string $class, string $method): mixed public static function getPropertyByAnnotation(string $attribute, string $class, string $method): mixed
{ {
$class = self::getAttributeTrees($attribute, $class); $class = self::getAttributeTrees($attribute, $class);
if (empty($class) || !isset($class['property'])) { if (empty($class) || !isset($class['property'])) {
return []; return [];
} }
foreach ($class['property'] as $value) { foreach ($class['property'] as $value) {
$key = key($value); $key = key($value);
if ($method == $key) { if ($method == $key) {
return $value[$key]; return $value[$key];
} }
} }
return null; return null;
} }
/** /**
* @param ReflectionClass|string $class * @param ReflectionClass|string $class
* @return array * @return array
* @throws \ReflectionException * @throws \ReflectionException
*/ */
public static function getMethods(ReflectionClass|string $class): array public static function getMethods(ReflectionClass|string $class): array
{ {
if (is_string($class)) { if (is_string($class)) {
$class = self::getReflect($class); $class = self::getReflect($class);
} }
return static::$_classMethod[$class->getName()] ?? []; return static::$_classMethod[$class->getName()] ?? [];
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @return ReflectionProperty[] * @return ReflectionProperty[]
*/ */
#[Pure] public static function getProperty(ReflectionClass $class): array #[Pure] public static function getProperty(ReflectionClass $class): array
{ {
return static::$_classProperty[$class->getName()] ?? []; return static::$_classProperty[$class->getName()] ?? [];
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @return array * @return array
*/ */
#[Pure] public static function getPropertyAnnotation(ReflectionClass $class): array #[Pure] public static function getPropertyAnnotation(ReflectionClass $class): array
{ {
return static::$_classPropertyAnnotation[$class->getName()] ?? []; 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 -117
View File
@@ -1,117 +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 Exception; use Exception;
use Kiri\Abstracts\Component; use Kiri\Abstracts\Component;
use Kiri\Core\Json; use Kiri\Core\Json;
use Kiri\Kiri; use Kiri\Kiri;
use Kiri\Annotation\Inject; use Kiri\Annotation\Inject;
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 = [];
/** /**
* inject logger * inject logger
* *
* @var LoggerInterface * @var LoggerInterface
*/ */
#[Inject(LoggerInterface::class)] #[Inject(LoggerInterface::class)]
public LoggerInterface $logger; public LoggerInterface $logger;
private array $sources = []; private array $sources = [];
/** /**
* @param string $application * @param string $application
* @return string * @return string
*/ */
public function getLastError(string $application = 'app'): string public function getLastError(string $application = 'app'): string
{ {
return $this->logs[$application] ?? 'Unknown error.'; return $this->logs[$application] ?? 'Unknown error.';
} }
/** /**
* @param $message * @param $message
* @param $method * @param $method
* @return void * @return void
*/ */
public function fail($message, $method) public function fail($message, $method)
{ {
$this->logs[$method] = $message; $this->logs[$method] = $message;
} }
/** /**
* @param string $messages * @param string $messages
* @param string $method * @param string $method
* @throws Exception * @throws Exception
*/ */
public function write(string $messages, string $method = 'app') public function write(string $messages, string $method = 'app')
{ {
if (empty($messages)) { if (empty($messages)) {
return; return;
} }
$to_day = date('Y-m-d'); $to_day = date('Y-m-d');
$fileName = storage('server-' . $to_day . '.log', $dirName = 'log/' . ($method ?? 'app')); $fileName = storage('server-' . $to_day . '.log', $dirName = 'log/' . ($method ?? 'app'));
file_put_contents($fileName, '[' . date('Y-m-d H:i:s') . ']:' . PHP_EOL . $messages . PHP_EOL); file_put_contents($fileName, '[' . date('Y-m-d H:i:s') . ']:' . PHP_EOL . $messages . PHP_EOL);
} }
/** /**
* @param Throwable $exception * @param Throwable $exception
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function exception(Throwable $exception): mixed public function exception(Throwable $exception): mixed
{ {
$code = $exception->getCode() == 0 ? 500 : $exception->getCode(); $code = $exception->getCode() == 0 ? 500 : $exception->getCode();
$logger = Kiri::app()->getLogger(); $logger = Kiri::app()->getLogger();
$logger->write(jTraceEx($exception), 'exception'); $logger->write(jTraceEx($exception), 'exception');
return Json::to($code, $exception->getMessage(), [ return Json::to($code, $exception->getMessage(), [
'file' => $exception->getFile(), 'file' => $exception->getFile(),
'line' => $exception->getLine() 'line' => $exception->getLine()
]); ]);
} }
/** /**
* @param string $name * @param string $name
* @param array $arguments * @param array $arguments
* @return mixed * @return mixed
*/ */
public function __call(string $name, array $arguments): mixed public function __call(string $name, array $arguments): mixed
{ {
if (!method_exists($this, $name)) { if (!method_exists($this, $name)) {
return $this->logger->{$name}(...$arguments); return $this->logger->{$name}(...$arguments);
} else { } else {
return $this->{$name}(...$arguments); 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 -235
View File
@@ -1,235 +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 Kiri\Annotation\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\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
/** /**
* *
*/ */
class HotReload extends Command class HotReload extends Command
{ {
public bool $isReloading = FALSE; public bool $isReloading = FALSE;
public bool $isReloadingOut = FALSE; public bool $isReloadingOut = FALSE;
public ?array $dirs = []; 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)] #[Inject(Logger::class)]
public Logger $logger; 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 ConfigException
* @throws \ReflectionException * @throws \ReflectionException
* @throws Exception * @throws Exception
*/ */
protected function initCore() protected function initCore()
{ {
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
$this->dirs = Config::get('inotify', [APP_PATH . 'app']); $this->dirs = Config::get('inotify', [APP_PATH . 'app']);
if (!extension_loaded('inotify')) { if (!extension_loaded('inotify')) {
$this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]); $this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]);
} else { } else {
$this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]); $this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]);
} }
$this->clearOtherService(); $this->clearOtherService();
$this->setProcessName(); $this->setProcessName();
} }
/** /**
* @throws ConfigException * @throws ConfigException
*/ */
public function setProcessName() public function setProcessName()
{ {
swoole_async_set(['enable_coroutine' => FALSE]); swoole_async_set(['enable_coroutine' => FALSE]);
if (Kiri::getPlatform()->isLinux()) { if (Kiri::getPlatform()->isLinux()) {
swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather'); 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'))) { if (file_exists(storage('.manager.pid'))) {
$pid = (int)file_get_contents(storage('.manager.pid')); $pid = (int)file_get_contents(storage('.manager.pid'));
if ($pid > 0 && Process::kill($pid, 0)) { if ($pid > 0 && Process::kill($pid, 0)) {
Process::kill($pid, 15) && Process::wait(TRUE); 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) { if ($error[0] === 0) {
$error[0] = 500; $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 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
{ {
$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 ($this->int == 1) { if ($this->int == 1) {
return; return;
} }
if (empty($pid)) { 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)) { } else if (!Process::kill($pid, 0)) {
$this->logger->warning('service is shutdown you need reload.'); $this->logger->warning('service is shutdown you need reload.');
$this->trigger_reload(); $this->trigger_reload();
} }
} }
/** /**
* @param $data * @param $data
* @throws Exception * @throws Exception
*/ */
public function onSignal($data) public function onSignal($data)
{ {
if (!$data) { if (!$data) {
return; return;
} }
Timer::clearAll(); Timer::clearAll();
$this->driver->clear(); $this->driver->clear();
$this->stopServer(); $this->stopServer();
$this->stopManager(); $this->stopManager();
while ($ret = Process::wait(TRUE)) { while ($ret = Process::wait(TRUE)) {
echo "PID={$ret['pid']}\n"; echo "PID={$ret['pid']}\n";
sleep(1); sleep(1);
} }
} }
/** /**
* @throws Exception * @throws Exception
*/ */
protected function stopServer() protected function stopServer()
{ {
$pid = file_get_contents(storage('.swoole.pid')); $pid = file_get_contents(storage('.swoole.pid'));
if (!empty($pid) && Process::kill($pid, 0)) { if (!empty($pid) && Process::kill($pid, 0)) {
Process::kill($pid, SIGTERM); Process::kill($pid, SIGTERM);
} }
} }
/** /**
* *
*/ */
protected function stopManager() protected function stopManager()
{ {
if ($this->process && Process::kill($this->process->pid, 0)) { if ($this->process && Process::kill($this->process->pid, 0)) {
Process::kill($this->process->pid) && Process::wait(TRUE); Process::kill($this->process->pid) && Process::wait(TRUE);
} }
} }
/** /**
* 重启 * 重启
* *
* @throws Exception * @throws Exception
*/ */
public function trigger_reload() public function trigger_reload()
{ {
if ($this->int == 1) { if ($this->int == 1) {
return; return;
} }
$this->int = 1; $this->int = 1;
$this->logger->warning('change reload'); $this->logger->warning('change reload');
$this->stopServer(); $this->stopServer();
$this->stopManager(); $this->stopManager();
$this->process = new Process(function (Process $process) { $this->process = new Process(function (Process $process) {
$process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "start"]); $process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "start"]);
}); });
$this->process->start(); $this->process->start();
$this->int = -1; $this->int = -1;
} }
} }
+169 -169
View File
@@ -1,169 +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 = [];
public 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_error_handler([$this, 'error']);
set_exception_handler([$this, 'error']); set_exception_handler([$this, 'error']);
} }
/** /**
* @return void * @return void
*/ */
public function error(): void public function error(): void
{ {
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function start() public function start()
{ {
$this->inotify = inotify_init(); $this->inotify = inotify_init();
$this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE; $this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE;
foreach ($this->dirs as $dir) { foreach ($this->dirs as $dir) {
if (!is_dir($dir)) continue; if (!is_dir($dir)) continue;
$this->watch($dir); $this->watch($dir);
} }
Event::add($this->inotify, [$this, 'check']); Event::add($this->inotify, [$this, 'check']);
Event::wait(); Event::wait();
} }
public function clear() public function clear()
{ {
Event::del($this->inotify); Event::del($this->inotify);
Event::exit(); Event::exit();
} }
/** /**
* 开始监听 * 开始监听
* @throws Exception * @throws Exception
*/ */
public function check() public function check()
{ {
if (!($events = inotify_read($this->inotify))) { if (!($events = inotify_read($this->inotify))) {
return; return;
} }
if ($this->isReloading) { if ($this->isReloading) {
return; return;
} }
$LISTEN_TYPE = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM]; $LISTEN_TYPE = [IN_CREATE, IN_DELETE, IN_MODIFY, IN_MOVED_TO, IN_MOVED_FROM];
foreach ($events as $ev) { foreach ($events as $ev) {
if (!in_array($ev['mask'], $LISTEN_TYPE)) { if (!in_array($ev['mask'], $LISTEN_TYPE)) {
continue; continue;
} }
//非重启类型 //非重启类型
if (str_ends_with($ev['name'], '.php')) { if (str_ends_with($ev['name'], '.php')) {
Timer::after(3000, fn() => $this->reload()); Timer::after(3000, fn() => $this->reload());
$this->isReloading = TRUE; $this->isReloading = TRUE;
} }
} }
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function reload() public function reload()
{ {
$this->process->trigger_reload(); $this->process->trigger_reload();
$this->clearWatch(); $this->clearWatch();
foreach ($this->dirs as $root) { foreach ($this->dirs as $root) {
$this->watch($root); $this->watch($root);
} }
$this->process->int = -1; $this->process->int = -1;
$this->isReloading = FALSE; $this->isReloading = FALSE;
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function clearWatch() public function clearWatch()
{ {
foreach ($this->watchFiles as $wd) { foreach ($this->watchFiles as $wd) {
try { try {
@inotify_rm_watch($this->inotify, $wd); @inotify_rm_watch($this->inotify, $wd);
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
// logger()->addError($exception->getMessage(), 'throwable'); // logger()->addError($exception->getMessage(), 'throwable');
} }
} }
$this->watchFiles = []; $this->watchFiles = [];
} }
/** /**
* @param $dir * @param $dir
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function watch($dir): bool public function watch($dir): bool
{ {
//目录不存在 //目录不存在
if (!is_dir($dir)) { if (!is_dir($dir)) {
return logger()->addError("[$dir] is not a directory."); return logger()->addError("[$dir] is not a directory.");
} }
//避免重复监听 //避免重复监听
if (isset($this->watchFiles[$dir])) { if (isset($this->watchFiles[$dir])) {
return FALSE; return FALSE;
} }
if (in_array($dir, self::IG_DIR)) { if (in_array($dir, self::IG_DIR)) {
return FALSE; return FALSE;
} }
$wd = @inotify_add_watch($this->inotify, $dir, $this->events); $wd = @inotify_add_watch($this->inotify, $dir, $this->events);
$this->watchFiles[$dir] = $wd; $this->watchFiles[$dir] = $wd;
$files = scandir($dir); $files = scandir($dir);
foreach ($files as $f) { foreach ($files as $f) {
if ($f == '.' || $f == '..') { if ($f == '.' || $f == '..') {
continue; continue;
} }
$path = $dir . '/' . $f; $path = $dir . '/' . $f;
//递归目录 //递归目录
if (is_dir($path)) { if (is_dir($path)) {
$this->watch($path); $this->watch($path);
} else if (!str_ends_with($f, '.php')) { } else if (!str_ends_with($f, '.php')) {
continue; continue;
} }
//检测文件类型 //检测文件类型
if (strstr($f, '.') == '.php') { if (strstr($f, '.') == '.php') {
$wd = @inotify_add_watch($this->inotify, $path, $this->events); $wd = @inotify_add_watch($this->inotify, $path, $this->events);
$this->watchFiles[$path] = $wd; $this->watchFiles[$path] = $wd;
} }
} }
return TRUE; return TRUE;
} }
} }
+149 -149
View File
@@ -1,149 +1,149 @@
<?php <?php
namespace Kiri\FileListen; namespace Kiri\FileListen;
use Exception; use Exception;
use Swoole\Timer; use Swoole\Timer;
class Scaner class Scaner
{ {
private array $md5Map = []; private array $md5Map = [];
public bool $isReloading = FALSE; public bool $isReloading = FALSE;
/** /**
* @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)
{ {
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function start(): void public function start(): void
{ {
$this->loadDirs(); $this->loadDirs();
$this->tick(); $this->tick();
} }
/** /**
* @param bool $isReload * @param bool $isReload
* @throws Exception * @throws Exception
*/ */
private function loadDirs(bool $isReload = FALSE) private function loadDirs(bool $isReload = FALSE)
{ {
foreach ($this->dirs as $value) { foreach ($this->dirs as $value) {
if (is_bool($path = realpath($value))) { if (is_bool($path = realpath($value))) {
continue; continue;
} }
if (!is_dir($path)) continue; if (!is_dir($path)) continue;
$this->loadByDir($path, $isReload); $this->loadByDir($path, $isReload);
} }
} }
/** /**
* @param $path * @param $path
* @param bool $isReload * @param bool $isReload
* @return void * @return void
* @throws Exception * @throws Exception
*/ */
private function loadByDir($path, bool $isReload = FALSE): void private function loadByDir($path, bool $isReload = FALSE): void
{ {
if (!is_string($path)) { if (!is_string($path)) {
return; return;
} }
$path = rtrim($path, '/'); $path = rtrim($path, '/');
foreach (glob(realpath($path) . '/*') as $value) { foreach (glob(realpath($path) . '/*') as $value) {
if (is_dir($value)) { if (is_dir($value)) {
$this->loadByDir($value, $isReload); $this->loadByDir($value, $isReload);
} }
if (is_file($value)) { if (is_file($value)) {
if ($this->checkFile($value, $isReload)) { if ($this->checkFile($value, $isReload)) {
Timer::after(2000, fn() => $this->timerReload()); Timer::after(2000, fn() => $this->timerReload());
$this->isReloading = TRUE; $this->isReloading = TRUE;
break; break;
} }
} }
} }
} }
/** /**
* @param $value * @param $value
* @param $isReload * @param $isReload
* @return bool * @return bool
*/ */
private function checkFile($value, $isReload): bool private function checkFile($value, $isReload): bool
{ {
$md5 = md5($value); $md5 = md5($value);
$mTime = filectime($value); $mTime = filectime($value);
if (!isset($this->md5Map[$md5])) { if (!isset($this->md5Map[$md5])) {
if ($isReload) { if ($isReload) {
return TRUE; return TRUE;
} }
$this->md5Map[$md5] = $mTime; $this->md5Map[$md5] = $mTime;
} else { } else {
if ($this->md5Map[$md5] != $mTime) { if ($this->md5Map[$md5] != $mTime) {
if ($isReload) { if ($isReload) {
return TRUE; return TRUE;
} }
$this->md5Map[$md5] = $mTime; $this->md5Map[$md5] = $mTime;
} }
} }
return FALSE; return FALSE;
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function timerReload() public function timerReload()
{ {
$this->isReloading = TRUE; $this->isReloading = TRUE;
$this->process->trigger_reload(); $this->process->trigger_reload();
$this->process->int = -1; $this->process->int = -1;
$this->loadDirs(); $this->loadDirs();
$this->isReloading = FALSE; $this->isReloading = FALSE;
$this->process->isReloadingOut = FALSE; $this->process->isReloadingOut = FALSE;
$this->tick(); $this->tick();
} }
private bool $isStop = FALSE; private bool $isStop = FALSE;
public function clear() public function clear()
{ {
$this->isStop = TRUE; $this->isStop = TRUE;
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function tick() public function tick()
{ {
if ($this->isReloading || $this->isStop) { if ($this->isReloading || $this->isStop) {
return; return;
} }
$this->loadDirs(TRUE); $this->loadDirs(TRUE);
sleep(2); sleep(2);
$this->tick(); $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 -636
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\Config; use Kiri\Abstracts\Config;
use Kiri\Abstracts\Input; use Kiri\Abstracts\Input;
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\Output\OutputInterface;
/** /**
* Class Runtime * Class Runtime
* @package Kiri * @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 CACHE_NAME = '.runtime.cache';
const CONFIG_NAME = '.config.cache'; const CONFIG_NAME = '.config.cache';
protected function configure() protected function configure()
{ {
$this->setName('runtime:builder'); $this->setName('runtime:builder');
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
* @param OutputInterface $output * @param OutputInterface $output
* @return int * @return int
* @throws Exception * @throws Exception
*/ */
public function execute(InputInterface $input, OutputInterface $output): int public function execute(InputInterface $input, OutputInterface $output): int
{ {
// TODO: Implement onHandler() method. // TODO: Implement onHandler() method.
$annotation = Kiri::app()->getAnnotation(); $annotation = Kiri::app()->getAnnotation();
$runtime = storage(static::CACHE_NAME); $runtime = storage(static::CACHE_NAME);
$config = storage(static::CONFIG_NAME); $config = storage(static::CONFIG_NAME);
Kiri::writeFile($config, $this->configEach()); Kiri::writeFile($config, $this->configEach());
Kiri::writeFile($runtime, serialize($annotation->getLoader())); Kiri::writeFile($runtime, serialize($annotation->getLoader()));
return 1; return 1;
} }
/** /**
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public function configEach(): string public function configEach(): string
{ {
$array = []; $array = [];
foreach (Config::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 -342
View File
@@ -1,342 +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->getOption('make'); $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
{ {
if ($input->hasOption('name')) { if ($input->hasOption('name')) {
$this->tableName = $input->getOption('name'); $this->tableName = $input->getOption('name');
} }
return match ($make) { return match ($make) {
'controller' => $this->getTable(1, 0), 'controller' => $this->getTable(1, 0),
'model' => $this->getTable(0, 1), 'model' => $this->getTable(0, 1),
default => [], default => [],
}; };
} }
/** /**
* @param $controller * @param $controller
* @param $model * @param $model
* @return array * @return array
* *
* @throws Exception * @throws Exception
*/ */
private function getTable($controller, $model): array private function getTable($controller, $model): array
{ {
$tables = $this->getFields($this->getTables()); $tables = $this->getFields($this->getTables());
if (empty($tables)) { if (empty($tables)) {
return []; return [];
} }
$fileList = []; $fileList = [];
foreach ($tables as $key => $val) { foreach ($tables as $key => $val) {
$data = $this->createModelFile($key, $val); $data = $this->createModelFile($key, $val);
if ($controller == 1) { if ($controller == 1) {
$fileList[] = $this->generateController($data); $fileList[] = $this->generateController($data);
} }
if ($model == 1) { if ($model == 1) {
$fileList[] = $this->generateModel($data); $fileList[] = $this->generateModel($data);
} }
} }
return $fileList; return $fileList;
} }
/** /**
* @param array $data * @param array $data
* @return string * @return string
* @throws Exception * @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 = new GiiModel($data['classFileName'], $data['tableName'], $data['visible'], $data['res'], $data['fields']);
$controller->setConnection($this->db); $controller->setConnection($this->db);
$controller->setModelPath($this->modelPath); $controller->setModelPath($this->modelPath);
$controller->setModelNamespace($this->modelNamespace); $controller->setModelNamespace($this->modelNamespace);
$controller->setInput($this->input); $controller->setInput($this->input);
// $controller->setModule($this->input->getArgument('module')); // $controller->setModule($this->input->getArgument('module'));
$controller->setControllerPath($this->controllerPath); $controller->setControllerPath($this->controllerPath);
$controller->setControllerNamespace($this->controllerNamespace); $controller->setControllerNamespace($this->controllerNamespace);
return $controller->generate(); return $controller->generate();
} }
/** /**
* @param array $data * @param array $data
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
private function generateController(array $data): string private function generateController(array $data): string
{ {
$controller = new GiiController($data['classFileName'], $data['fields']); $controller = new GiiController($data['classFileName'], $data['fields']);
$controller->setConnection($this->db); $controller->setConnection($this->db);
$controller->setModelPath($this->modelPath); $controller->setModelPath($this->modelPath);
$controller->setInput($this->input); $controller->setInput($this->input);
$controller->setModelNamespace($this->modelNamespace); $controller->setModelNamespace($this->modelNamespace);
$controller->setControllerPath($this->controllerPath); $controller->setControllerPath($this->controllerPath);
$controller->setModule($this->input->getArgument('module')); $controller->setModule($this->input->getArgument('module'));
$controller->setControllerNamespace($this->controllerNamespace); $controller->setControllerNamespace($this->controllerNamespace);
return $controller->generate(); return $controller->generate();
} }
/** /**
* @return array|string|null * @return array|string|null
* @throws Exception * @throws Exception
*/ */
private function getTables(): array|string|null private function getTables(): array|string|null
{ {
if (empty($this->tableName)) { if (empty($this->tableName)) {
return $this->showAll(); return $this->showAll();
} }
$res = $this->tableName; $res = $this->tableName;
if (is_string($res)) { if (is_string($res)) {
$res = explode(',', $this->tableName); $res = explode(',', $this->tableName);
} }
if (empty($res)) { if (empty($res)) {
return []; return [];
} }
return $res; return $res;
} }
/** /**
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
private function showAll(): array private function showAll(): array
{ {
$res = []; $res = [];
$_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db); $_tables = Db::findAllBySql('show tables from `' . $this->db->database . '`', [], $this->db);
if (empty($_tables)) { if (empty($_tables)) {
return $res; return $res;
} }
foreach ($_tables as $key => $val) { foreach ($_tables as $key => $val) {
$res[] = array_shift($val); $res[] = array_shift($val);
} }
return $res; return $res;
} }
/** /**
* @param $table * @param $table
* @return bool|int|null * @return bool|int|null
* @throws Exception * @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 * @return array
* @throws * @throws
*/ */
private function getFields($tables): array private function getFields($tables): array
{ {
$res = []; $res = [];
if (!is_array($tables)) { if (!is_array($tables)) {
$tables = [$tables]; $tables = [$tables];
} }
foreach ($tables as $key => $val) { foreach ($tables as $key => $val) {
if (empty($val)) continue; if (empty($val)) continue;
$_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db); $_tmp = Db::findAllBySql('SHOW FULL FIELDS FROM `' . $this->db->database . '`.' . $val, [], $this->db);
if (empty($_tmp)) { if (empty($_tmp)) {
continue; continue;
} }
$res[$val] = $_tmp; $res[$val] = $_tmp;
} }
return $res; return $res;
} }
/** /**
* @param $tableName * @param $tableName
* @param $tables * @param $tables
* *
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function createModelFile($tableName, $tables): array public function createModelFile($tableName, $tables): array
{ {
$res = $visible = $fields = $keys = []; $res = $visible = $fields = $keys = [];
foreach ($tables as $_key => $_val) { foreach ($tables as $_key => $_val) {
$keys = $tableName; $keys = $tableName;
if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') { if ($_val['Extra'] == 'auto_increment' || $_val['Key'] == 'PRI') {
$keys = $tableName; $keys = $tableName;
} }
if (!isset($keys) && !($index = $this->getIndex($tableName))) { if (!isset($keys) && !($index = $this->getIndex($tableName))) {
$keys = $index['Column_name']; $keys = $index['Column_name'];
} }
if (in_array(strtoupper($_val['Field']), $this->keyword)) { if (in_array(strtoupper($_val['Field']), $this->keyword)) {
throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"'); throw new Exception('You can not use keyword "' . $_val['Field'] . '" as field at table "' . $tableName . '"');
} }
array_push($visible, $this->createVisible($_val['Field'])); array_push($visible, $this->createVisible($_val['Field']));
array_push($fields, $_val); array_push($fields, $_val);
$res[] = $this->createSetFunc($_val['Field'], $_val['Comment']); $res[] = $this->createSetFunc($_val['Field'], $_val['Comment']);
} }
$classFileName = $this->getClassName($tableName); $classFileName = $this->getClassName($tableName);
return [ return [
'classFileName' => $classFileName, 'classFileName' => $classFileName,
'tableName' => $keys, 'tableName' => $keys,
'visible' => $visible, 'visible' => $visible,
'fields' => $fields, 'fields' => $fields,
'res' => $res, 'res' => $res,
]; ];
} }
/** /**
* @param $field * @param $field
* @return string * @return string
* 创建变量注释 * 创建变量注释
*/ */
private function createVisible($field): string private function createVisible($field): string
{ {
return ' return '
* @property $' . $field; * @property $' . $field;
} }
/** /**
* @param $field * @param $field
* @param $comment * @param $comment
* @return string * @return string
* 暂时不知道干嘛用的 * 暂时不知道干嘛用的
*/ */
private function createSetFunc($field, $comment): string private function createSetFunc($field, $comment): string
{ {
return ' return '
' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\','; ' . str_pad('\'' . $field . '\'', 20, ' ', STR_PAD_RIGHT) . '=> \'' . (empty($comment) ? ucfirst($field) : $comment) . '\',';
} }
/** /**
* @param $tableName * @param $tableName
* @return string * @return string
* 构建类名称 * 构建类名称
*/ */
private function getClassName($tableName): string private function getClassName($tableName): string
{ {
$res = []; $res = [];
$tableName = str_replace($this->db->tablePrefix,'', $tableName); $tableName = str_replace($this->db->tablePrefix,'', $tableName);
foreach (explode('_', $tableName) as $n => $val) { foreach (explode('_', $tableName) as $n => $val) {
$res[] = ucfirst($val); $res[] = ucfirst($val);
} }
return implode('', $res); return implode('', $res);
} }
} }
+411 -411
View File
@@ -1,411 +1,411 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Database\Connection; use Database\Connection;
use Exception; use Exception;
use Kiri\Core\Json; use Kiri\Core\Json;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
/** /**
* Class GiiBase * Class GiiBase
* @package Gii * @package Gii
*/ */
abstract class GiiBase abstract class GiiBase
{ {
public array $fileList = []; public array $fileList = [];
protected InputInterface $input; protected InputInterface $input;
public string $modelPath = APP_PATH . 'app/Model/'; public string $modelPath = APP_PATH . 'app/Model/';
public string $modelNamespace = 'App\Model\\'; public string $modelNamespace = 'App\Model\\';
public string $controllerPath = APP_PATH . 'app/Http/Controller/'; public string $controllerPath = APP_PATH . 'app/Http/Controller/';
public string $controllerNamespace = 'App\\Controller\\'; public string $controllerNamespace = 'App\\Controller\\';
public ?string $module = null; public ?string $module = null;
public array $rules = []; public array $rules = [];
public array $type = [ public array $type = [
'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'], 'int' => ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'],
'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'], 'string' => ['char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext', 'enum'],
'date' => ['date'], 'date' => ['date'],
'time' => ['time'], 'time' => ['time'],
'year' => ['year'], 'year' => ['year'],
'datetime' => ['datetime'], 'datetime' => ['datetime'],
'timestamp' => ['timestamp'], 'timestamp' => ['timestamp'],
'float' => ['float', 'double', 'decimal',], 'float' => ['float', 'double', 'decimal',],
]; ];
public ?string $tableName = NULL; public ?string $tableName = NULL;
public ?Connection $db = null; public ?Connection $db = null;
/** /**
* @param string $modelPath * @param string $modelPath
*/ */
public function setModelPath(string $modelPath): void public function setModelPath(string $modelPath): void
{ {
$this->modelPath = $modelPath; $this->modelPath = $modelPath;
} }
/** /**
* @param string $modelNamespace * @param string $modelNamespace
*/ */
public function setModelNamespace(string $modelNamespace): void public function setModelNamespace(string $modelNamespace): void
{ {
$this->modelNamespace = $modelNamespace; $this->modelNamespace = $modelNamespace;
} }
/** /**
* @param string $controllerPath * @param string $controllerPath
*/ */
public function setControllerPath(string $controllerPath): void public function setControllerPath(string $controllerPath): void
{ {
$this->controllerPath = $controllerPath; $this->controllerPath = $controllerPath;
} }
/** /**
* @param $module * @param $module
*/ */
public function setModule($module) public function setModule($module)
{ {
$this->module = $module; $this->module = $module;
} }
/** /**
* @param string $controllerNamespace * @param string $controllerNamespace
*/ */
public function setControllerNamespace(string $controllerNamespace): void public function setControllerNamespace(string $controllerNamespace): void
{ {
$this->controllerNamespace = $controllerNamespace; $this->controllerNamespace = $controllerNamespace;
} }
/** /**
* @param InputInterface $input * @param InputInterface $input
*/ */
public function setInput(InputInterface $input) public function setInput(InputInterface $input)
{ {
$this->input = $input; $this->input = $input;
} }
/** /**
* @param ReflectionClass $object * @param ReflectionClass $object
* @param $className * @param $className
* *
* @return string * @return string
*/ */
public function getUseContent(ReflectionClass $object, $className): string public function getUseContent(ReflectionClass $object, $className): string
{ {
if (empty($object)) { if (empty($object)) {
return ''; return '';
} }
$file = $this->getFilePath($className); $file = $this->getFilePath($className);
if (!file_exists($file)) { if (!file_exists($file)) {
return ''; return '';
} }
$content = file_get_contents($file); $content = file_get_contents($file);
$explode = explode(PHP_EOL, $content); $explode = explode(PHP_EOL, $content);
$exists = array_slice($explode, 0, $object->getStartLine()); $exists = array_slice($explode, 0, $object->getStartLine());
$_tmp = []; $_tmp = [];
foreach ($exists as $key => $val) { foreach ($exists as $key => $val) {
if (trim($val) == '/**') { if (trim($val) == '/**') {
break; break;
} }
$_tmp[] = $val; $_tmp[] = $val;
} }
return trim(implode(PHP_EOL, $_tmp)); return trim(implode(PHP_EOL, $_tmp));
} }
/** /**
* @param string $fileName * @param string $fileName
* @param ReflectionClass $class * @param ReflectionClass $class
* @return string * @return string
*/ */
protected function getImports(string $fileName, ReflectionClass $class): string protected function getImports(string $fileName, ReflectionClass $class): string
{ {
$startLine = 1; $startLine = 1;
$array = []; $array = [];
$fileOpen = fopen($fileName, 'r'); $fileOpen = fopen($fileName, 'r');
while (($content = fgets($fileOpen)) !== false) { while (($content = fgets($fileOpen)) !== false) {
if (str_starts_with($content, 'use ')) { if (str_starts_with($content, 'use ')) {
$array[] = $content; $array[] = $content;
} }
if ($startLine == $class->getStartLine()) { if ($startLine == $class->getStartLine()) {
break; break;
} }
++$startLine; ++$startLine;
} }
return implode($array); return implode($array);
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @return string * @return string
* @throws ReflectionException * @throws ReflectionException
*/ */
protected function getClassProperty(ReflectionClass $class): string protected function getClassProperty(ReflectionClass $class): string
{ {
$html = ''; $html = '';
$rc = $class->getParentClass()->getConstants(); $rc = $class->getParentClass()->getConstants();
foreach ($class->getConstants() as $key => $val) { foreach ($class->getConstants() as $key => $val) {
if (isset($rc[$key])) { if (isset($rc[$key])) {
continue; continue;
} }
if (is_numeric($val)) { if (is_numeric($val)) {
$html .= ' $html .= '
const ' . $key . ' = ' . $val . ';' . "\n"; const ' . $key . ' = ' . $val . ';' . "\n";
} else { } else {
$html .= ' $html .= '
const ' . $key . ' = \'' . $val . '\';' . "\n"; const ' . $key . ' = \'' . $val . '\';' . "\n";
} }
} }
foreach ($class->getDefaultProperties() as $key => $val) { foreach ($class->getDefaultProperties() as $key => $val) {
$property = $class->getProperty($key); $property = $class->getProperty($key);
if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') { if ($key == 'primary' || $key == 'table' || $key == 'connection' || $key == 'rules') {
continue; continue;
} }
if ($property->class != $class->getName()) continue; if ($property->class != $class->getName()) continue;
if (is_array($val)) { if (is_array($val)) {
$val = '[\'' . implode('\', \'', $val) . '\']'; $val = '[\'' . implode('\', \'', $val) . '\']';
} else if (!is_numeric($val)) { } else if (!is_numeric($val)) {
$val = '\'' . $val . '\''; $val = '\'' . $val . '\'';
} }
if ($property->isProtected()) { if ($property->isProtected()) {
$debug = 'protected'; $debug = 'protected';
} else if ($property->isPrivate()) { } else if ($property->isPrivate()) {
$debug = 'private'; $debug = 'private';
} else { } else {
$debug = 'public'; $debug = 'public';
} }
if ($property->hasType()) { if ($property->hasType()) {
$type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n"; $type = ' ' . $property->getType() . ' $' . $key . ' = ' . $val . ';' . "\n";
} else { } else {
$type = ' $' . $key . ' = ' . $val . ';' . "\n"; $type = ' $' . $key . ' = ' . $val . ';' . "\n";
} }
if ($property->isStatic()) { if ($property->isStatic()) {
$html .= ' $html .= '
' . $debug . ' static' . $type; ' . $debug . ' static' . $type;
} else { } else {
$html .= ' $html .= '
' . $debug . $type; ' . $debug . $type;
} }
} }
return $html; return $html;
} }
/** /**
* @param ReflectionClass $class * @param ReflectionClass $class
* @param array $filters * @param array $filters
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
protected function getClassMethods(ReflectionClass $class, array $filters = []): string protected function getClassMethods(ReflectionClass $class, array $filters = []): string
{ {
$methods = $class->getMethods(); $methods = $class->getMethods();
$classFileName = str_replace(APP_PATH, '', $class->getFileName()); $classFileName = str_replace(APP_PATH, '', $class->getFileName());
$content = []; $content = [];
if (!empty($methods)) foreach ($methods as $key => $val) { if (!empty($methods)) foreach ($methods as $key => $val) {
if ($val->class != $class->getName()) continue; if ($val->class != $class->getName()) continue;
if (in_array($val->name, $filters)) continue; if (in_array($val->name, $filters)) continue;
$over = " $over = "
" . $val->getDocComment() . "\n"; " . $val->getDocComment() . "\n";
$attributes = $val->getAttributes(); $attributes = $val->getAttributes();
if (!empty($attributes)) { if (!empty($attributes)) {
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
$explode = explode('\\', $attribute->getName()); $explode = explode('\\', $attribute->getName());
$_array = []; $_array = [];
foreach ($attribute->getArguments() as $_key => $argument) { foreach ($attribute->getArguments() as $_key => $argument) {
$argument = $this->resolveArray($argument); $argument = $this->resolveArray($argument);
if (is_numeric($_key)) { if (is_numeric($_key)) {
$_array[] = $argument; $_array[] = $argument;
} else { } else {
$_array[] = $_key . ': ' . $argument . ''; $_array[] = $_key . ': ' . $argument . '';
} }
} }
if (empty($_array)) { if (empty($_array)) {
$end = " #[" . end($explode) . "] $end = " #[" . end($explode) . "]
"; ";
} else { } else {
$end = " #[" . end($explode) . "(" . implode(',', $_array) . ")] $end = " #[" . end($explode) . "(" . implode(',', $_array) . ")]
"; ";
} }
if (str_contains($over, $end)) { if (str_contains($over, $end)) {
$over = str_replace($end, '', $over); $over = str_replace($end, '', $over);
} }
$over .= $end; $over .= $end;
} }
} }
$func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n"; $func = $this->getFuncLineContent($class, $classFileName, $val->name) . "\n";
$content[] = $over . $func; $content[] = $over . $func;
} }
return implode(PHP_EOL, $content); return implode(PHP_EOL, $content);
} }
/** /**
* @param $argument * @param $argument
* @return string * @return string
*/ */
private function resolveArray($argument): string private function resolveArray($argument): string
{ {
if (is_array($argument)) { if (is_array($argument)) {
$__array = []; $__array = [];
foreach ($argument as $key => $value) { foreach ($argument as $key => $value) {
if (is_string($value)) { if (is_string($value)) {
if (str_contains($value, '\\') && class_exists($value)) { if (str_contains($value, '\\') && class_exists($value)) {
$explode_class = explode('\\', $value); $explode_class = explode('\\', $value);
$__array[] = end($explode_class) . '::class'; $__array[] = end($explode_class) . '::class';
} else { } else {
$__array[] = '\'' . $value . '\''; $__array[] = '\'' . $value . '\'';
} }
} else { } else {
$value = str_replace('{', '[', Json::encode($value)); $value = str_replace('{', '[', Json::encode($value));
$value = str_replace('}', ']', Json::encode($value)); $value = str_replace('}', ']', Json::encode($value));
$value = str_replace(':', '=>', Json::encode($value)); $value = str_replace(':', '=>', Json::encode($value));
$value = preg_replace('/"\d+"\=\>/', '', $value); $value = preg_replace('/"\d+"\=\>/', '', $value);
$__array[] = $value; $__array[] = $value;
} }
} }
$argument = '[' . implode(', ', $__array) . ']'; $argument = '[' . implode(', ', $__array) . ']';
} else { } else {
$argument = '\'' . $argument . '\''; $argument = '\'' . $argument . '\'';
} }
return $argument; return $argument;
} }
/** /**
* @param $fields * @param $fields
* @return mixed 返回表主键 * @return mixed 返回表主键
* 返回表主键 * 返回表主键
*/ */
public function getPrimaryKey($fields): mixed public function getPrimaryKey($fields): mixed
{ {
$condition = ['PRI', 'UNI']; $condition = ['PRI', 'UNI'];
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field['Extra'] == 'auto_increment') { if ($field['Extra'] == 'auto_increment') {
return $field['Field']; return $field['Field'];
} }
if (in_array($field['Key'], $condition)) { if (in_array($field['Key'], $condition)) {
return $field['Field']; return $field['Field'];
} }
} }
return null; return null;
} }
/** /**
* @param $className * @param $className
* @return string * @return string
*/ */
private function getFilePath($className): string private function getFilePath($className): string
{ {
if (strpos($className, '\\')) { if (strpos($className, '\\')) {
$className = str_replace('\\', '/', $className); $className = str_replace('\\', '/', $className);
} }
if (strpos($className, '\\')) { if (strpos($className, '\\')) {
$className = str_replace('\\', '/', $className); $className = str_replace('\\', '/', $className);
} }
return APP_PATH . $className; return APP_PATH . $className;
} }
/** /**
* @param ReflectionClass $object * @param ReflectionClass $object
* @param $className * @param $className
* @param $method * @param $method
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public function getFuncLineContent(ReflectionClass $object, $className, $method): string public function getFuncLineContent(ReflectionClass $object, $className, $method): string
{ {
$fun = $object->getMethod($method); $fun = $object->getMethod($method);
$content = file_get_contents($this->getFilePath($className)); $content = file_get_contents($this->getFilePath($className));
$explode = explode(PHP_EOL, $content); $explode = explode(PHP_EOL, $content);
$exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1); $exists = array_slice($explode, $fun->getStartLine() - 1, $fun->getEndLine() - $fun->getStartLine() + 1);
return implode(PHP_EOL, $exists); return implode(PHP_EOL, $exists);
} }
/** /**
* @return array * @return array
*/ */
protected function getModelPath(): array protected function getModelPath(): array
{ {
$dbName = $this->db->id; $dbName = $this->db->id;
if (empty($dbName) || $dbName == 'db') { if (empty($dbName) || $dbName == 'db') {
$dbName = ''; $dbName = '';
} }
$modelPath = [ $modelPath = [
'namespace' => $this->modelNamespace, 'namespace' => $this->modelNamespace,
'path' => $this->modelPath, 'path' => $this->modelPath,
]; ];
if (!is_dir($modelPath['path'])) { if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']); mkdir($modelPath['path']);
} }
if (!empty($dbName)) { if (!empty($dbName)) {
$modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName); $modelPath['namespace'] = $this->modelNamespace . ucfirst($dbName);
$modelPath['path'] = $this->modelPath . ucfirst($dbName); $modelPath['path'] = $this->modelPath . ucfirst($dbName);
} }
if (!is_dir($modelPath['path'])) { if (!is_dir($modelPath['path'])) {
mkdir($modelPath['path']); mkdir($modelPath['path']);
} }
return $modelPath; return $modelPath;
} }
/** /**
* @param $db * @param $db
*/ */
public function setConnection($db) public function setConnection($db)
{ {
$this->db = $db; $this->db = $db;
} }
/** /**
* @param $val * @param $val
* @return string * @return string
*/ */
protected function checkIsRequired($val): string protected function checkIsRequired($val): string
{ {
return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false'; return strtolower($val['Null']) == 'no' && $val['Default'] === NULL ? 'true' : 'false';
} }
/** /**
* @return array * @return array
*/ */
public function getFileLists(): array public function getFileLists(): array
{ {
return $this->fileList; return $this->fileList;
} }
} }
+76 -76
View File
@@ -1,76 +1,76 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace Gii; namespace Gii;
use Exception; use Exception;
use Kiri\Abstracts\Config; use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Kiri; use Kiri\Kiri;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
/** /**
* Class Command * Class Command
* @package Http * @package Http
*/ */
class GiiCommand extends Command class GiiCommand extends Command
{ {
public string $command = 'sw:gii'; public string $command = 'sw:gii';
public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx'; public string $description = './snowflake sw:gii make=model|controller|task|interceptor|limits|middleware name=xxxx';
/** /**
* *
*/ */
protected function configure() protected function configure()
{ {
$this->setName('sw:gii') $this->setName('sw:gii')
->addOption('make','m', InputArgument::OPTIONAL) ->addOption('make','m', InputArgument::OPTIONAL)
->addOption('name','t', InputArgument::OPTIONAL) ->addOption('name','t', InputArgument::OPTIONAL)
->addOption('databases','d', 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->getOption('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->getOption('make'); $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 Kiri\Annotation\Target; use Kiri\Annotation\Target;
use Kiri\Annotation\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 Kiri\Annotation\Target; use Kiri\Annotation\Target;
use Kiri\Rpc\Annotation\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