diff --git a/Database/ActiveQuery.php b/Database/ActiveQuery.php
index 4c911fcd..7c3ecfee 100644
--- a/Database/ActiveQuery.php
+++ b/Database/ActiveQuery.php
@@ -12,7 +12,6 @@ namespace Database;
use Database\Traits\QueryTrait;
use Exception;
use Snowflake\Abstracts\Component;
-use Snowflake\Snowflake;
/**
* Class ActiveQuery
@@ -107,22 +106,12 @@ class ActiveQuery extends Component implements ISqlBuilder
if (is_string($name)) {
$name = explode(',', $name);
}
- foreach ($name as $key => $val) {
+ foreach ($name as $val) {
array_push($this->with, $val);
}
return $this;
}
- /**
- * @param bool $isArray
- * @return $this
- */
- public function asArray(bool $isArray = TRUE): static
- {
- $this->asArray = $isArray;
- return $this;
- }
-
/**
* @param $sql
@@ -137,20 +126,16 @@ class ActiveQuery extends Component implements ISqlBuilder
/**
- * @return ActiveRecord|array|null
+ * @return ActiveRecord|null
* @throws Exception
*/
- public function first(): ActiveRecord|array|null
+ public function first(): ActiveRecord|null
{
$data = $this->execute($this->builder->one())->one();
if (empty($data)) {
return NULL;
}
- $newModel = $this->modelClass::populate($data);
- if ($this->asArray) {
- return $newModel->toArray();
- }
- return $newModel;
+ return $this->modelClass::populate($data);
}
diff --git a/Database/Base/BaseActiveRecord.php b/Database/Base/BaseActiveRecord.php
index 04bc17bd..724c7913 100644
--- a/Database/Base/BaseActiveRecord.php
+++ b/Database/Base/BaseActiveRecord.php
@@ -43,7 +43,7 @@ use validator\Validator;
* @property bool $isCreate
* @method rules()
* @method static tableName()
- * @property Application $application
+ * @property Application $container
*/
abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
{
@@ -106,7 +106,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
/**
* @return Application
*/
- #[Pure] private function getApplication(): Application
+ #[Pure] private function getContainer(): Application
{
return Snowflake::app();
}
@@ -322,14 +322,30 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
/**
* @return ActiveQuery
- * @throws ReflectionException
- * @throws NotFindClassException
*/
public static function find(): ActiveQuery
{
- return Snowflake::createObject(ActiveQuery::class, [static::class]);
+ return new ActiveQuery(get_called_class());
}
+ /**
+ * @return ActiveQuery
+ */
+ public static function query(): ActiveQuery
+ {
+ return new ActiveQuery(get_called_class());
+ }
+
+
+ /**
+ * @throws ConfigException
+ */
+ protected function getConnection()
+ {
+ return Config::get('connections.' . static::$ab_name, null, true);
+ }
+
+
/**
* @param null $condition
* @param array $attributes
@@ -710,7 +726,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
* @return bool
* @throws Exception
*/
- #[Event(ActiveRecord::AFTER_SAVE)]
+ #[Event(self::AFTER_SAVE)]
public function afterSave($attributes, $changeAttributes): bool
{
return true;
diff --git a/HttpServer/Controller.php b/HttpServer/Controller.php
index e28e0126..21eb95dd 100644
--- a/HttpServer/Controller.php
+++ b/HttpServer/Controller.php
@@ -10,6 +10,7 @@ use HttpServer\Http\HttpParams;
use HttpServer\Http\Request;
use HttpServer\Http\Response;
use Snowflake\Abstracts\TraitApplication;
+use Snowflake\Application;
/**
* Class WebController
@@ -18,39 +19,48 @@ use Snowflake\Abstracts\TraitApplication;
class Controller
{
- use TraitApplication;
+ use TraitApplication;
- /**
- * inject request
- *
- * @var Request|null
- */
- #[Inject('request')]
- public ?Request $request = null;
+ /**
+ * @param Application $container
+ */
+ public function __construct(protected Application $container)
+ {
+
+ }
- /**
- * @var HttpParams|null
- */
- #[Inject('input')]
- public ?HttpParams $input = null;
+ /**
+ * inject request
+ *
+ * @var Request|null
+ */
+ #[Inject('request')]
+ public ?Request $request = null;
- /**
- * @var HttpHeaders|null
- */
- #[Inject('header')]
- public ?HttpHeaders $header = null;
+ /**
+ * @var HttpParams|null
+ */
+ #[Inject('input')]
+ public ?HttpParams $input = null;
- /**
- * inject response
- *
- * @var Response|null
- */
- #[Inject('response')]
- public ?Response $response = null;
+ /**
+ * @var HttpHeaders|null
+ */
+ #[Inject('header')]
+ public ?HttpHeaders $header = null;
+
+
+ /**
+ * inject response
+ *
+ * @var Response|null
+ */
+ #[Inject('response')]
+ public ?Response $response = null;
}
diff --git a/HttpServer/Route/Router.php b/HttpServer/Route/Router.php
index cb162c2d..2a9e6860 100644
--- a/HttpServer/Route/Router.php
+++ b/HttpServer/Route/Router.php
@@ -28,656 +28,656 @@ defined('ROUTER_HASH') or define('ROUTER_HASH', 2);
*/
class Router extends HttpService implements RouterInterface
{
- /** @var Node[] $nodes */
- public static array $nodes = [];
- public array $groupTacks = [];
- public ?string $dir = 'App\\Http\\Controllers';
-
- const NOT_FOUND = 'Page not found or method not allowed.';
-
- /** @var string[] */
- public array $methods = ['GET', 'POST', 'OPTIONS', 'PUT', 'DELETE', 'RECEIVE', 'HEAD'];
-
-
- public ?Closure $middleware = null;
-
- public int $useTree = ROUTER_TREE;
-
-
- private static array $controllers = [];
-
-
- public ?Response $response = null;
-
-
- /**
- * @param Closure $middleware
- */
- public function setMiddleware(\Closure $middleware): void
- {
- $this->middleware = $middleware;
- }
-
-
- /**
- * @throws ConfigException
- * @throws Exception
- * 初始化函数路径
- */
- public function init()
- {
- $this->dir = Config::get('http.namespace', $this->dir);
-
- $this->response = Snowflake::app()->get('response');
- }
-
-
- /**
- * @param bool $useTree
- */
- public function setUseTree(bool $useTree): void
- {
- $this->useTree = $useTree ? ROUTER_TREE : ROUTER_HASH;
- }
-
-
- /**
- * @param $port
- * @param Closure|array|string $closure
- * @param null $method
- * @return Node|bool|null
- * @throws
- */
- public function addPortListen($port, Closure|array|string $closure, $method = null): Node|null|bool
- {
- if (!is_string($closure)) {
- return $this->addRoute('add-port-listen/port_' . $port, $closure, 'listen');
- }
- if (empty($method)) {
- return $this->addError($closure . '::' . $method);
- }
- $_closure = Snowflake::createObject($closure);
- if (!method_exists($_closure, $method)) {
- return $this->addError($closure . '::' . $method);
- }
- return $this->addRoute('add-port-listen/port_' . $port, [$_closure, $method], 'listen');
- }
-
-
- /**
- * @param $path
- * @param $handler
- * @param string $method
- * @return ?Node
- * @throws Exception
- */
- public function addRoute($path, $handler, string $method = 'any'): ?Node
- {
- if (!isset(static::$nodes[$method])) {
- static::$nodes[$method] = [];
- }
- if ($handler instanceof Closure) {
- $handler = Closure::bind($handler, di(Controller::class));
- }
- return $this->hash($path, $handler, $method);
- }
-
-
- /**
- * @param $path
- * @param $handler
- * @param string $method
- * @return ?Node
- */
- private function hash($path, $handler, string $method = 'any'): ?Node
- {
- $path = $this->resolve($path);
- static::$nodes[$method][$path] = $this->NodeInstance($path, 0, $method);
-
- return static::$nodes[$method][$path]->bindHandler($handler);
- }
-
-
- /**
- * @param $path
- * @return string
- */
- #[Pure] private function resolve($path): string
- {
- $paths = array_column($this->groupTacks, 'prefix');
- if (empty($paths)) {
- return '/' . ltrim($path, '/');
- }
- $paths = '/' . implode('/', $paths);
- if ($path != '/') {
- return $paths . '/' . ltrim($path, '/');
- }
- return $paths . '/';
- }
-
-
- /**
- * @param $path
- * @param $handler
- * @param string $method
- * @return Node
- * @throws Exception
- */
- private function tree($path, $handler, string $method = 'any'): Node
- {
- list($first, $explode) = $this->split($path);
-
- $parent = static::$nodes[$method][$first] ?? null;
- if (empty($parent)) {
- static::$nodes[$method][$first] = $parent = $this->NodeInstance('/', 0, $method);
- }
-
- if ($first !== '/') {
- $parent = $this->bindNode($parent, $explode, $method);
- }
- $parent->path = $path;
- return $parent->bindHandler($handler);
- }
-
-
- /**
- * @param Node $parent
- * @param array $explode
- * @param $method
- * @return Node
- * @throws Exception
- */
- private function bindNode(Node $parent, array $explode, $method): Node
- {
- $a = 0;
- if (empty($explode)) {
- return $parent->addChild($this->NodeInstance('/', $a, $method), '/');
- }
- foreach ($explode as $value) {
- if (empty($value)) {
- continue;
- }
- ++$a;
-
- $search = $parent->findNode($value);
- if ($search === null) {
- $parent = $parent->addChild($this->NodeInstance($value, $a, $method), $value);
- } else {
- $parent = $search;
- }
- }
- return $parent;
- }
-
- /**
- * @param $route
- * @param $handler
- * @return Node|null
- * @throws
- */
- public function socket($route, $handler): ?Node
- {
- return $this->addRoute($route, $handler, 'socket');
- }
-
-
- /**
- * @param $route
- * @param $handler
- * @return Node|null
- * @throws
- */
- public function post($route, $handler): ?Node
- {
- return $this->addRoute($route, $handler, 'POST');
- }
-
- /**
- * @param $route
- * @param $handler
- * @return Node|null
- * @throws
- */
- public function get($route, $handler): ?Node
- {
- return $this->addRoute($route, $handler, 'GET');
- }
-
-
- /**
- * @param $port
- * @param callable $callback
- * @return mixed
- * @throws Exception
- */
- public function addRpcService($port, callable $callback): mixed
- {
- return call_user_func($callback, new Actuator($port));
- }
-
-
- /**
- * @param $route
- * @param $handler
- * @return Node|null
- * @throws
- */
- public function options($route, $handler): ?Node
- {
- return $this->addRoute($route, $handler, 'OPTIONS');
- }
-
-
- /**
- * @param $route
- * @param $handler
- * @return Any
- * @throws
- */
- public function any($route, $handler): Any
- {
- $nodes = [];
- foreach (['GET', 'POST', 'OPTIONS', 'PUT', 'DELETE', 'HEAD'] as $method) {
- $nodes[] = $this->addRoute($route, $handler, $method);
- }
- return new Any($nodes);
- }
-
- /**
- * @param $route
- * @param $handler
- * @return Node|null
- * @throws
- */
- public function delete($route, $handler): ?Node
- {
- return $this->addRoute($route, $handler, 'DELETE');
- }
-
-
- /**
- * @param $route
- * @param $handler
- * @return Node|null
- * @throws Exception
- */
- public function head($route, $handler): ?Node
- {
- return $this->addRoute($route, $handler, 'HEAD');
- }
-
-
- /**
- * @param $route
- * @param $handler
- * @return Node|null
- * @throws
- */
- public function put($route, $handler): ?Node
- {
- return $this->addRoute($route, $handler, 'PUT');
- }
-
- /**
- * @param $value
- * @param int $index
- * @param string $method
- * @return Node
- * @throws
- */
- public function NodeInstance($value, int $index = 0, string $method = 'GET'): Node
- {
- $node = new Node();
- $node->childes = [];
- $node->path = $value;
- $node->index = $index;
- $node->method = $method;
- $node->namespace = $this->loadNamespace($method);
-
- $name = array_column($this->groupTacks, 'middleware');
- if ($this->middleware instanceof \Closure) {
- $node->addMiddleware([$this->middleware]);
- }
- if (is_array($name)) {
- $node->addMiddleware($this->resolve_middleware($name));
- }
- return $node;
- }
-
-
- /**
- * @param string|array $middleware
- * @return array
- * @throws NotFindClassException
- * @throws ReflectionException
- */
- private function resolve_middleware(string|array $middleware): array
- {
- if (is_string($middleware)) {
- $middleware = [$middleware];
- }
-
- $array = [];
- foreach ($middleware as $value) {
- if (is_array($value)) {
- foreach ($value as $item) {
- $array[] = $this->getMiddlewareInstance($item);
- }
- } else {
- $array[] = $this->getMiddlewareInstance($value);
- }
- }
- return array_filter($array);
- }
-
-
- /**
- * @param $value
- * @return Closure|array|null
- * @throws NotFindClassException
- * @throws ReflectionException
- */
- private function getMiddlewareInstance($value): null|Closure|array
- {
- if (!is_string($value)) {
- return $value;
- }
- $value = Snowflake::createObject($value);
- if (!($value instanceof Middleware)) {
- return null;
- }
- return [$value, 'onHandler'];
- }
-
-
- /**
- * @param $method
- * @return array
- */
- private function loadNamespace($method): array
- {
- $name = array_column($this->groupTacks, 'namespace');
- if ($method == 'package' || $method == 'RECEIVE') {
- $dir = 'App\\Listener';
- } else {
- $dir = $this->dir;
- }
- array_unshift($name, $dir);
- return array_filter($name);
- }
-
- /**
- * @param array $config
- * @param callable $callback
- * 路由分组
- * @param null $stdClass
- */
- public function group(array $config, callable $callback, $stdClass = null)
- {
- $this->groupTacks[] = $config;
- if ($stdClass) {
- $callback($stdClass);
- } else {
- $callback($this);
- }
- array_pop($this->groupTacks);
- }
-
- /**
- * @return string
- */
- public function addPrefix(): string
- {
- $prefix = array_column($this->groupTacks, 'prefix');
-
- $prefix = array_filter($prefix);
-
- if (empty($prefix)) {
- return '';
- }
-
- return '/' . implode('/', $prefix);
- }
-
- /**
- * @param array|null $explode
- * @param $method
- * @return Node|null
- * 查找指定路由
- */
- public function tree_search(?array $explode, $method): ?Node
- {
- if (empty($explode)) {
- return static::$nodes[$method]['/'] ?? null;
- }
- $first = array_shift($explode);
- if (!($parent = static::$nodes[$method][$first] ?? null)) {
- return null;
- }
- if (empty($explode)) {
- return $parent->findNode('/');
- }
- while ($value = array_shift($explode)) {
- $node = $parent->findNode($value);
- if (!$node) {
- break;
- }
- $parent = $node;
- }
- return $parent;
- }
-
- /**
- * @param $path
- * @return array
- * '*'
- */
- public function split($path): array
- {
- $prefix = $this->addPrefix();
- $path = ltrim($path, '/');
- if (!empty($prefix)) {
- $path = $prefix . '/' . $path;
- }
-
- $explode = array_filter(explode('/', $path));
- if (empty($explode)) {
- return ['/', []];
- }
-
- $first = array_shift($explode);
- if (empty($explode)) {
- $explode = [];
- }
- return [$first, $explode];
- }
-
- /**
- * @return array
- */
- public function each(): array
- {
- $paths = [];
- foreach (static::$nodes as $node) {
- /** @var Node[] $node */
- foreach ($node as $path => $_node) {
- $paths[] = strtoupper($_node->method) . ' : ' . $path;
- }
- }
- return $paths;
- }
-
-
- /**
- * @return mixed
- * @throws
- */
- public function dispatch(Request $request): void
- {
- $node = $this->find_path($request);
- if (!($node instanceof Node)) {
- $this->response->setFormat(Response::HTML);
- $this->response->send('
404
');
- } else {
- $this->response->send($node->dispatch(), 200);
- }
- }
+ /** @var Node[] $nodes */
+ public static array $nodes = [];
+ public array $groupTacks = [];
+ public ?string $dir = 'App\\Http\\Controllers';
+
+ const NOT_FOUND = 'Page not found or method not allowed.';
+
+ /** @var string[] */
+ public array $methods = ['GET', 'POST', 'OPTIONS', 'PUT', 'DELETE', 'RECEIVE', 'HEAD'];
+
+
+ public ?Closure $middleware = null;
+
+ public int $useTree = ROUTER_TREE;
+
+
+ private static array $controllers = [];
+
+
+ public ?Response $response = null;
+
+
+ /**
+ * @param Closure $middleware
+ */
+ public function setMiddleware(\Closure $middleware): void
+ {
+ $this->middleware = $middleware;
+ }
+
+
+ /**
+ * @throws ConfigException
+ * @throws Exception
+ * 初始化函数路径
+ */
+ public function init()
+ {
+ $this->dir = Config::get('http.namespace', $this->dir);
+
+ $this->response = Snowflake::app()->get('response');
+ }
+
+
+ /**
+ * @param bool $useTree
+ */
+ public function setUseTree(bool $useTree): void
+ {
+ $this->useTree = $useTree ? ROUTER_TREE : ROUTER_HASH;
+ }
+
+
+ /**
+ * @param $port
+ * @param Closure|array|string $closure
+ * @param null $method
+ * @return Node|bool|null
+ * @throws
+ */
+ public function addPortListen($port, Closure|array|string $closure, $method = null): Node|null|bool
+ {
+ if (!is_string($closure)) {
+ return $this->addRoute('add-port-listen/port_' . $port, $closure, 'listen');
+ }
+ if (empty($method)) {
+ return $this->addError($closure . '::' . $method);
+ }
+ $_closure = Snowflake::createObject($closure);
+ if (!method_exists($_closure, $method)) {
+ return $this->addError($closure . '::' . $method);
+ }
+ return $this->addRoute('add-port-listen/port_' . $port, [$_closure, $method], 'listen');
+ }
+
+
+ /**
+ * @param $path
+ * @param $handler
+ * @param string $method
+ * @return ?Node
+ * @throws Exception
+ */
+ public function addRoute($path, $handler, string $method = 'any'): ?Node
+ {
+ if (!isset(static::$nodes[$method])) {
+ static::$nodes[$method] = [];
+ }
+ if ($handler instanceof Closure) {
+ $handler = Closure::bind($handler, di(Controller::class));
+ }
+ return $this->hash($path, $handler, $method);
+ }
+
+
+ /**
+ * @param $path
+ * @param $handler
+ * @param string $method
+ * @return ?Node
+ */
+ private function hash($path, $handler, string $method = 'any'): ?Node
+ {
+ $path = $this->resolve($path);
+ static::$nodes[$method][$path] = $this->NodeInstance($path, 0, $method);
+
+ return static::$nodes[$method][$path]->bindHandler($handler);
+ }
+
+
+ /**
+ * @param $path
+ * @return string
+ */
+ #[Pure] private function resolve($path): string
+ {
+ $paths = array_column($this->groupTacks, 'prefix');
+ if (empty($paths)) {
+ return '/' . ltrim($path, '/');
+ }
+ $paths = '/' . implode('/', $paths);
+ if ($path != '/') {
+ return $paths . '/' . ltrim($path, '/');
+ }
+ return $paths . '/';
+ }
+
+
+ /**
+ * @param $path
+ * @param $handler
+ * @param string $method
+ * @return Node
+ * @throws Exception
+ */
+ private function tree($path, $handler, string $method = 'any'): Node
+ {
+ list($first, $explode) = $this->split($path);
+
+ $parent = static::$nodes[$method][$first] ?? null;
+ if (empty($parent)) {
+ static::$nodes[$method][$first] = $parent = $this->NodeInstance('/', 0, $method);
+ }
+
+ if ($first !== '/') {
+ $parent = $this->bindNode($parent, $explode, $method);
+ }
+ $parent->path = $path;
+ return $parent->bindHandler($handler);
+ }
+
+
+ /**
+ * @param Node $parent
+ * @param array $explode
+ * @param $method
+ * @return Node
+ * @throws Exception
+ */
+ private function bindNode(Node $parent, array $explode, $method): Node
+ {
+ $a = 0;
+ if (empty($explode)) {
+ return $parent->addChild($this->NodeInstance('/', $a, $method), '/');
+ }
+ foreach ($explode as $value) {
+ if (empty($value)) {
+ continue;
+ }
+ ++$a;
+
+ $search = $parent->findNode($value);
+ if ($search === null) {
+ $parent = $parent->addChild($this->NodeInstance($value, $a, $method), $value);
+ } else {
+ $parent = $search;
+ }
+ }
+ return $parent;
+ }
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Node|null
+ * @throws
+ */
+ public function socket($route, $handler): ?Node
+ {
+ return $this->addRoute($route, $handler, 'socket');
+ }
+
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Node|null
+ * @throws
+ */
+ public function post($route, $handler): ?Node
+ {
+ return $this->addRoute($route, $handler, 'POST');
+ }
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Node|null
+ * @throws
+ */
+ public function get($route, $handler): ?Node
+ {
+ return $this->addRoute($route, $handler, 'GET');
+ }
+
+
+ /**
+ * @param $port
+ * @param callable $callback
+ * @return mixed
+ * @throws Exception
+ */
+ public function addRpcService($port, callable $callback): mixed
+ {
+ return call_user_func($callback, new Actuator($port));
+ }
+
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Node|null
+ * @throws
+ */
+ public function options($route, $handler): ?Node
+ {
+ return $this->addRoute($route, $handler, 'OPTIONS');
+ }
+
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Any
+ * @throws
+ */
+ public function any($route, $handler): Any
+ {
+ $nodes = [];
+ foreach (['GET', 'POST', 'OPTIONS', 'PUT', 'DELETE', 'HEAD'] as $method) {
+ $nodes[] = $this->addRoute($route, $handler, $method);
+ }
+ return new Any($nodes);
+ }
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Node|null
+ * @throws
+ */
+ public function delete($route, $handler): ?Node
+ {
+ return $this->addRoute($route, $handler, 'DELETE');
+ }
+
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Node|null
+ * @throws Exception
+ */
+ public function head($route, $handler): ?Node
+ {
+ return $this->addRoute($route, $handler, 'HEAD');
+ }
+
+
+ /**
+ * @param $route
+ * @param $handler
+ * @return Node|null
+ * @throws
+ */
+ public function put($route, $handler): ?Node
+ {
+ return $this->addRoute($route, $handler, 'PUT');
+ }
+
+ /**
+ * @param $value
+ * @param int $index
+ * @param string $method
+ * @return Node
+ * @throws
+ */
+ public function NodeInstance($value, int $index = 0, string $method = 'GET'): Node
+ {
+ $node = new Node();
+ $node->childes = [];
+ $node->path = $value;
+ $node->index = $index;
+ $node->method = $method;
+ $node->namespace = $this->loadNamespace($method);
+
+ $name = array_column($this->groupTacks, 'middleware');
+ if ($this->middleware instanceof \Closure) {
+ $node->addMiddleware([$this->middleware]);
+ }
+ if (is_array($name)) {
+ $node->addMiddleware($this->resolve_middleware($name));
+ }
+ return $node;
+ }
+
+
+ /**
+ * @param string|array $middleware
+ * @return array
+ * @throws NotFindClassException
+ * @throws ReflectionException
+ */
+ private function resolve_middleware(string|array $middleware): array
+ {
+ if (is_string($middleware)) {
+ $middleware = [$middleware];
+ }
+
+ $array = [];
+ foreach ($middleware as $value) {
+ if (is_array($value)) {
+ foreach ($value as $item) {
+ $array[] = $this->getMiddlewareInstance($item);
+ }
+ } else {
+ $array[] = $this->getMiddlewareInstance($value);
+ }
+ }
+ return array_filter($array);
+ }
+
+
+ /**
+ * @param $value
+ * @return Closure|array|null
+ * @throws NotFindClassException
+ * @throws ReflectionException
+ */
+ private function getMiddlewareInstance($value): null|Closure|array
+ {
+ if (!is_string($value)) {
+ return $value;
+ }
+ $value = Snowflake::createObject($value);
+ if (!($value instanceof Middleware)) {
+ return null;
+ }
+ return [$value, 'onHandler'];
+ }
+
+
+ /**
+ * @param $method
+ * @return array
+ */
+ private function loadNamespace($method): array
+ {
+ $name = array_column($this->groupTacks, 'namespace');
+ if ($method == 'package' || $method == 'RECEIVE') {
+ $dir = 'App\\Listener';
+ } else {
+ $dir = $this->dir;
+ }
+ array_unshift($name, $dir);
+ return array_filter($name);
+ }
+
+ /**
+ * @param array $config
+ * @param callable $callback
+ * 路由分组
+ * @param null $stdClass
+ */
+ public function group(array $config, callable $callback, $stdClass = null)
+ {
+ $this->groupTacks[] = $config;
+ if ($stdClass) {
+ $callback($stdClass);
+ } else {
+ $callback($this);
+ }
+ array_pop($this->groupTacks);
+ }
+
+ /**
+ * @return string
+ */
+ public function addPrefix(): string
+ {
+ $prefix = array_column($this->groupTacks, 'prefix');
+
+ $prefix = array_filter($prefix);
+
+ if (empty($prefix)) {
+ return '';
+ }
+
+ return '/' . implode('/', $prefix);
+ }
+
+ /**
+ * @param array|null $explode
+ * @param $method
+ * @return Node|null
+ * 查找指定路由
+ */
+ public function tree_search(?array $explode, $method): ?Node
+ {
+ if (empty($explode)) {
+ return static::$nodes[$method]['/'] ?? null;
+ }
+ $first = array_shift($explode);
+ if (!($parent = static::$nodes[$method][$first] ?? null)) {
+ return null;
+ }
+ if (empty($explode)) {
+ return $parent->findNode('/');
+ }
+ while ($value = array_shift($explode)) {
+ $node = $parent->findNode($value);
+ if (!$node) {
+ break;
+ }
+ $parent = $node;
+ }
+ return $parent;
+ }
+
+ /**
+ * @param $path
+ * @return array
+ * '*'
+ */
+ public function split($path): array
+ {
+ $prefix = $this->addPrefix();
+ $path = ltrim($path, '/');
+ if (!empty($prefix)) {
+ $path = $prefix . '/' . $path;
+ }
+
+ $explode = array_filter(explode('/', $path));
+ if (empty($explode)) {
+ return ['/', []];
+ }
+
+ $first = array_shift($explode);
+ if (empty($explode)) {
+ $explode = [];
+ }
+ return [$first, $explode];
+ }
+
+ /**
+ * @return array
+ */
+ public function each(): array
+ {
+ $paths = [];
+ foreach (static::$nodes as $node) {
+ /** @var Node[] $node */
+ foreach ($node as $path => $_node) {
+ $paths[] = strtoupper($_node->method) . ' : ' . $path;
+ }
+ }
+ return $paths;
+ }
+
+
+ /**
+ * @return mixed
+ * @throws
+ */
+ public function dispatch(Request $request): void
+ {
+ $node = $this->find_path($request);
+ if (!($node instanceof Node)) {
+ $this->response->setFormat(Response::HTML);
+ $this->response->send('404
');
+ } else {
+ $this->response->send($node->dispatch(), 200);
+ }
+ }
/**
* @throws Exception
*/
- public function pageNotFound()
- {
- $this->response->setFormat(Response::HTML);
- $this->response->send('404
');
- }
+ public function pageNotFound()
+ {
+ $this->response->setFormat(Response::HTML);
+ $this->response->send('404
');
+ }
- /**
- * @param $exception
- * @return mixed
- * @throws Exception
- */
- public function exception($exception): mixed
- {
- return Snowflake::app()->getLogger()->exception($exception);
- }
+ /**
+ * @param $exception
+ * @return mixed
+ * @throws Exception
+ */
+ public function exception($exception): mixed
+ {
+ return Snowflake::app()->getLogger()->exception($exception);
+ }
- /**
- * @param Request $request
- * @return Node|null 树干搜索
- * 树干搜索
- */
- public function find_path(Request $request): ?Node
- {
- $method = $request->getMethod();
- $uri = $request->headers->get('request_uri', '/');
+ /**
+ * @param Request $request
+ * @return Node|null 树干搜索
+ * 树干搜索
+ */
+ public function find_path(Request $request): ?Node
+ {
+ $method = $request->getMethod();
+ $uri = $request->headers->get('request_uri', '/');
- $methods = static::$nodes[$method][$uri] ?? null;
- if (!is_null($methods)) {
- return $methods;
- }
- if ($request->isOption) {
- return static::$nodes[$method]['*'] ?? null;
- }
- return null;
- }
+ $methods = static::$nodes[$method][$uri] ?? null;
+ if (!is_null($methods)) {
+ return $methods;
+ }
+ if ($request->isOption) {
+ return static::$nodes[$method]['*'] ?? null;
+ }
+ return null;
+ }
- /**
- * @param $uri
- * @param $method
- * @return Node|null
- */
- public function search($uri, $method): Node|null
- {
- if (!isset(static::$nodes[$method])) {
- return null;
- }
- $methods = static::$nodes[$method];
- if (isset($methods[$uri])) {
- return $methods[$uri];
- }
- return $methods['/'] ?? null;
- }
+ /**
+ * @param $uri
+ * @param $method
+ * @return Node|null
+ */
+ public function search($uri, $method): Node|null
+ {
+ if (!isset(static::$nodes[$method])) {
+ return null;
+ }
+ $methods = static::$nodes[$method];
+ if (isset($methods[$uri])) {
+ return $methods[$uri];
+ }
+ return $methods['/'] ?? null;
+ }
- /**
- * @param $request
- * @return Node|null
- */
- private function search_options($request): ?Node
- {
- $method = $request->getMethod();
- if (!isset(static::$nodes[$method])) {
- return null;
- }
- if (!isset(static::$nodes[$method]['*'])) {
- return null;
- }
- return static::$nodes[$method]['*'];
- }
+ /**
+ * @param $request
+ * @return Node|null
+ */
+ private function search_options($request): ?Node
+ {
+ $method = $request->getMethod();
+ if (!isset(static::$nodes[$method])) {
+ return null;
+ }
+ if (!isset(static::$nodes[$method]['*'])) {
+ return null;
+ }
+ return static::$nodes[$method]['*'];
+ }
- /**
- * @param Request $request
- * @return Node|null
- * 树杈搜索
- */
- private function Branch_search(Request $request): ?Node
- {
- $node = $this->tree_search($request->getExplode(), $request->getMethod());
- if ($node instanceof Node) {
- return $node;
- }
- if (!$request->isOption) {
- return null;
- }
- $node = $this->tree_search(['*'], $request->getMethod());
- if (!($node instanceof Node)) {
- return null;
- }
- return $node;
- }
+ /**
+ * @param Request $request
+ * @return Node|null
+ * 树杈搜索
+ */
+ private function Branch_search(Request $request): ?Node
+ {
+ $node = $this->tree_search($request->getExplode(), $request->getMethod());
+ if ($node instanceof Node) {
+ return $node;
+ }
+ if (!$request->isOption) {
+ return null;
+ }
+ $node = $this->tree_search(['*'], $request->getMethod());
+ if (!($node instanceof Node)) {
+ return null;
+ }
+ return $node;
+ }
- /**
- * @throws
- */
- public function _loader()
- {
- $this->loadRouteDir(APP_PATH . 'routes');
- $classes = Snowflake::getAnnotation()->runtime(CONTROLLER_PATH);
- foreach ($classes as $class) {
- $instance = Snowflake::getDi()->get($class);
- $methods = Snowflake::getDi()->getMethodAttribute($class);
- foreach ($methods as $method => $attribute) {
- if (empty($attribute)) {
- continue;
- }
- foreach ($attribute as $item) {
- $item->execute($instance, $method);
- }
- }
- }
- }
+ /**
+ * @throws
+ */
+ public function _loader()
+ {
+ $this->loadRouteDir(APP_PATH . 'routes');
+ $classes = Snowflake::getAnnotation()->runtime(CONTROLLER_PATH);
+ foreach ($classes as $class) {
+ $instance = Snowflake::getDi()->get($class);
+ $methods = Snowflake::getDi()->getMethodAttribute($class);
+ foreach ($methods as $method => $attribute) {
+ if (empty($attribute)) {
+ continue;
+ }
+ foreach ($attribute as $item) {
+ $item->execute($instance, $method);
+ }
+ }
+ }
+ }
- /**
- * @param $path
- * @throws Exception
- * 加载目录下的路由文件
- */
- private function loadRouteDir($path)
- {
- $files = glob($path . '/*');
- for ($i = 0; $i < count($files); $i++) {
- if (is_dir($files[$i])) {
- $this->loadRouteDir($files[$i]);
- } else {
- $this->loadRouterFile($files[$i]);
- }
- }
- }
+ /**
+ * @param $path
+ * @throws Exception
+ * 加载目录下的路由文件
+ */
+ private function loadRouteDir($path)
+ {
+ $files = glob($path . '/*');
+ for ($i = 0; $i < count($files); $i++) {
+ if (is_dir($files[$i])) {
+ $this->loadRouteDir($files[$i]);
+ } else {
+ $this->loadRouterFile($files[$i]);
+ }
+ }
+ }
- /**
- * @param $files
- * @throws Exception
- */
- private function loadRouterFile($files)
- {
- try {
- $router = $this;
- include_once "{$files}";
- } catch (\Throwable $exception) {
- $this->addError($exception, 'throwable');
- } finally {
- if (isset($exception)) {
- unset($exception);
- }
- }
- }
+ /**
+ * @param $files
+ * @throws Exception
+ */
+ private function loadRouterFile($files)
+ {
+ try {
+ $router = $this;
+ include_once "{$files}";
+ } catch (\Throwable $exception) {
+ $this->addError($exception, 'throwable');
+ } finally {
+ if (isset($exception)) {
+ unset($exception);
+ }
+ }
+ }
}
diff --git a/System/Abstracts/BaseApplication.php b/System/Abstracts/BaseApplication.php
index bc5e9309..e34e6226 100644
--- a/System/Abstracts/BaseApplication.php
+++ b/System/Abstracts/BaseApplication.php
@@ -50,429 +50,431 @@ use Swoole\Table;
abstract class BaseApplication extends Service
{
- use TraitApplication;
-
-
- /**
- * @var string
- */
- public string $storage = APP_PATH . 'storage';
-
- public string $envPath = APP_PATH . '.env';
-
- /**
- * Init constructor.
- *
- * @param array $config
- *
- * @throws
- */
- public function __construct(array $config = [])
- {
- Snowflake::init($this);
-
- $this->moreComponents();
- $this->parseInt($config);
- $this->parseEvents($config);
- $this->initErrorHandler();
- $this->enableEnvConfig();
-
- parent::__construct($config);
- }
-
-
- /**
- * @return array
- */
- public function enableEnvConfig(): array
- {
- if (!file_exists($this->envPath)) {
- return [];
- }
- $lines = $this->readLinesFromFile($this->envPath);
- foreach ($lines as $line) {
- if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
- [$key, $value] = explode('=', $line);
- putenv(trim($key) . '=' . trim($value));
- }
- }
- return $lines;
- }
-
-
- /**
- * Read lines from the file, auto detecting line endings.
- *
- * @param string $filePath
- *
- * @return array
- */
- protected function readLinesFromFile(string $filePath): array
- {
- // Read file into an array of lines with auto-detected line endings
- $autodetect = ini_get('auto_detect_line_endings');
- ini_set('auto_detect_line_endings', '1');
- $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
- ini_set('auto_detect_line_endings', $autodetect);
-
- return $lines;
- }
-
- /**
- * Determine if the line in the file is a comment, e.g. begins with a #.
- *
- * @param string $line
- *
- * @return bool
- */
- protected function isComment(string $line): bool
- {
- $line = ltrim($line);
-
- return isset($line[0]) && $line[0] === '#';
- }
-
- /**
- * Determine if the given line looks like it's setting a variable.
- *
- * @param string $line
- *
- * @return bool
- */
- #[Pure] protected function looksLikeSetter(string $line): bool
- {
- return str_contains($line, '=');
- }
-
-
- /**
- * @param $config
- *
- * @throws
- */
- public function parseInt($config)
- {
- Config::sets($config);
- if ($storage = Config::get('storage', 'storage')) {
- if (!str_contains($storage, APP_PATH)) {
- $storage = APP_PATH . $storage . '/';
- }
- if (!is_dir($storage)) {
- mkdir($storage);
- }
- if (!is_dir($storage) || !is_writeable($storage)) {
- throw new InitException("Directory {$storage} does not have write permission");
- }
- }
- }
-
-
- /**
- * @param $config
- *
- * @throws
- */
- public function parseEvents($config)
- {
- if (!isset($config['events']) || !is_array($config['events'])) {
- return;
- }
- foreach ($config['events'] as $key => $value) {
- if (is_string($value)) {
- $value = Snowflake::createObject($value);
- }
- $this->addEvent($key, $value);
- }
- }
-
-
- /**
- * @param $key
- * @param $value
- * @throws InitException
- * @throws NotFindClassException
- * @throws ReflectionException
- * @throws Exception
- */
- private function addEvent($key, $value): void
- {
- if ($value instanceof \Closure) {
- Event::on($key, $value, [], true);
- return;
- }
- if (is_object($value)) {
- Event::on($key, $value, [], true);
- return;
- }
- if (is_array($value)) {
- if (is_object($value[0]) && !($value[0] instanceof \Closure)) {
- Event::on($key, $value, [], true);
- return;
- }
-
- if (is_string($value[0])) {
- $value[0] = Snowflake::createObject($value[0]);
- Event::on($key, $value, [], true);
- return;
- }
-
- foreach ($value as $item) {
- if (!is_callable($item, true)) {
- throw new InitException("Class does not hav callback.");
- }
- Event::on($key, $item, [], true);
- }
- }
-
- }
-
-
- /**
- * @param $name
- * @return mixed
- * @throws Exception
- */
- public function clone($name): mixed
- {
- return clone $this->get($name);
- }
-
- /**
- *
- * @throws Exception
- */
- public function initErrorHandler()
- {
- $this->get('error')->register();
- }
-
- /**
- * @return mixed
- */
- public function getLocalIps(): mixed
- {
- return swoole_get_local_ip();
- }
-
- /**
- * @return mixed
- */
- public function getFirstLocal(): mixed
- {
- return current($this->getLocalIps());
- }
-
-
- /**
- * @return Logger
- * @throws Exception
- */
- public function getLogger(): Logger
- {
- return $this->get('logger');
- }
-
-
- /**
- * @return Producer
- * @throws Exception
- */
- public function getKafka(): Producer
- {
- return $this->get('kafka');
- }
-
-
- /**
- * @return \Redis|Redis
- * @throws Exception
- */
- public function getRedis(): Redis|\Redis
- {
- return $this->get('redis');
- }
-
- /**
- * @param $ip
- * @return bool
- */
- public function isLocal($ip): bool
- {
- return $this->getFirstLocal() == $ip;
- }
-
-
- /**
- * @return ErrorHandler
- * @throws Exception
- */
- public function getError(): ErrorHandler
- {
- return $this->get('error');
- }
-
-
- /**
- * @return Connection
- * @throws Exception
- */
- public function getMysqlFromPool(): Connection
- {
- return $this->get('connections');
- }
-
-
- /**
- * @return SRedis
- * @throws Exception
- */
- public function getRedisFromPool(): SRedis
- {
- return $this->get('redis_connections');
- }
-
-
- /**
- * @param $name
- * @return Table
- * @throws Exception
- */
- public function getTable($name): Table
- {
- return $this->get($name);
- }
-
-
- /**
- * @return Config
- * @throws Exception
- */
- public function getConfig(): Config
- {
- return $this->get('config');
- }
-
-
- /**
- * @return Router
- * @throws Exception
- */
- public function getRouter(): Router
- {
- return $this->get('router');
- }
-
-
- /**
- * @return Jwt
- * @throws Exception
- */
- public function getJwt(): Jwt
- {
- return $this->get('jwt');
- }
-
-
- /**
- * @return Server
- * @throws Exception
- */
- public function getServer(): Server
- {
- return $this->get('server');
- }
-
-
- /**
- * @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
- */
- public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
- {
- return ServerManager::getContext()->getServer();
- }
-
-
- /**
- * @return SAnnotation
- * @throws Exception
- */
- public function getAnnotation(): SAnnotation
- {
- return $this->get('annotation');
- }
-
-
- /**
- * @return Async
- * @throws Exception
- */
- public function getAsync(): Async
- {
- return $this->get('async');
- }
-
-
- /**
- * @return \Rpc\Producer
- * @throws Exception
- */
- public function getRpc(): \Rpc\Producer
- {
- return $this->get('rpc');
- }
-
-
- /**
- * @return Channel
- * @throws Exception
- */
- public function getChannel(): Channel
- {
- return $this->get('channel');
- }
-
-
- /**
- * @return Pool
- * @throws Exception
- */
- public function getClientsPool(): Pool
- {
- return $this->get('clientsPool');
- }
-
-
- /**
- * @throws Exception
- */
- protected function moreComponents(): void
- {
- $this->setComponents([
- 'error' => ['class' => ErrorHandler::class],
- 'connections' => ['class' => Connection::class],
- 'redis_connections' => ['class' => SRedis::class],
- 'clientsPool' => ['class' => Pool::class],
- 'config' => ['class' => Config::class],
- 'logger' => ['class' => Logger::class],
- 'annotation' => ['class' => SAnnotation::class],
- 'router' => ['class' => Router::class],
- 'event' => ['class' => Event::class],
- 'redis' => ['class' => Redis::class],
- 'aop' => ['class' => Aop::class],
- 'input' => ['class' => HttpParams::class],
- 'header' => ['class' => HttpHeaders::class],
- 'jwt' => ['class' => Jwt::class],
- 'async' => ['class' => Async::class],
- 'kafka-container' => ['class' => TaskContainer::class],
- 'filter' => ['class' => HttpFilter::class],
- 'goto' => ['class' => BaseGoto::class],
- 'response' => ['class' => Response::class],
- 'request' => ['class' => Request::class],
- 'channel' => ['class' => Channel::class],
- 'rpc' => ['class' => \Rpc\Producer::class],
- 'rpc-service' => ['class' => \Rpc\Service::class],
- 'http2' => ['class' => Http2::class],
- 'shutdown' => ['class' => Shutdown::class],
- ]);
- }
+ use TraitApplication;
+
+
+ /**
+ * @var string
+ */
+ public string $storage = APP_PATH . 'storage';
+
+ public string $envPath = APP_PATH . '.env';
+
+ /**
+ * Init constructor.
+ *
+ *
+ * @throws
+ */
+ public function __construct()
+ {
+ Snowflake::init($this);
+
+ $config = sweep(APP_PATH . '/config');
+
+ $this->moreComponents();
+ $this->parseInt($config);
+ $this->parseEvents($config);
+ $this->initErrorHandler();
+ $this->enableEnvConfig();
+
+ parent::__construct();
+ }
+
+
+ /**
+ * @return array
+ */
+ public function enableEnvConfig(): array
+ {
+ if (!file_exists($this->envPath)) {
+ return [];
+ }
+ $lines = $this->readLinesFromFile($this->envPath);
+ foreach ($lines as $line) {
+ if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
+ [$key, $value] = explode('=', $line);
+ putenv(trim($key) . '=' . trim($value));
+ }
+ }
+ return $lines;
+ }
+
+
+ /**
+ * Read lines from the file, auto detecting line endings.
+ *
+ * @param string $filePath
+ *
+ * @return array
+ */
+ protected function readLinesFromFile(string $filePath): array
+ {
+ // Read file into an array of lines with auto-detected line endings
+ $autodetect = ini_get('auto_detect_line_endings');
+ ini_set('auto_detect_line_endings', '1');
+ $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ ini_set('auto_detect_line_endings', $autodetect);
+
+ return $lines;
+ }
+
+ /**
+ * Determine if the line in the file is a comment, e.g. begins with a #.
+ *
+ * @param string $line
+ *
+ * @return bool
+ */
+ protected function isComment(string $line): bool
+ {
+ $line = ltrim($line);
+
+ return isset($line[0]) && $line[0] === '#';
+ }
+
+ /**
+ * Determine if the given line looks like it's setting a variable.
+ *
+ * @param string $line
+ *
+ * @return bool
+ */
+ #[Pure] protected function looksLikeSetter(string $line): bool
+ {
+ return str_contains($line, '=');
+ }
+
+
+ /**
+ * @param $config
+ *
+ * @throws
+ */
+ public function parseInt($config)
+ {
+ Config::sets($config);
+ if ($storage = Config::get('storage', 'storage')) {
+ if (!str_contains($storage, APP_PATH)) {
+ $storage = APP_PATH . $storage . '/';
+ }
+ if (!is_dir($storage)) {
+ mkdir($storage);
+ }
+ if (!is_dir($storage) || !is_writeable($storage)) {
+ throw new InitException("Directory {$storage} does not have write permission");
+ }
+ }
+ }
+
+
+ /**
+ * @param $config
+ *
+ * @throws
+ */
+ public function parseEvents($config)
+ {
+ if (!isset($config['events']) || !is_array($config['events'])) {
+ return;
+ }
+ foreach ($config['events'] as $key => $value) {
+ if (is_string($value)) {
+ $value = Snowflake::createObject($value);
+ }
+ $this->addEvent($key, $value);
+ }
+ }
+
+
+ /**
+ * @param $key
+ * @param $value
+ * @throws InitException
+ * @throws NotFindClassException
+ * @throws ReflectionException
+ * @throws Exception
+ */
+ private function addEvent($key, $value): void
+ {
+ if ($value instanceof \Closure) {
+ Event::on($key, $value, [], true);
+ return;
+ }
+ if (is_object($value)) {
+ Event::on($key, $value, [], true);
+ return;
+ }
+ if (is_array($value)) {
+ if (is_object($value[0]) && !($value[0] instanceof \Closure)) {
+ Event::on($key, $value, [], true);
+ return;
+ }
+
+ if (is_string($value[0])) {
+ $value[0] = Snowflake::createObject($value[0]);
+ Event::on($key, $value, [], true);
+ return;
+ }
+
+ foreach ($value as $item) {
+ if (!is_callable($item, true)) {
+ throw new InitException("Class does not hav callback.");
+ }
+ Event::on($key, $item, [], true);
+ }
+ }
+
+ }
+
+
+ /**
+ * @param $name
+ * @return mixed
+ * @throws Exception
+ */
+ public function clone($name): mixed
+ {
+ return clone $this->get($name);
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public function initErrorHandler()
+ {
+ $this->get('error')->register();
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getLocalIps(): mixed
+ {
+ return swoole_get_local_ip();
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getFirstLocal(): mixed
+ {
+ return current($this->getLocalIps());
+ }
+
+
+ /**
+ * @return Logger
+ * @throws Exception
+ */
+ public function getLogger(): Logger
+ {
+ return $this->get('logger');
+ }
+
+
+ /**
+ * @return Producer
+ * @throws Exception
+ */
+ public function getKafka(): Producer
+ {
+ return $this->get('kafka');
+ }
+
+
+ /**
+ * @return \Redis|Redis
+ * @throws Exception
+ */
+ public function getRedis(): Redis|\Redis
+ {
+ return $this->get('redis');
+ }
+
+ /**
+ * @param $ip
+ * @return bool
+ */
+ public function isLocal($ip): bool
+ {
+ return $this->getFirstLocal() == $ip;
+ }
+
+
+ /**
+ * @return ErrorHandler
+ * @throws Exception
+ */
+ public function getError(): ErrorHandler
+ {
+ return $this->get('error');
+ }
+
+
+ /**
+ * @return Connection
+ * @throws Exception
+ */
+ public function getMysqlFromPool(): Connection
+ {
+ return $this->get('connections');
+ }
+
+
+ /**
+ * @return SRedis
+ * @throws Exception
+ */
+ public function getRedisFromPool(): SRedis
+ {
+ return $this->get('redis_connections');
+ }
+
+
+ /**
+ * @param $name
+ * @return Table
+ * @throws Exception
+ */
+ public function getTable($name): Table
+ {
+ return $this->get($name);
+ }
+
+
+ /**
+ * @return Config
+ * @throws Exception
+ */
+ public function getConfig(): Config
+ {
+ return $this->get('config');
+ }
+
+
+ /**
+ * @return Router
+ * @throws Exception
+ */
+ public function getRouter(): Router
+ {
+ return $this->get('router');
+ }
+
+
+ /**
+ * @return Jwt
+ * @throws Exception
+ */
+ public function getJwt(): Jwt
+ {
+ return $this->get('jwt');
+ }
+
+
+ /**
+ * @return Server
+ * @throws Exception
+ */
+ public function getServer(): Server
+ {
+ return $this->get('server');
+ }
+
+
+ /**
+ * @return \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
+ */
+ public function getSwoole(): \Swoole\Http\Server|\Swoole\Server|\Swoole\WebSocket\Server|null
+ {
+ return ServerManager::getContext()->getServer();
+ }
+
+
+ /**
+ * @return SAnnotation
+ * @throws Exception
+ */
+ public function getAnnotation(): SAnnotation
+ {
+ return $this->get('annotation');
+ }
+
+
+ /**
+ * @return Async
+ * @throws Exception
+ */
+ public function getAsync(): Async
+ {
+ return $this->get('async');
+ }
+
+
+ /**
+ * @return \Rpc\Producer
+ * @throws Exception
+ */
+ public function getRpc(): \Rpc\Producer
+ {
+ return $this->get('rpc');
+ }
+
+
+ /**
+ * @return Channel
+ * @throws Exception
+ */
+ public function getChannel(): Channel
+ {
+ return $this->get('channel');
+ }
+
+
+ /**
+ * @return Pool
+ * @throws Exception
+ */
+ public function getClientsPool(): Pool
+ {
+ return $this->get('clientsPool');
+ }
+
+
+ /**
+ * @throws Exception
+ */
+ protected function moreComponents(): void
+ {
+ $this->setComponents([
+ 'error' => ['class' => ErrorHandler::class],
+ 'connections' => ['class' => Connection::class],
+ 'redis_connections' => ['class' => SRedis::class],
+ 'clientsPool' => ['class' => Pool::class],
+ 'config' => ['class' => Config::class],
+ 'logger' => ['class' => Logger::class],
+ 'annotation' => ['class' => SAnnotation::class],
+ 'router' => ['class' => Router::class],
+ 'event' => ['class' => Event::class],
+ 'redis' => ['class' => Redis::class],
+ 'databases' => ['class' => \Database\Connection::class],
+ 'aop' => ['class' => Aop::class],
+ 'input' => ['class' => HttpParams::class],
+ 'header' => ['class' => HttpHeaders::class],
+ 'jwt' => ['class' => Jwt::class],
+ 'async' => ['class' => Async::class],
+ 'kafka-container' => ['class' => TaskContainer::class],
+ 'filter' => ['class' => HttpFilter::class],
+ 'goto' => ['class' => BaseGoto::class],
+ 'response' => ['class' => Response::class],
+ 'request' => ['class' => Request::class],
+ 'channel' => ['class' => Channel::class],
+ 'rpc' => ['class' => \Rpc\Producer::class],
+ 'rpc-service' => ['class' => \Rpc\Service::class],
+ 'http2' => ['class' => Http2::class],
+ 'shutdown' => ['class' => Shutdown::class],
+ ]);
+ }
}
diff --git a/System/Abstracts/TraitApplication.php b/System/Abstracts/TraitApplication.php
index 79a6ccc6..64ce0301 100644
--- a/System/Abstracts/TraitApplication.php
+++ b/System/Abstracts/TraitApplication.php
@@ -16,15 +16,15 @@ use HttpServer\Route\Router;
use HttpServer\Server;
use HttpServer\Shutdown;
use Kafka\Producer;
+use Rpc\Producer as RPCProducer;
use Snowflake\Async;
use Snowflake\Cache\Redis;
use Snowflake\Channel;
use Snowflake\Error\Logger;
use Snowflake\Event;
use Snowflake\Jwt\Jwt;
-use Snowflake\Pool\Pool;
use Snowflake\Pool\Connection;
-use Rpc\Producer as RPCProducer;
+use Snowflake\Pool\Pool;
/**
* Trait TraitApplication
@@ -45,6 +45,7 @@ use Rpc\Producer as RPCProducer;
* @property BaseGoto $goto
* @property Producer $kafka
* @property Client $client
+ * @property \Database\Connection $databases
* @property Curl $curl
* @property \Snowflake\Crontab\Producer $crontab
* @property HttpFilter $filter
diff --git a/System/Cache/Redis.php b/System/Cache/Redis.php
index bf888b8f..4e3d7d9f 100644
--- a/System/Cache/Redis.php
+++ b/System/Cache/Redis.php
@@ -25,12 +25,7 @@ use Snowflake\Snowflake;
*/
class Redis extends Component
{
- public string $host = '127.0.0.1';
- public string $auth = 'xl.2005113426';
- public int $port = 6973;
- public int $databases = 0;
- public int $timeout = -1;
- public string $prefix = 'idd';
+
/**
* @throws Exception
@@ -54,7 +49,7 @@ class Redis extends Component
$config = $this->get_config();
- $length = (int)env('REDIS.POOL_LENGTH', 100);
+ $length = Config::get('connections.pool.max',10);
$connections->initConnections('Redis:' . $config['host'], true, $length);
}
diff --git a/System/Di/Attributes.php b/System/Di/Attributes.php
new file mode 100644
index 00000000..7290de9a
--- /dev/null
+++ b/System/Di/Attributes.php
@@ -0,0 +1,132 @@
+getName();
+ if (!isset($this->_classTarget[$className])) {
+ $this->_classTarget[$className] = [];
+ }
+ foreach ($class->getAttributes() as $attribute) {
+ if (!class_exists($attribute->getName())) {
+ continue;
+ }
+ $this->_classTarget[$className][] = $attribute->newInstance();
+ }
+ }
+
+
+ /**
+ * @param mixed $class
+ * @return array
+ */
+ public function getTargetNote(mixed $class): array
+ {
+ if (!is_string($class)) {
+ $class = $class::class;
+ }
+ return $this->_classTarget[$class] ?? [];
+ }
+
+
+ /**
+ * @param ReflectionClass $class
+ */
+ protected function setMethodNote(ReflectionClass $class)
+ {
+ $className = $class->getName();
+ $this->_classMethodNote[$className] = $this->_classMethod[$className] = [];
+ foreach ($class->getMethods(ReflectionMethod::IS_FINAL | ReflectionMethod::IS_PRIVATE
+ | ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED | ReflectionMethod::IS_ABSTRACT
+ ) as $ReflectionMethod) {
+ $this->_classMethod[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
+ foreach ($ReflectionMethod->getAttributes() as $attribute) {
+ if (!class_exists($attribute->getName())) {
+ continue;
+ }
+ $this->_classMethodNote[$className][] = $attribute->newInstance();
+ }
+ }
+ }
+
+
+ /**
+ * @param ReflectionClass $class
+ * @return array
+ */
+ #[Pure] public function getMethodNote(ReflectionClass $class): array
+ {
+ return $this->_classMethodNote[$class->getName()] ?? [];
+ }
+
+
+ /**
+ * @param ReflectionClass $class
+ */
+ protected function setPropertyNote(ReflectionClass $class)
+ {
+ $className = $class->getName();
+ $this->_classProperty[$className] = $this->_classPropertyNote[$className] = [];
+ foreach ($class->getProperties(\ReflectionProperty::IS_PRIVATE | \ReflectionProperty::IS_PUBLIC |
+ \ReflectionProperty::IS_PROTECTED) as $ReflectionMethod) {
+ $this->_classProperty[$className][$ReflectionMethod->getName()] = $ReflectionMethod;
+ foreach ($ReflectionMethod->getAttributes() as $attribute) {
+ if (!class_exists($attribute->getName())) {
+ continue;
+ }
+ $this->_classPropertyNote[$className][] = $attribute->newInstance();
+ }
+ }
+ }
+
+
+ /**
+ * @param ReflectionClass $class
+ * @return array
+ */
+ #[Pure] public function getMethods(ReflectionClass $class): array
+ {
+ return $this->_classMethod[$class->getName()] ?? [];
+ }
+
+
+ /**
+ * @param ReflectionClass $class
+ * @return \ReflectionProperty[]
+ */
+ #[Pure] public function getProperty(ReflectionClass $class): array
+ {
+ return $this->_classProperty[$class->getName()] ?? [];
+ }
+
+
+ /**
+ * @param ReflectionClass $class
+ * @return array
+ */
+ #[Pure] public function getPropertyNote(ReflectionClass $class): array
+ {
+ return $this->_classPropertyNote[$class->getName()] ?? [];
+ }
+
+
+}
diff --git a/System/Di/Container.php b/System/Di/Container.php
index 3ce79e1a..7b3dcf8a 100644
--- a/System/Di/Container.php
+++ b/System/Di/Container.php
@@ -10,14 +10,13 @@ declare(strict_types=1);
namespace Snowflake\Di;
use Annotation\Inject;
-use Annotation\Target;
use Exception;
+use JetBrains\PhpStorm\Pure;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use ReflectionProperty;
use Snowflake\Abstracts\BaseObject;
-use Snowflake\Abstracts\Configure;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Snowflake;
@@ -28,63 +27,32 @@ use Snowflake\Snowflake;
class Container extends BaseObject
{
+ use Attributes;
+
/**
* @var array
*
* instance class by className
*/
- private static array $_singletons = [];
+ private array $_singletons = [];
/**
* @var array
*
* class new instance construct parameter
*/
- private static array $_constructs = [];
+ private array $_constructs = [];
/**
* @var array
*
* implements \ReflectClass
*/
- private static array $_reflection = [];
+ private array $_reflection = [];
- /**
- * @var ReflectionProperty[]
- */
- private static array $_reflectionProperty = [];
-
- /**
- * @var ReflectionMethod[]
- */
- private static array $_reflectionMethod = [];
-
- /**
- * @var ReflectionClass[]
- */
- private static array $_reflectionClass = [];
-
-
- /**
- * @var array
- */
- private static array $_propertyAttributes = [];
-
-
- /**
- * @var array
- */
- private static array $_methodsAttributes = [];
-
-
- /**
- * @var array
- */
- private static array $_targetAttributes = [];
-
-
- private static array $_attributeMapping = [];
+ /** @var array */
+ private array $_parameters = [];
/**
@@ -92,7 +60,7 @@ class Container extends BaseObject
*
* The construct parameter
*/
- private static array $_param = [];
+ private array $_param = [];
/**
* @param $class
@@ -106,50 +74,25 @@ class Container extends BaseObject
*/
public function get($class, array $constrict = [], array $config = []): mixed
{
- if (isset(static::$_singletons[$class])) {
- return static::$_singletons[$class];
- } else if (!isset(static::$_constructs[$class])) {
- return $this->resolve($class, $constrict, $config);
- }
- $definition = static::$_constructs[$class];
- if (is_callable($definition, TRUE)) {
- return call_user_func($definition, $this, $constrict, $config);
- } else if (is_array($definition)) {
- return static::$_singletons[$class] = $this->resolveDefinition($definition, $class, $config, $constrict);
- } else if (is_object($definition)) {
- return static::$_singletons[$class] = $definition;
- } else {
- throw new NotFindClassException($class);
+ if (!isset($this->_singletons[$class])) {
+ $this->_singletons[$class] = $this->resolve($class, $constrict, $config);
}
+ return $this->_singletons[$class];
}
/**
- * @param $definition
* @param $class
- * @param $config
- * @param $constrict
- * @return mixed
+ * @param array $constrict
+ * @param array $config
+ * @return object
* @throws NotFindClassException
* @throws ReflectionException
* @throws Exception
*/
- private function resolveDefinition($definition, $class, $config, $constrict): mixed
+ public function newObject($class, array $constrict = [], array $config = []): object
{
- if (!isset($definition['class'])) {
- throw new NotFindClassException($class);
- }
- $_className = $definition['class'];
- unset($definition['class']);
-
- $definition = $this->mergeParam($class, $constrict);
-
- if ($_className === $class) {
- $object = $this->resolve($class, $definition, $config);
- } else {
- $object = $this->get($class, $definition, $config);
- }
- return $object;
+ return $this->resolve($class, $constrict, $config);
}
@@ -163,65 +106,44 @@ class Container extends BaseObject
*/
private function resolve($class, $constrict, $config): object
{
- /** @var ReflectionClass $reflect */
- [$reflect, $dependencies] = $this->resolveDependencies($class, $constrict);
+ $reflect = $this->resolveDependencies($class);
if (empty($reflect) || !$reflect->isInstantiable()) {
throw new NotFindClassException($class);
}
- $object = $this->setConfig($config, $reflect, $dependencies, $class);
- return $this->setClassAnnotation($reflect, $object);
- }
+ $object = $this->setConfig($config, $reflect, $constrict);
-
- /**
- * @param $reflect
- * @param $object
- * @return mixed
- * @throws Exception
- */
- private function setClassAnnotation($reflect, $object): mixed
- {
- static::$_reflectionClass[$reflect->getName()] = [];
- foreach ($reflect->getAttributes() as $attribute) {
- static::$_reflectionClass[$reflect->getName()][] = $attribute->newInstance();
- }
return $this->propertyInject($reflect, $object);
}
-
/**
* @param $config
* @param $reflect
* @param $dependencies
- * @param $class
- * @return mixed
+ * @return object
+ * @throws NotFindClassException
+ * @throws ReflectionException
*/
- private function setConfig($config, $reflect, $dependencies, $class): mixed
+ private function setConfig($config, $reflect, $dependencies): object
{
- if (empty($config) || !is_array($config)) {
- $object = $this->newInstance($reflect, $dependencies);
- } else if (!empty($dependencies) && $reflect->implementsInterface(Configure::class)) {
- $dependencies[count($dependencies) - 1] = $config;
- $object = $this->newInstance($reflect, $dependencies);
- } else {
- static::$_param[$class] = $config;
-
- $object = $this->onAfterInit($this->newInstance($reflect, $dependencies), $config);
- }
- return $object;
+ $object = $this->newInstance($reflect, $dependencies);
+ return $this->onAfterInit($object, $config);
}
/**
- * @param $reflect
+ * @param ReflectionClass $reflect
* @param $dependencies
- * @return mixed
+ * @return object
+ * @throws ReflectionException
+ * @throws NotFindClassException
*/
- private function newInstance($reflect, $dependencies): mixed
+ private function newInstance(ReflectionClass $reflect, $dependencies): object
{
- if (!empty($dependencies)) {
- return $reflect->newInstanceArgs($dependencies);
+ $parameters = $this->getMethodParameters($reflect, '__construct');
+ $parameters = $this->mergeParam($parameters, $dependencies);
+ if (!empty($parameters)) {
+ return $reflect->newInstanceArgs($parameters);
}
return $reflect->newInstance();
}
@@ -235,10 +157,7 @@ class Container extends BaseObject
*/
public function propertyInject(ReflectionClass $reflect, $object): mixed
{
- if (!isset(static::$_propertyAttributes[$reflect->getName()])) {
- return $object;
- }
- foreach (static::$_propertyAttributes[$reflect->getName()] as $property => $inject) {
+ foreach ($this->getPropertyNote($reflect) as $property => $inject) {
/** @var Inject $inject */
$inject->execute($object, $property);
}
@@ -246,102 +165,15 @@ class Container extends BaseObject
}
- /**
- * @param ReflectionClass $class
- */
- private function resolveMethodAttribute(ReflectionClass $class)
- {
- if ($class->isAbstract() || $class->isTrait()) {
- return;
- }
- foreach ($class->getMethods() as $method) {
- if ($method->isStatic()) {
- continue;
- }
- $this->setReflectionMethod($class, $method);
- foreach ($method->getAttributes() as $attribute) {
- if (!class_exists($attribute->getName())) {
- continue;
- }
- $this->setMethodsAttributes($class, $method, $attribute->newInstance());
- }
- }
- }
-
-
- /**
- * @param ReflectionClass $class
- * @param ReflectionMethod $method
- */
- private function setReflectionMethod(ReflectionClass $class, ReflectionMethod $method)
- {
- if (!isset(static::$_attributeMapping[$class->getName()])) {
- static::$_attributeMapping[$class->getName()] = [];
- }
- static::$_attributeMapping[$class->getName()][$method->getName()][] = $method;
- }
-
-
- /**
- * @param ReflectionClass $attribute
- * @param ReflectionMethod $method
- * @param $object
- */
- private function setMethodsAttributes(ReflectionClass $attribute, ReflectionMethod $method, $object)
- {
- if (!isset(static::$_methodsAttributes[$attribute->getName()])) {
- static::$_methodsAttributes[$attribute->getName()] = [];
- }
- static::$_methodsAttributes[$attribute->getName()][$method->getName()][] = $object;
- }
-
-
- /**
- * @param ReflectionClass $class
- */
- private function resolveTargetAttribute(ReflectionClass $class)
- {
- if ($class->isAbstract() || $class->isTrait()) {
- return;
- }
- foreach ($class->getAttributes() as $method) {
- if ($method->getName() == Target::class) {
- continue;
- }
- static::$_targetAttributes[$class->getName()] = $method->newInstance();
- }
- }
-
-
- /**
- * @param $className
- * @param $method
- * @return ReflectionMethod|null
- */
- public function getReflectionMethod($className, $method): ?ReflectionMethod
- {
- return static::$_reflectionMethod[$className][$method] ?? null;
- }
-
-
- /**
- * @param $className
- * @return ReflectionMethod|null
- */
- public function getTargetAnnotation($className): ?ReflectionMethod
- {
- return static::$_targetAttributes[$className] ?? null;
- }
-
-
/**
* @param $className
* @param $method
* @return array
+ * @throws ReflectionException
*/
public function getMethodAttribute($className, $method = null): array
{
- $methods = static::$_methodsAttributes[$className] ?? [];
+ $methods = $this->getMethodNote($this->getReflect($className));
if (!empty($method)) {
return $methods[$method] ?? [];
}
@@ -353,17 +185,18 @@ class Container extends BaseObject
* @param string $class
* @param string|null $property
* @return ReflectionProperty|ReflectionProperty[]|null
+ * @throws ReflectionException
*/
public function getClassReflectionProperty(string $class, string $property = null): ReflectionProperty|null|array
{
- if (!isset(static::$_reflectionProperty[$class])) {
+ $lists = $this->getProperty($this->getReflect($class));
+ if (empty($lists)) {
return null;
}
- $properties = static::$_reflectionProperty[$class];
if (!empty($property)) {
- return $properties[$property] ?? null;
+ return $lists[$property] ?? null;
}
- return $properties;
+ return $lists;
}
@@ -381,75 +214,78 @@ class Container extends BaseObject
return $object;
}
+
/**
* @param $class
- * @param array $dependencies
+ * @return ReflectionClass
+ * @throws ReflectionException
+ */
+ private function resolveDependencies($class): ReflectionClass
+ {
+ $this->_reflection[$class] = new ReflectionClass($class);
+ if (!$this->_reflection[$class]->isInstantiable()) {
+ throw new ReflectionException('Class ' . $class . ' cannot be instantiated');
+ }
+ $this->setPropertyNote($this->_reflection[$class]);
+ $this->setTargetNote($this->_reflection[$class]);
+ $this->setMethodNote($this->_reflection[$class]);
+ if (!is_null($construct = $this->_reflection[$class]->getConstructor())) {
+ $this->_constructs[$class] = $construct;
+ }
+ return $this->_reflection[$class];
+ }
+
+
+ /**
+ * @param ReflectionClass|string $class
+ * @return ReflectionMethod[]
+ */
+ #[Pure] public function getReflectMethods(ReflectionClass|string $class): array
+ {
+ return $this->getMethods($class);
+ }
+
+
+ /**
+ * @param ReflectionClass|string $class
+ * @param string $method
+ * @return ReflectionMethod|null
+ */
+ #[Pure] public function getReflectMethod(ReflectionClass|string $class, string $method): ?ReflectionMethod
+ {
+ return $this->getReflectMethods($class)[$method] ?? null;
+ }
+
+
+ /**
+ * @param ReflectionClass|string $class
+ * @param string $method
* @return array|null
* @throws NotFindClassException
* @throws ReflectionException
*/
- private function resolveDependencies($class, array $dependencies = []): ?array
+ public function getMethodParameters(ReflectionClass|string $class, string $method): ?array
{
- if (!isset(static::$_reflection[$class])) {
- if (!($reflect = new ReflectionClass($class))->isInstantiable()) {
- throw new ReflectionException('Class ' . $class . ' cannot be instantiated');
- }
- static::$_reflection[$class] = $reflect;
- $this->resolveTargetAttribute(static::$_reflection[$class]);
- $this->resolveMethodAttribute(static::$_reflection[$class]);
- $this->scanProperty(static::$_reflection[$class]);
+ if (isset($this->_parameters[$class]) && isset($this->_parameters[$class][$method])) {
+ return $this->_parameters[$class][$method];
}
- if (!is_null($construct = static::$_reflection[$class]->getConstructor())) {
- foreach ($this->resolveMethodParam($construct) as $key => $item) {
- $dependencies[$key] = $item;
- }
+ $reflectMethod = $this->getReflectMethod($class, $method);
+ if (!($reflectMethod instanceof ReflectionMethod)) {
+ throw new ReflectionException("Class does not have a function $class::$method");
}
- return [static::$_reflection[$class], $dependencies];
- }
-
-
- /**
- * @param ReflectionClass $reflectionClass
- * @return void
- */
- private function scanProperty(ReflectionClass $reflectionClass): void
- {
- $properties = $reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC |
- ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PROTECTED
- );
-
- $className = $reflectionClass->getName();
- foreach ($properties as $property) {
- $targets = $property->getAttributes(Inject::class);
- if (count($targets) < 1) {
- continue;
- }
-
- static::$_reflectionProperty[$className][$property->getName()] = $property;
-
- static::$_propertyAttributes[$className][$property->getName()] = $targets[0]->newInstance();
+ if ($reflectMethod->getNumberOfParameters() < 1) {
+ return [];
}
- }
-
-
- /**
- * @param ReflectionMethod|null $method
- * @return array
- * @throws NotFindClassException
- * @throws ReflectionException
- */
- private function resolveMethodParam(?ReflectionMethod $method): array
- {
- $array = [];
- foreach ($method->getParameters() as $parameter) {
+ $this->_parameters[$class][$method] = $params = [];
+ foreach ($reflectMethod->getParameters() as $key => $parameter) {
if ($parameter->isDefaultValueAvailable()) {
- $array[] = $parameter->getDefaultValue();
+ $params[$key] = $parameter->getDefaultValue();
} else {
$type = $parameter->getType();
if (is_string($type) && class_exists($type)) {
- $type = Snowflake::createObject($type);
+ $type = Snowflake::getDi()->get($type);
}
- $array[] = match ($parameter->getType()) {
+ $params[$key] = match ($parameter->getType()) {
'string' => '',
'int', 'float' => 0,
'', null, 'object', 'mixed' => NULL,
@@ -458,23 +294,21 @@ class Container extends BaseObject
};
}
}
- return $array;
+ return $this->_parameters[$class][$method] = $params;
}
/**
* @param $class
* @return ReflectionClass|null
- * @throws NotFindClassException
* @throws ReflectionException
*/
public function getReflect($class): ?ReflectionClass
{
- $reflect = static::$_reflection[$class] ?? null;
- if (!is_null($reflect)) {
- return $reflect;
+ if (!isset($this->_reflection[$class])) {
+ return $this->resolveDependencies($class);
}
- return $this->resolveDependencies($class)[0];
+ return $this->_reflection[$class];
}
/**
@@ -488,8 +322,8 @@ class Container extends BaseObject
$class = $class::class;
}
unset(
- static::$_reflection[$class], static::$_singletons[$class],
- static::$_param[$class], static::$_constructs[$class]
+ $this->_reflection[$class], $this->_singletons[$class],
+ $this->_param[$class], $this->_constructs[$class]
);
}
@@ -498,10 +332,10 @@ class Container extends BaseObject
*/
public function flush(): static
{
- static::$_reflection = [];
- static::$_singletons = [];
- static::$_param = [];
- static::$_constructs = [];
+ $this->_reflection = [];
+ $this->_singletons = [];
+ $this->_param = [];
+ $this->_constructs = [];
return $this;
}
@@ -513,12 +347,12 @@ class Container extends BaseObject
*/
private function mergeParam($class, $newParam): array
{
- if (empty(static::$_param[$class])) {
+ if (empty($this->_param[$class])) {
return $newParam;
} else if (empty($newParam)) {
- return static::$_param[$class];
+ return $this->_param[$class];
}
- $old = static::$_param[$class];
+ $old = $this->_param[$class];
foreach ($newParam as $key => $val) {
$old[$key] = $val;
}
diff --git a/System/Di/Service.php b/System/Di/Service.php
index 43d21d4c..a28342d3 100644
--- a/System/Di/Service.php
+++ b/System/Di/Service.php
@@ -23,133 +23,143 @@ use Snowflake\Snowflake;
class Service extends Component
{
- private array $_components = [];
+ private array $_components = [];
- private array $_definition = [];
+ private array $_definition = [];
- private array $_ids = [];
+ private array $_ids = [];
- protected array $_alias = [];
+ protected array $_alias = [];
- /**
- * @param $id
- * @param bool $try
- * @return mixed
- * @throws Exception
- */
- public function get($id, bool $try = true): mixed
- {
- if (isset($this->_components[$id])) {
- return $this->_components[$id];
- }
- if (!isset($this->_definition[$id]) && !isset($this->_alias[$id])) {
- if ($try === false) {
- return null;
- }
- throw new ComponentException("Unknown component ID: $id");
- }
- if (isset($this->_definition[$id])) {
- $config = $this->_definition[$id];
- if (is_object($config)) {
- return $this->_components[$id] = $config;
- }
- } else {
- $config = $this->_alias[$id];
- }
- return $this->_components[$id] = Snowflake::createObject($config);
- }
-
- /**
- * @param string $className
- * @param string $alias
- */
- public function setAlias(string $className, string $alias)
- {
- $this->_alias[$className] = $alias;
- }
-
- /**
- * @param $id
- * @param $definition
- *
- * @return mixed
- * @throws Exception
- */
- public function set($id, $definition): void
- {
- if ($definition === NULL) {
- $this->remove($id);
- return;
- }
-
- $this->_ids[] = $id;
-
- unset($this->_components[$id]);
- if (is_object($definition) || is_callable($definition, TRUE)) {
- $this->_definition[$id] = $definition;
- } else if (!is_array($definition)) {
- throw new ComponentException("Unexpected configuration type for the \"$id\" component: " . gettype($definition));
- }
- $this->_definition[$id] = $definition;
- }
-
- /**
- * @param $id
- * @return bool
- */
- #[Pure] public function has($id): bool
- {
- return in_array($id, $this->_ids);
- }
-
- /**
- * @param array $data
- * @throws Exception
- */
- public function setComponents(array $data)
- {
- foreach ($data as $key => $val) {
- $this->set($key, $val);
- }
- }
+ /**
+ * @param $id
+ * @param bool $try
+ * @return mixed
+ * @throws Exception
+ */
+ public function get($id, bool $try = true): mixed
+ {
+ if (isset($this->_components[$id])) {
+ return $this->_components[$id];
+ }
+ $config = $this->_getConfig($id, $try);
+ if (!is_object($config)) {
+ $config = Snowflake::createObject($config);
+ }
+ return $this->_components[$id] = $config;
+ }
- /**
- * @param $name
- * @return mixed
- * @throws Exception
- */
- public function __get($name): mixed
- {
- if ($this->has($name)) {
- return $this->get($name);
- }
+ /**
+ * @param $id
+ * @param $try
+ * @return mixed
+ * @throws ComponentException
+ */
+ private function _getConfig($id, $try): mixed
+ {
+ $config = $this->_definition[$id] ?? $this->_alias[$id] ?? null;
+ if (is_null($config)) {
+ if ($try === false) {
+ return null;
+ }
+ throw new ComponentException("Unknown component ID: $id");
+ }
+ return $config;
+ }
- return parent::__get($name);
- }
- /**
- * @param $id
- * @return bool
- */
- public function remove($id): bool
- {
- $component = $this->_components[$id];
- $className = $component::class;
+ /**
+ * @param string $className
+ * @param string $alias
+ */
+ public function setAlias(string $className, string $alias)
+ {
+ $this->_alias[$className] = $alias;
+ }
- unset($component, $this->_components[$id]);
- unset($this->_definition[$id]);
- if (isset($this->_alias[$id])) {
- unset($this->_components[$this->_alias[$id]]);
- unset($this->_definition[$this->_alias[$id]]);
- unset($this->_alias[$id]);
- }
+ /**
+ * @param $id
+ * @param $definition
+ *
+ * @return mixed
+ * @throws Exception
+ */
+ public function set($id, $definition): void
+ {
+ if ($definition === NULL) {
+ $this->remove($id);
+ return;
+ }
+ $this->_ids[] = $id;
+ unset($this->_components[$id]);
+ if (is_object($definition)) {
+ $this->_components[$id] = $definition;
+ $this->_definition[$id] = $definition;
+ } else if (!is_array($definition)) {
+ throw new ComponentException("Unexpected configuration type for the \"$id\" component: " . gettype($definition));
+ } else {
+ $this->_definition[$id] = $definition;
+ }
+ }
- Snowflake::getDi()->unset($className);
+ /**
+ * @param $id
+ * @return bool
+ */
+ #[Pure] public function has($id): bool
+ {
+ return in_array($id, $this->_ids);
+ }
- return $this->has($id);
- }
+ /**
+ * @param array $data
+ * @throws Exception
+ */
+ public function setComponents(array $data)
+ {
+ foreach ($data as $key => $val) {
+ $this->set($key, $val);
+ }
+ }
+
+
+ /**
+ * @param $name
+ * @return mixed
+ * @throws Exception
+ */
+ public function __get($name): mixed
+ {
+ if ($this->has($name)) {
+ return $this->get($name);
+ }
+
+ return parent::__get($name);
+ }
+
+ /**
+ * @param $id
+ * @return bool
+ */
+ public function remove($id): bool
+ {
+ $component = $this->_components[$id];
+ $className = $component::class;
+
+ unset($component, $this->_components[$id]);
+ unset($this->_definition[$id]);
+ if (isset($this->_alias[$id])) {
+ unset($this->_components[$this->_alias[$id]]);
+ unset($this->_definition[$this->_alias[$id]]);
+ unset($this->_alias[$id]);
+ }
+
+ Snowflake::getDi()->unset($className);
+
+ return $this->has($id);
+ }
}
diff --git a/System/Events/EventDispatch.php b/System/Events/EventDispatch.php
new file mode 100644
index 00000000..e3531c2c
--- /dev/null
+++ b/System/Events/EventDispatch.php
@@ -0,0 +1,32 @@
+eventListener->getEventListeners($event);
+ if (empty($events)) {
+ return;
+ }
+ while ($events->valid()) {
+ /** @var EventDispatchInterface $interface */
+ $interface = $events->current();
+ $interface->onHandler();
+ if ($interface->stopPagination()) {
+ break;
+ }
+ $events->next();
+ }
+ }
+
+}
diff --git a/System/Events/EventDispatchInterface.php b/System/Events/EventDispatchInterface.php
new file mode 100644
index 00000000..42fb8986
--- /dev/null
+++ b/System/Events/EventDispatchInterface.php
@@ -0,0 +1,18 @@
+_events[$event])) {
+ $this->_events[$event] = new SplPriorityQueue();
+ }
+ $this->_events[$event]->insert($handler, $handler->getZOrder());
+ }
+
+
+ /**
+ * @param $event
+ * @return SplPriorityQueue|null
+ */
+ public function getEventListeners($event): ?SplPriorityQueue
+ {
+ return $this->_events[$event] ?? null;
+ }
+
+
+}
diff --git a/System/Events/EventProviders.php b/System/Events/EventProviders.php
new file mode 100644
index 00000000..88441e1e
--- /dev/null
+++ b/System/Events/EventProviders.php
@@ -0,0 +1,8 @@
+get($class, $construct, $className);
+ return static::$container->newObject($class, $construct, $className);
} else if (is_callable($className, TRUE)) {
return call_user_func($className, $construct);
} else {
@@ -250,7 +250,7 @@ class Snowflake
*/
public static function setManagerId($workerId): mixed
{
- if (empty($workerId) || static::isDcoker()) {
+ if (empty($workerId) || static::isDocker()) {
return $workerId;
}
@@ -267,7 +267,7 @@ class Snowflake
*/
public static function setProcessId($workerId): mixed
{
- if (empty($workerId) || static::isDcoker()) {
+ if (empty($workerId) || static::isDocker()) {
return $workerId;
}
@@ -280,7 +280,7 @@ class Snowflake
/**
* @return bool
*/
- public static function isDcoker(): bool
+ public static function isDocker(): bool
{
$output = shell_exec('[ -f /.dockerenv ] && echo yes || echo no');
if (trim($output) === 'yes') {
@@ -297,7 +297,7 @@ class Snowflake
*/
public static function setWorkerId($workerId): mixed
{
- if (empty($workerId) || static::isDcoker()) {
+ if (empty($workerId) || static::isDocker()) {
return $workerId;
}
@@ -314,7 +314,7 @@ class Snowflake
*/
public static function setTaskId($workerId): mixed
{
- if (empty($workerId) || static::isDcoker()) {
+ if (empty($workerId) || static::isDocker()) {
return $workerId;
}