【问题标题】:PHP - constants/global variables/configurationPHP - 常量/全局变量/配置
【发布时间】:2011-02-03 16:25:02
【问题描述】:

我有一个脚本(一个小而简单的类似 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)...

另一种选择是使用全局变量,但人们说使用全局变量不好。

那么对于我正在寻找的东西有更好的解决方案吗?

【问题讨论】:

  • 你为什么要这么做?如果你要走那条路,也可以定义一个全局数组。或者,您可以使用一个配置库,它允许您将数组存储为配置值。
  • 因为我需要一个数组常量 :) 而且我不想使用全局变量
  • 你在使用 MVC 框架吗?
  • 没有。除了全局变量之外,还有其他方法可以存储我想要的数据并能够在任何地方访问吗?
  • 让一个函数返回那个数组怎么样?

标签: php arrays performance constants


【解决方案1】:

我建议使用带有静态变量的类。结果大致相同,但不需要反序列化,您可以实际使用变量,而不是临时变量。

// 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) {
    // ...
}

【讨论】:

  • 概念略有不同,因为公共静态变量是可变的,而常量则不是。 (MCo::$BLA['foo'] = 'bar';)...但可能是一个不错的选择。
  • 是的,与我作为评论建议她的概念相同 - 使用单例。
  • 您可以通过派生 ArrayObject 并将 offsetSet() 设为 NOP,使其成为只读数组。
  • 听起来很有趣。我想使用常量的原因是因为我可以通过在另一个脚本中更早地定义它们来“覆盖”默认值(并且只有在之前没有定义它们时才在当前脚本中定义它们)。我可以用你的方法吗?
  • @inti:更好,但由于 PHP 不支持数组解引用,因此访问数组的直接成员变量会很尴尬(又名MPCo::bla()['foo'] 将不起作用)。好多了,但还是有一些问题...
【解决方案2】:

如果您打算将大量静态数据存储在数组中,为什么不将其存储在配置文件中呢?或者,您可以从数据库中加载它,但配置更好。

另一种选择是按照@inti 在他的回答中提出的建议。

【讨论】:

  • 因为这不是真正的“配置”,它更像是代码配置:) 真正的配置使用数据库。基本上我有一个定义了这些常量的 script1(一个类似 CMS 的系统,用于不同的客户端)。然后我创建其他可能使用 script1 的脚本 (2,3..)。所以我可以在脚本 2,3 等中定义这些常量(就像这个简单 CMS 的“模块”),在 script1 中更改这个配置......这样我就不必为每个客户端修改 script1,我可以从模块中做到这一点......这可以用你提到的单例类来完成吗?如果有,怎么做?
【解决方案3】:

我要问的第一个问题是为什么你需要一个常量数组。您的问题可能还有另一种解决方案,它同样好,但不需要数组。

一个更好的选择是创建一个配置对象,然后传递它。这样它仍然是可测试的,因为它正在注入依赖项并且不会对使用序列化产生性能影响。

$config = new StdClass();
$config->boo = 'stuff';

doSomething($config);

常量并不比全局变量好多少。事实上,它们在某些方面更糟糕,因为用它们非常很难测试,因为一旦你定义了一个常数,你就不能改变它。所以在追求好的可测试代码的过程中,常量是不好的。如果您依赖常量而不是处理幻数或文件系统路径,您可能需要重新考虑您的方法(即使幻数常量也可能使用配置类更好地处理)...

【讨论】:

  • 我需要它来获取配置。这个配置不是从数据库中检索的,值是在脚本中设置的,就像设置一个常量一样
【解决方案4】:

这真的没必要,只用一个变量而不是一个常数,它会更简单,更清晰,我猜性能更好。

【讨论】:

  • 我已经重写了这个问题,以更好地解释我在寻找什么:)
猜你喜欢
  • 2015-09-04
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 2011-01-04
相关资源
最近更新 更多