我有一个脚本(一个小而简单的类似CMS的系统),我一直在努力将其用于客户端站点。由于客户有不同的要求,我实施了一个模块系统,允许我修改/或向CMS添加功能,而无需修改CMS脚本。
如何实施允许我从模块更改主CMS的默认设置的配置系统?
例如,CMS默认有两个菜单:$menu = array('menu-1', 'menu-2');
我怎么能从模块中覆盖这个设置?
我想到的一个解决方案是使用常量和序列化/反序列化:
defined("BLA") or define("BLA", serialize(array(
'boo' => 'stuff',
'foo' => array('1', '2', '3'),
'moo' => true,
...
)));
因此,我可以在模块初始化函数中轻松覆盖此设置,该函数在CMS中定义常量之前运行。
然后我在脚本中的每个地方都使用这些常量,例如:
$bla = unserialize(BLA);
...
foreach(unserialize(BLA) as $key => $value)...
另一种选择是使用全局变量,但人们说使用全局变量是不好的。
那么我正在寻找什么更好的解决方案吗?
答案 0 :(得分:5)
我建议使用带有静态变量的类。或多或少相同的结果,但不需要反序列化,您实际上可以使用变量,而不是临时变量。
// My Constants
class MCo {
public static $BLA = array(
'boo' => 'stuff',
'foo' => array('1', '2', '3'),
'moo' => true,
// ...
);
}
echo MCo::$BLA['boo'];
foreach (MCo::$BLA as $key => $value) {
// ...
}
编辑: ircmaxell有一点,请考虑一下
// My Private Constants
class MPCo {
private static $_BLA = array(
'boo' => 'stuff',
'foo' => array('1', '2', '3'),
'moo' => true,
// ...
);
public static BLA() {
return self::$_BLA;
}
}
foreach (MPCo::BLA() as $key => $value) {
// ...
}
答案 1 :(得分:1)
如果要计划存储在阵列中的很多静态数据,为什么不将它存储在配置文件中呢?或者,您可以从数据库加载它,但配置更好。
另一个选择是做@inti在答案中建议的内容。
答案 2 :(得分:1)
我要问的第一个问题是为什么你需要一个常数中的数组。您的问题可能有另一种解决方案,但同样不错,但不需要数组。
更好的另一种方法是创建一个配置对象,然后传递它。这样它仍然可以测试,因为它注入了依赖项,并且没有使用序列化对性能产生影响。
$config = new StdClass();
$config->boo = 'stuff';
doSomething($config);
常量并不比全局变量好多少。实际上,它们在某些方面更糟糕,因为它很难用它们进行测试,因为一旦定义了常量,就无法改变它。因此,在追求良好的可测试代码时,常量并不好。如果你依赖于处理魔术数字或文件系统路径以外的常量,你可能想重新考虑你的方法(甚至魔术数字常量可能更好用配置类处理)...
答案 3 :(得分:1)
这实际上是不必要的,只需使用一个变量而不是一个常数,它会更简单,更清晰,我觉得会更好。