用static方法+单例模式+配置数组分离更优,因DBDA类是数据访问封装而非纯配置类,new会重复建MySQLi连接、引发泄漏与并发冲突,且配置不应有状态、难维护、无加载失败兜底;推荐Config类通过静态get/all方法读取外部config.php数组,缓存一次、安全可靠。

直接说结论:用 static 方法 + 单例模式 + 配置数组分离,比每次 new 一个实例更方便调用,也更安全。
为什么不能直接 new DBDA() 这种方式用在配置类上
你看到的 DBDA 类本质是数据访问封装,不是纯配置类。它把数据库连接参数写死在属性里,每次 new 都会新建一次 MySQLi 连接——这对配置读取来说是过度设计,还容易引发连接泄漏或并发冲突。
-
new DBDA()每次实例化都重复初始化四个属性,但配置本身不该有“状态” - 如果多个地方同时
new,参数改一处漏一处,维护成本高 - 没有加载失败兜底(比如配置文件不存在、JSON 解析失败),直接报错中断执行
推荐的配置类封装结构:静态方法 + 外部配置文件
把配置项从类里抽出来,放到独立文件中,类只负责“读”和“缓存”,不参与业务逻辑。
- 配置文件用
config.php(返回关联数组),避免 JSON 解析开销和语法限制 - 类用
Config命名,提供get($key)和all()两个静态方法 - 内部用
static $data = null缓存一次读取结果,后续调用不重复加载 - 首次加载失败时抛出
Exception,而不是静默返回null或空数组
示例 config.php:
立即学习“PHP免费学习笔记(深入)”;
<?php
return [
'database' => [
'host' => 'localhost',
'port' => 3306,
'dbname' => 'myapp',
'charset' => 'utf8mb4'
],
'debug' => true,
'timezone' => 'Asia/Shanghai'
];
对应 Config.php:
<?php
class Config
{
private static $data = null;
public static function get($key, $default = null)
{
if (self::$data === null) {
self::load();
}
$keys = explode('.', $key);
$value = self::$data;
foreach ($keys as $k) {
if (!is_array($value) || !isset($value[$k])) {
return $default;
}
$value = $value[$k];
}
return $value;
}
private static function load()
{
$file = __DIR__ . '/config.php';
if (!is_file($file)) {
throw new Exception("Config file not found: {$file}");
}
$data = require $file;
if (!is_array($data)) {
throw new Exception("Config file must return an array");
}
self::$data = $data;
}
}
调用时直接:Config::get('database.host') 或 Config::get('debug', false)
容易踩的坑:private 属性 + 构造函数陷阱
很多人模仿 DBDA 写法,把配置值设为 private 属性,再靠构造函数传参初始化——这反而让调用变麻烦,还失去“全局可读”的本意。
- 构造函数传参意味着每次
new Config($host, $user...),参数顺序一错就难调试 -
private属性无法被子类继承,也无法被 IDE 自动补全(因为没公共 getter) - 如果真要用对象实例(比如多环境切换),应明确区分:用
Config::forEnv('prod')返回不同实例,而不是靠构造函数硬塞
最常被忽略的一点:配置类不该承担连接、验证、加密等职责。它只做一件事——可靠、快速、可预测地返回数组里的某个值。其他逻辑交给专门的类(如 Database、Crypt)去处理。



















