变更
This commit is contained in:
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Class Attribute
|
||||
* @package Annotation
|
||||
*/
|
||||
abstract class AbstractAttribute implements IAnnotation
|
||||
{
|
||||
|
||||
|
||||
protected object $_class;
|
||||
|
||||
|
||||
protected string $_method;
|
||||
|
||||
|
||||
/**
|
||||
* @param static $class
|
||||
* @param mixed|string $method
|
||||
* @return mixed
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function execute(mixed $class, mixed $method = ''): mixed
|
||||
{
|
||||
// TODO: Implement execute() method.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object
|
||||
*/
|
||||
public function getClass(): object
|
||||
{
|
||||
return $this->_class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $class
|
||||
*/
|
||||
public function setClass(object $class): void
|
||||
{
|
||||
$this->_class = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
*/
|
||||
public function setMethod(string $method): void
|
||||
{
|
||||
$this->_method = $method;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
use DirectoryIterator;
|
||||
use Exception;
|
||||
use ReflectionException;
|
||||
use Kiri\Abstracts\Component;
|
||||
|
||||
/**
|
||||
* Class Annotation
|
||||
* @package Annotation
|
||||
*/
|
||||
class Annotation extends Component
|
||||
{
|
||||
|
||||
|
||||
private Loader $_loader;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function init(): void
|
||||
{
|
||||
$this->_loader = new Loader();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Loader
|
||||
*/
|
||||
public function getLoader(): Loader
|
||||
{
|
||||
return $this->_loader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Loader $loader
|
||||
* @return Loader
|
||||
*/
|
||||
public function setLoader(Loader $loader): Loader
|
||||
{
|
||||
return $this->_loader = $loader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object $class
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function injectProperty(object $class)
|
||||
{
|
||||
$this->_loader->injectProperty($class::class, $class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $namespace
|
||||
* @param array $exclude
|
||||
* @return static
|
||||
* @throws Exception
|
||||
*/
|
||||
public function read(string $path, string $namespace = 'App', array $exclude = []): static
|
||||
{
|
||||
$this->_loader->_scanDir(new DirectoryIterator($path), $namespace, $exclude);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
* @param array $exclude
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function runtime(string $dir, array $exclude = []): array
|
||||
{
|
||||
return $this->_loader->loadByDirectory($dir, $exclude);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
use Exception;
|
||||
|
||||
defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement ');
|
||||
|
||||
/**
|
||||
* Class Aspect
|
||||
* @package Annotation
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Aspect constructor.
|
||||
* @param string $aspect
|
||||
*/
|
||||
public function __construct(public string $aspect)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute(mixed $class, mixed $method = ''): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri;
|
||||
use Kiri\Events\EventProvider;
|
||||
|
||||
|
||||
/**
|
||||
* Class Event
|
||||
* @package Annotation
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD)] class Event extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Event constructor.
|
||||
* @param string $name
|
||||
* @param array $params
|
||||
*/
|
||||
public function __construct(public string $name, public array $params = [])
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public function __serialize()
|
||||
{
|
||||
// TODO: Implement __serialize() method.
|
||||
}
|
||||
|
||||
|
||||
public function __unserialize(array $data)
|
||||
{
|
||||
// TODO: Implement __unserialize() method.
|
||||
}
|
||||
|
||||
|
||||
public function serialize(): array
|
||||
{
|
||||
// TODO: Implement __serialize() method.
|
||||
}
|
||||
|
||||
|
||||
public function unserialize(array|string $data): void
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $class
|
||||
* @param mixed|null $method
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute(mixed $class, mixed $method = null): bool
|
||||
{
|
||||
$pro = Kiri::getDi()->get(EventProvider::class);
|
||||
if (is_string($class)) {
|
||||
$class = Kiri::getDi()->get($class);
|
||||
}
|
||||
$pro->on($this->name, [$class, $method]);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
|
||||
interface IAnnotation
|
||||
{
|
||||
|
||||
/**
|
||||
* @param mixed $class
|
||||
* @param mixed $method
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute(mixed $class, mixed $method = ''): mixed;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Core\Str;
|
||||
use Kiri;
|
||||
use Kiri\Di\LocalService;
|
||||
use ReflectionException;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Class Inject
|
||||
* @package Annotation
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_PROPERTY)] class Inject extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Inject constructor.
|
||||
* @param string $value
|
||||
* @param array $construct
|
||||
*/
|
||||
public function __construct(public string $value, public array $construct = [])
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $class
|
||||
* @param mixed|null $method
|
||||
* @return bool
|
||||
* @throws ReflectionException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute(mixed $class, mixed $method = null): bool
|
||||
{
|
||||
if (!($method = $this->getProperty($class, $method))) {
|
||||
return false;
|
||||
}
|
||||
/** @var ReflectionProperty $class */
|
||||
$injectValue = static::parseInjectValue();
|
||||
if ($method->isPrivate() || $method->isProtected()) {
|
||||
$this->setter($class, $method, $injectValue);
|
||||
} else {
|
||||
$class->{$method->getName()} = $injectValue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @param $method
|
||||
* @param $injectValue
|
||||
*/
|
||||
private function setter($class, $method, $injectValue)
|
||||
{
|
||||
$method = 'set' . ucfirst(Str::convertUnderline($method->getName()));
|
||||
if (!method_exists($class, $method)) {
|
||||
return;
|
||||
}
|
||||
$class->$method($injectValue);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @param $method
|
||||
* @return ReflectionProperty|bool
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function getProperty($class, $method): ReflectionProperty|bool
|
||||
{
|
||||
if ($method instanceof ReflectionProperty && !$method->isStatic()) {
|
||||
return $method;
|
||||
}
|
||||
if (is_object($class)) $class = $class::class;
|
||||
$method = Kiri::getDi()->getClassReflectionProperty($class, $method);
|
||||
if (!$method || $method->isStatic()) {
|
||||
return false;
|
||||
}
|
||||
return $method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
private function parseInjectValue(): mixed
|
||||
{
|
||||
$localService = Kiri::getDi()->get(LocalService::class);
|
||||
if ($localService->has($this->value)) {
|
||||
return $localService->get($this->value);
|
||||
}
|
||||
if (!empty($this->construct)) {
|
||||
return instance($this->value, $this->construct);
|
||||
}
|
||||
return di($this->value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
use DirectoryIterator;
|
||||
use Exception;
|
||||
use Kiri;
|
||||
use Kiri\Abstracts\Component;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use Throwable;
|
||||
|
||||
|
||||
/**
|
||||
* Class Loader
|
||||
* @package Annotation
|
||||
*/
|
||||
class Loader extends Component
|
||||
{
|
||||
|
||||
|
||||
private array $_directory = [];
|
||||
|
||||
|
||||
private array $_methods = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @param $namespace
|
||||
* @throws Exception
|
||||
*/
|
||||
public function loader($path, $namespace)
|
||||
{
|
||||
$this->_scanDir(new DirectoryIterator($path), $namespace);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param object $handler
|
||||
* @return $this
|
||||
* @throws ReflectionException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function injectProperty(string $class, object $handler): static
|
||||
{
|
||||
$di = Kiri::getDi();
|
||||
|
||||
$reflect = $di->getReflect($class);
|
||||
|
||||
$di->propertyInject($reflect, $handler);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $method
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMethod(string $class, string $method = ''): array
|
||||
{
|
||||
if (!isset($this->_methods[$class])) {
|
||||
return [];
|
||||
}
|
||||
$properties = $this->_methods[$class];
|
||||
if (!empty($method) && isset($properties[$method])) {
|
||||
return $properties[$method];
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param DirectoryIterator $paths
|
||||
* @param $namespace
|
||||
* @param array $exclude
|
||||
* @throws Exception
|
||||
*/
|
||||
public function _scanDir(DirectoryIterator $paths, $namespace, array $exclude = [])
|
||||
{
|
||||
foreach ($paths as $path) {
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate($path->getRealPath(), true);
|
||||
}
|
||||
if ($path->isDot() || str_starts_with($path->getFilename(), '.')) {
|
||||
continue;
|
||||
}
|
||||
if ($this->inExclude($exclude, $path->getRealPath())) {
|
||||
continue;
|
||||
}
|
||||
if ($path->isDir()) {
|
||||
$iterator = new DirectoryIterator($path->getRealPath());
|
||||
$directory = rtrim($path->getRealPath(), '/');
|
||||
if (!isset($this->_directory[$directory])) {
|
||||
$this->_directory[$directory] = [];
|
||||
}
|
||||
$this->_scanDir($iterator, $namespace);
|
||||
} else {
|
||||
$this->readFile($path, $namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param DirectoryIterator $path
|
||||
* @param $namespace
|
||||
* @throws Exception
|
||||
*/
|
||||
private function readFile(DirectoryIterator $path, $namespace)
|
||||
{
|
||||
try {
|
||||
if ($path->getExtension() !== 'php') {
|
||||
return;
|
||||
}
|
||||
$replace = $this->getReflect($path, $namespace);
|
||||
if (!$replace || !$replace->getAttributes(Target::class)) {
|
||||
return;
|
||||
}
|
||||
$this->appendFileToDirectory($path->getRealPath(), $replace->getName());
|
||||
} catch (Throwable $throwable) {
|
||||
$this->logger->error(jTraceEx($throwable));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param DirectoryIterator $path
|
||||
* @param string $namespace
|
||||
* @return ReflectionClass|null
|
||||
*/
|
||||
private function getReflect(DirectoryIterator $path, string $namespace): ?ReflectionClass
|
||||
{
|
||||
$class = $this->explodeFileName($path, $namespace);
|
||||
if (!class_exists($class)) {
|
||||
return null;
|
||||
}
|
||||
return Kiri::getDi()->getReflectionClass($class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $exclude
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function loadByDirectory(string $path, array $exclude = []): array
|
||||
{
|
||||
try {
|
||||
$path = '/' . trim($path, '/');
|
||||
$paths = [];
|
||||
foreach ($this->_directory as $key => $_path) {
|
||||
$key = '/' . trim($key, '/');
|
||||
if (!str_starts_with($key, $path) || $this->inExclude($exclude, $path)) {
|
||||
continue;
|
||||
}
|
||||
unset($this->_directory[$key]);
|
||||
foreach ($_path as $item) {
|
||||
$paths[] = $item;
|
||||
}
|
||||
}
|
||||
return $paths;
|
||||
} catch (Throwable $exception) {
|
||||
$this->logger->addError($exception, 'throwable');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $exclude
|
||||
* @param $path
|
||||
* @return bool
|
||||
*/
|
||||
private function inExclude(array $exclude, $path): bool
|
||||
{
|
||||
if (empty($exclude)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($exclude as $value) {
|
||||
if (str_starts_with($path, $value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param DirectoryIterator $path
|
||||
* @param string $namespace
|
||||
* @return string
|
||||
*/
|
||||
private function explodeFileName(DirectoryIterator $path, string $namespace): string
|
||||
{
|
||||
$replace = str_replace(APP_PATH, '', $path->getRealPath());
|
||||
|
||||
$replace = str_replace('.php', '', $replace);
|
||||
$replace = str_replace(DIRECTORY_SEPARATOR, '\\', $replace);
|
||||
$explode = explode('\\', $replace);
|
||||
array_shift($explode);
|
||||
|
||||
return $namespace . '\\' . implode('\\', $explode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $filePath
|
||||
* @param string $className
|
||||
*/
|
||||
public function appendFileToDirectory(string $filePath, string $className)
|
||||
{
|
||||
$array = explode('/', $filePath);
|
||||
unset($array[count($array) - 1]);
|
||||
|
||||
$array = '/' . trim(implode('/', $array), '/');
|
||||
|
||||
$this->_directory[$array][] = $className;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
use Kiri;
|
||||
|
||||
#[\Attribute(\Attribute::TARGET_CLASS)] class Mapping extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
*/
|
||||
public function __construct(public string $class)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $class
|
||||
* @param mixed|string $method
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute(mixed $class, mixed $method = ''): mixed
|
||||
{
|
||||
Kiri::getDi()->mapping($this->class, $class);
|
||||
|
||||
return parent::execute($class, $method);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation\Route;
|
||||
|
||||
|
||||
use Kiri\Annotation\AbstractAttribute;
|
||||
|
||||
/**
|
||||
* Class Document
|
||||
* @package Annotation\Route
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD)] class Document extends AbstractAttribute
|
||||
{
|
||||
|
||||
const INTEGER = 'int';
|
||||
const STRING = 'string';
|
||||
const BOOLEAN = 'bool';
|
||||
const FLOAT = 'float';
|
||||
|
||||
const ALIAS = [
|
||||
self::INTEGER => '整数',
|
||||
self::STRING => '字符串',
|
||||
self::BOOLEAN => '布尔值',
|
||||
self::FLOAT => '浮点',
|
||||
];
|
||||
|
||||
|
||||
public function __construct(array $request, array $response)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation\Route;
|
||||
|
||||
|
||||
use Kiri\Annotation\AbstractAttribute;
|
||||
use Kiri\Message\Handler\Abstracts\MiddlewareManager;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
|
||||
/**
|
||||
* Class Middleware
|
||||
* @package Annotation\Route
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Middleware extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Interceptor constructor.
|
||||
* @param string|array $middleware
|
||||
* @throws
|
||||
*/
|
||||
public function __construct(public string|array $middleware)
|
||||
{
|
||||
if (is_string($this->middleware)) {
|
||||
$this->middleware = [$this->middleware];
|
||||
}
|
||||
$array = [];
|
||||
foreach ($this->middleware as $value) {
|
||||
if (!in_array(MiddlewareInterface::class, class_implements($value))) {
|
||||
throw new \Exception('The middleware');
|
||||
}
|
||||
$array[] = $value;
|
||||
}
|
||||
$this->middleware = $array;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $class
|
||||
* @param mixed|null $method
|
||||
* @return $this
|
||||
*/
|
||||
public function execute(mixed $class, mixed $method = null): mixed
|
||||
{
|
||||
MiddlewareManager::add($class, $method, $this->middleware);
|
||||
return parent::execute($class, $method);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Kiri\Annotation\Route;
|
||||
|
||||
use Kiri\Annotation\AbstractAttribute;
|
||||
|
||||
#[\Attribute(\Attribute::TARGET_METHOD)] class RequestMapping extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param RequestMethod $method
|
||||
* @param string $path
|
||||
* @param string|null $version
|
||||
*/
|
||||
public function __construct(RequestMethod $method, string $path, string $version = null)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Kiri\Annotation\Route;
|
||||
|
||||
enum RequestMethod
|
||||
{
|
||||
|
||||
|
||||
case REQUEST_POST;
|
||||
case REQUEST_GET;
|
||||
case REQUEST_HEAD;
|
||||
case REQUEST_OPTIONS;
|
||||
case REQUEST_DELETE;
|
||||
case REQUEST_PUT;
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getString(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::REQUEST_POST => 'POST',
|
||||
self::REQUEST_GET => 'GET',
|
||||
self::REQUEST_HEAD => 'HEAD',
|
||||
self::REQUEST_OPTIONS => 'OPTIONS',
|
||||
self::REQUEST_DELETE => 'DELETE',
|
||||
self::REQUEST_PUT => 'PUT'
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation\Route;
|
||||
|
||||
|
||||
use Kiri\Annotation\AbstractAttribute;
|
||||
use Kiri\Message\Handler\Router;
|
||||
use Kiri;
|
||||
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class Route extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Route constructor.
|
||||
* @param string $uri
|
||||
* @param RequestMethod $method
|
||||
* @param string $version
|
||||
*/
|
||||
public function __construct(public string $uri, public RequestMethod $method, public string $version = 'v.1.0')
|
||||
{
|
||||
$this->uri = '/' . ltrim($this->uri, '/');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $class
|
||||
* @param mixed|null $method
|
||||
* @return bool
|
||||
*/
|
||||
public function execute(mixed $class, mixed $method = null): bool
|
||||
{
|
||||
$di = Kiri::getDi()->get(Router::class);
|
||||
$di->addRoute($this->method, $this->uri, $class . '@' . $method);
|
||||
return parent::execute($class, $method);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation\Route;
|
||||
|
||||
|
||||
use Kiri\Annotation\AbstractAttribute;
|
||||
|
||||
/**
|
||||
* Class Socket
|
||||
* @package Annotation
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD)] class Socket extends AbstractAttribute
|
||||
{
|
||||
|
||||
const CLOSE = 'CLOSE';
|
||||
const MESSAGE = 'MESSAGE';
|
||||
const HANDSHAKE = 'HANDSHAKE';
|
||||
|
||||
/**
|
||||
* Socket constructor.
|
||||
* @param string $event
|
||||
* @param string|null $uri
|
||||
* @param string $version
|
||||
*/
|
||||
public function __construct(string $event, ?string $uri = null, string $version = 'v.1.0')
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Kiri\Annotation\Route;
|
||||
|
||||
use Kiri\Annotation\Aspect;
|
||||
use Kiri\Error\LoggerAspect;
|
||||
|
||||
class TestController
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[RequestMapping(method: RequestMethod::REQUEST_GET, path: '/', version: 'v1')]
|
||||
#[Aspect(aspect: LoggerAspect::class)]
|
||||
#[Middleware(middleware: LoggerAspect::class)]
|
||||
public function index()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Kiri\Annotation;
|
||||
|
||||
|
||||
/**
|
||||
* Class Target
|
||||
* @package Annotation
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_CLASS)] class Target extends AbstractAttribute
|
||||
{
|
||||
|
||||
|
||||
const WORKER = 'worker';
|
||||
const ALL = 'any';
|
||||
const PROCESS = 'process';
|
||||
const TASK = 'task';
|
||||
|
||||
|
||||
/**
|
||||
* @param string $only
|
||||
*/
|
||||
public function __construct(string $only = Target::ALL)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,17 +29,11 @@ class Component implements Configure
|
||||
/**
|
||||
* BaseAbstract constructor.
|
||||
*
|
||||
* @param array $config
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
public function __construct()
|
||||
{
|
||||
if (is_null($this->logger)) {
|
||||
$this->logger = Kiri::getDi()->get(StdoutLoggerInterface::class);
|
||||
}
|
||||
if (!empty($config) && is_array($config)) {
|
||||
Kiri::configure($this, $config);
|
||||
}
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Kiri;
|
||||
|
||||
use Exception;
|
||||
use Kiri;
|
||||
use Kiri\Di\Container;
|
||||
use Kiri\Abstracts\{BaseMain, Config, Kernel};
|
||||
use Kiri\Events\{OnAfterCommandExecute, OnBeforeCommandExecute};
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
@@ -23,7 +24,6 @@ use Symfony\Component\Console\{Application as ConsoleApplication,
|
||||
Output\OutputInterface
|
||||
};
|
||||
use Kiri\Di\LocalService;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Error\ErrorHandler;
|
||||
|
||||
|
||||
@@ -120,6 +120,9 @@ class Main extends BaseMain
|
||||
$console = $this->container->get(ConsoleApplication::class);
|
||||
$command = $console->find($input->getFirstArgument());
|
||||
|
||||
$scanner = $this->container->get(Scanner::class);
|
||||
$scanner->read(APP_PATH);
|
||||
|
||||
fire(new OnBeforeCommandExecute());
|
||||
|
||||
$command->run($input, $output);
|
||||
|
||||
+58
-40
@@ -13,12 +13,15 @@ use Exception;
|
||||
use Kiri;
|
||||
use Kiri\Abstracts\Component;
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Core\Json;
|
||||
use Kiri\Events\EventProvider;
|
||||
use Kiri\Di\Inject\Container;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Exception\RedisConnectException;
|
||||
use Kiri\Pool\Pool;
|
||||
use Kiri\Server\Events\OnWorkerExit;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* Class Redis
|
||||
@@ -28,35 +31,41 @@ use Kiri\Server\Events\OnWorkerExit;
|
||||
class Redis extends Component
|
||||
{
|
||||
|
||||
private string $host = '';
|
||||
|
||||
const REDIS_OPTION_HOST = 'host';
|
||||
const REDIS_OPTION_PORT = 'port';
|
||||
const REDIS_OPTION_PREFIX = 'prefix';
|
||||
const REDIS_OPTION_AUTH = 'auth';
|
||||
const REDIS_OPTION_DATABASES = 'databases';
|
||||
const REDIS_OPTION_TIMEOUT = 'timeout';
|
||||
const REDIS_OPTION_POOL = 'pool';
|
||||
const REDIS_OPTION_POOL_TICK = 'tick';
|
||||
const REDIS_OPTION_POOL_MIN = 'min';
|
||||
const REDIS_OPTION_POOL_MAX = 'max';
|
||||
private int $port = 6379;
|
||||
|
||||
private string $prefix = 'api:';
|
||||
|
||||
private string $auth = '';
|
||||
|
||||
private int $databases = 0;
|
||||
|
||||
private int $timeout = 30;
|
||||
|
||||
|
||||
/**
|
||||
* @param EventProvider $eventProvider
|
||||
* @param Pool $pool
|
||||
* @param array $config
|
||||
* @throws Exception
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
public function __construct(public EventProvider $eventProvider,
|
||||
public Pool $pool, array $config = [])
|
||||
{
|
||||
parent::__construct($config);
|
||||
}
|
||||
#[Container(ContainerInterface::class)]
|
||||
readonly public ContainerInterface $container;
|
||||
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private int $read_timeout = -1;
|
||||
|
||||
/**
|
||||
* @var array|int[]
|
||||
*/
|
||||
private array $pool = ['min' => 1, 'max' => 100];
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws ConfigException
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function init(): void
|
||||
@@ -65,9 +74,11 @@ class Redis extends Component
|
||||
|
||||
$length = Config::get('cache.redis.pool.max', 10);
|
||||
|
||||
$this->eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0);
|
||||
$eventProvider = $this->container->get(EventProvider::class);
|
||||
$eventProvider->on(OnWorkerExit::class, [$this, 'destroy'], 0);
|
||||
|
||||
$this->pool->initConnections($config['host'], $length, static function () use ($config) {
|
||||
$pool = $this->container->get(Pool::class);
|
||||
$pool->initConnections($config['host'], $length, static function () use ($config) {
|
||||
$redis = new \Redis();
|
||||
if (!$redis->connect($config['host'], $config['port'], $config['timeout'])) {
|
||||
throw new RedisConnectException(sprintf('The Redis Connect %s::%d Fail.', $config['host'], $config['port']));
|
||||
@@ -157,30 +168,25 @@ SCRIPT;
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
* @return void
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function release()
|
||||
public function destroy(): void
|
||||
{
|
||||
$this->pool->clean($this->get_config()['host']);
|
||||
$pool = $this->container->get(Pool::class);
|
||||
$pool->clean($this->host);
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁连接池
|
||||
* @throws ConfigException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
$this->pool->clean($this->get_config()['host']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
* @throws ConfigException
|
||||
* @throws Exception
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function proxy($name, $arguments): mixed
|
||||
{
|
||||
@@ -190,7 +196,8 @@ SCRIPT;
|
||||
} catch (\Throwable $throwable) {
|
||||
$response = $this->logger->addError($throwable->getMessage());
|
||||
} finally {
|
||||
$this->pool->push($this->get_config()['host'], $client);
|
||||
$pool = $this->container->get(Pool::class);
|
||||
$pool->push($this->host, $client);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
@@ -199,11 +206,13 @@ SCRIPT;
|
||||
/**
|
||||
* @return \Redis
|
||||
* @throws ConfigException
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
private function getClient(): \Redis
|
||||
{
|
||||
$config = $this->get_config();
|
||||
return $this->pool->get($config['host']);
|
||||
$pool = $this->container->get(Pool::class);
|
||||
return $pool->get($this->host);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +221,16 @@ SCRIPT;
|
||||
*/
|
||||
public function get_config(): array
|
||||
{
|
||||
return Config::get('cache.redis', null, true);
|
||||
return [
|
||||
'host' => $this->host,
|
||||
'port' => $this->port,
|
||||
'prefix' => $this->prefix,
|
||||
'auth' => $this->auth,
|
||||
'databases' => $this->databases,
|
||||
'timeout' => $this->timeout,
|
||||
'read_timeout' => $this->read_timeout,
|
||||
'pool' => $this->pool
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Kiri;
|
||||
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Component;
|
||||
use Kiri\Di\Container;
|
||||
use ReflectionException;
|
||||
|
||||
class Scanner extends Component
|
||||
{
|
||||
|
||||
|
||||
private array $files = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function read(string $path): void
|
||||
{
|
||||
$this->load_dir($path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @return void
|
||||
* @throws ReflectionException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function parse(string $namespace): void
|
||||
{
|
||||
$container = Container::instance();
|
||||
foreach ($this->files as $file) {
|
||||
$class = $namespace . '\\' . $this->rename($file);
|
||||
if (!file_exists($class)) {
|
||||
throw new Exception('Please follow the PSR-4 specification to write code.' . $class);
|
||||
}
|
||||
$container->parse($class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return string
|
||||
*/
|
||||
private function rename(string $file): string
|
||||
{
|
||||
$filter = array_filter(explode('/', $file), function ($value) {
|
||||
if (empty($value)) {
|
||||
return false;
|
||||
}
|
||||
return ucfirst($value);
|
||||
});
|
||||
array_shift($filter);
|
||||
return implode('\\', $filter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
private function load_dir(string $path): void
|
||||
{
|
||||
$dir = new \DirectoryIterator($path);
|
||||
foreach ($dir as $value) {
|
||||
if ($value->isDot()) {
|
||||
continue;
|
||||
}
|
||||
if (is_dir($value)) {
|
||||
$this->load_dir($value->getRealPath());
|
||||
} else if ($value->getExtension() == '.php') {
|
||||
$this->load_file($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
private function load_file(string $path): void
|
||||
{
|
||||
try {
|
||||
require_once "$path";
|
||||
$path = str_replace($_SERVER['HOME'], '', $path);
|
||||
$path = str_replace('.php', '', $path);
|
||||
$this->files[] = $path;
|
||||
} catch (\Throwable $throwable) {
|
||||
error($throwable->getMessage(), [$throwable]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user