diff --git a/src/ZM/Config/ConfigTracer.php b/src/ZM/Config/ConfigTracer.php new file mode 100644 index 00000000..8c1d4a4a --- /dev/null +++ b/src/ZM/Config/ConfigTracer.php @@ -0,0 +1,58 @@ +traces = array_merge($this->traces, $this->flatten($group, $traces, $source)); + } + + /** + * 获取配置项的来源 + * + * @param string $key 配置项 + * @return null|string 来源,如果没有找到,返回 null + */ + public function getTraceOf(string $key): ?string + { + return $this->traces[$key] ?? null; + } + + /** + * 扁平化配置 + * + * @param string $prefix 前缀 + * @param array $array 数组 + * @param string $source 来源 + * @return array 扁平化后的数组,键名为 $prefix . $key,键值为 $source + */ + private function flatten(string $prefix, array $array, string $source): array + { + $result = []; + $prefix = $prefix ? $prefix . '.' : ''; + foreach ($array as $key => $value) { + if (is_array($value)) { + $result += $this->flatten($prefix . $key, $value, $source); + } else { + $result[$prefix . $key] = $source; + } + } + return $result; + } +} diff --git a/src/ZM/Config/ZMConfig.php b/src/ZM/Config/ZMConfig.php index ef6d30a7..30eb7248 100644 --- a/src/ZM/Config/ZMConfig.php +++ b/src/ZM/Config/ZMConfig.php @@ -7,6 +7,7 @@ namespace ZM\Config; use OneBot\Util\Singleton; use OneBot\V12\Config\Config; use ZM\Exception\ConfigException; +use ZM\Framework; class ZMConfig implements \ArrayAccess { @@ -56,6 +57,11 @@ class ZMConfig implements \ArrayAccess */ private Config $holder; + /** + * @var null|ConfigTracer 配置跟踪器 + */ + private ?ConfigTracer $tracer; + /** * 构造配置实例 * @@ -69,49 +75,16 @@ class ZMConfig implements \ArrayAccess $this->config_paths = $config_paths ?: [self::DEFAULT_CONFIG_PATH]; $this->environment = self::$environment_alias[$environment] ?? $environment; $this->holder = new Config([]); + if (Framework::getInstance()->getArgv()['debug'] ?? false) { + $this->tracer = new ConfigTracer(); + } else { + $this->tracer = null; + } if ($environment !== 'uninitiated') { $this->loadFiles(); } } - /** - * 添加配置文件路径 - * - * @param string $path 路径 - */ - public function addConfigPath(string $path): void - { - if (!in_array($path, $this->config_paths, true)) { - $this->config_paths[] = $path; - } - } - - /** - * 获取当前环境 - * - * @return string 当前环境 - */ - public function getEnvironment(): string - { - return $this->environment; - } - - /** - * 设置当前环境 - * - * 变更环境后,将会自动调用 `reload` 方法重载配置 - * - * @param string $environment 目标环境 - */ - public function setEnvironment(string $environment): void - { - $target = self::$environment_alias[$environment] ?? $environment; - if ($this->environment !== $target) { - $this->environment = $target; - $this->reload(); - } - } - /** * 加载配置文件 * @@ -210,11 +183,41 @@ class ZMConfig implements \ArrayAccess } /** - * 获取内部配置容器 + * 添加配置文件路径 + * + * @param string $path 路径 */ - public function getHolder(): Config + public function addConfigPath(string $path): void { - return $this->holder; + if (!in_array($path, $this->config_paths, true)) { + $this->config_paths[] = $path; + } + } + + /** + * 获取当前环境 + * + * @return string 当前环境 + */ + public function getEnvironment(): string + { + return $this->environment; + } + + /** + * 设置当前环境 + * + * 变更环境后,将会自动调用 `reload` 方法重载配置 + * + * @param string $environment 目标环境 + */ + public function setEnvironment(string $environment): void + { + $target = self::$environment_alias[$environment] ?? $environment; + if ($this->environment !== $target) { + $this->environment = $target; + $this->reload(); + } } /** @@ -230,6 +233,14 @@ class ZMConfig implements \ArrayAccess $this->loadFiles(); } + /** + * 获取内部配置容器 + */ + public function getHolder(): Config + { + return $this->holder; + } + public function offsetExists($offset): bool { return $this->get($offset) !== null; @@ -251,6 +262,22 @@ class ZMConfig implements \ArrayAccess $this->set($offset); } + /** + * 获取配置项的来源 + * + * @param string $key 配置项 + * @return null|string 来源,如果没有找到,返回 null + */ + public function getTrace(string $key): ?string + { + if ($this->tracer === null) { + logger()->warning('你正在获取配置项的来源,但没有开启配置来源追踪功能'); + return null; + } + + return $this->tracer->getTraceOf($key); + } + /** * 获取文件元信息 * @@ -389,5 +416,9 @@ class ZMConfig implements \ArrayAccess // 加入配置 $this->merge($group, $config); logger()->debug("已载入配置文件:{$path}"); + + if ($this->tracer !== null) { + $this->tracer->addTracesOf($group, $config, $path); + } } }