fix(config): 修复Config类循环依赖

This commit is contained in:
zimoyin
2026-03-11 03:58:21 +08:00
parent 3471deb3f1
commit 5adf3930e2
3 changed files with 192 additions and 45 deletions
+56 -8
View File
@@ -2,8 +2,7 @@
namespace app\config;
use app\config\DatabaseConfig;
use app\utils\Logger;
class Config
{
@@ -83,10 +82,12 @@ class Config
*/
public bool $blockMode {
get => $this->blockMode;
set(bool $value){
Logger::error("禁止修改热修改阻断模式,这只是用于测试方法");
$this->blockMode = $value;
}
}
public function setBlockMode(bool $value)
{
echo "\033[31m获取禁止修改热修改阻断模式,这只是用于测试方法\033[0m\n";
$this->blockMode = $value;
}
/**
@@ -113,6 +114,7 @@ class Config
private function __construct()
{
$this->detectCircularDependency();
$this->database = new DatabaseConfig();
$this->customProcess = require __DIR__ . '/custom_process_config.php';
$this->machineId = self::getStringEnv("MACHINE_ID", "0");
@@ -142,6 +144,52 @@ class Config
$this->enableVirtualCleanerParser = self::getBoolEnv('ENABLE_VIRTUAL_CLEANER_PARSER', false);
}
private function __clone() {}
private function detectCircularDependency(): void
{
// 获取调用栈(深度10层,足够覆盖依赖链)
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
$logRelatedPaths = [
'support/Log.php', // Log类文件
'support\Log.php', // Windows路径
'config/log.php', // 日志配置文件
'monolog' // 日志组件
];
// 遍历调用栈,检查是否包含日志相关文件
foreach ($trace as $step) {
if (isset($step['file'])) {
$file = strtolower($step['file']);
foreach ($logRelatedPaths as $path) {
if (str_contains($file, strtolower($path))) {
throw new \RuntimeException(
"循环依赖检测:Config类初始化时检测到日志组件({$step['file']})被引入\n" .
"请移除Config类中对日志的依赖,或调整日志配置加载逻辑。"
);
}
}
}
// 检查是否直接调用了 Log 类
if (isset($step['class']) && str_contains(strtolower($step['class']), 'support\log')) {
throw new \RuntimeException(
"循环依赖检测:Config类被 support\Log 类直接调用,导致循环依赖!"
);
}
}
// 检查当前文件是否主动引入了 Log 类(防止硬编码引入)
$includedFiles = get_included_files();
foreach ($includedFiles as $file) {
if (str_contains(strtolower($file), 'support/log')) {
throw new \RuntimeException(
"循环依赖检测:Config类加载时,support\Log 已被提前引入({$file}),禁止循环依赖!"
);
}
}
}
/**
* 获取服务器MAC地址并散列成2位数字(00-99)作为机器ID
* 兼容Linux/Windows系统,失败时降级使用IP散列
@@ -201,8 +249,8 @@ class Config
// 步骤4:补零为2位(如5→05,99→99)
return str_pad($machineId, 2, '0', STR_PAD_LEFT);
} catch (\Exception $e) {
// 极端异常时返回默认值(建议日志记录)
Logger::error('获取机器ID失败:', ['error' => $e->getMessage()]);
// 红色输出
echo "\033[31m获取机器ID失败:{$e->getMessage()}\033[0m\n";
return '01'; // 默认机器ID
}
}