在PHP中处理全局变量的最有效方法是什么?

6

有些人似乎不喜欢全局变量,但如果你能解释如何在没有它们的情况下编写代码,我很愿意听取建议。

除此之外,我有几个选项,并且想知道哪一个是最好的长期选择。考虑到我有一个在整个程序运行期间都不会改变的变量,它是一个静态全局变量。我可以使用:

$_SESSION['var'] = constantval;
define('var', constantval);
var = constantval;

我真正好奇的是:

function my_constants($which)
{
    switch ($which) {
        case 'var':
            return 'constantval';
    }
}

在上述代码中,目标是将变量从全局作用域中移除,以节省内存,但会牺牲一些处理器的性能。那么节省的内存是否值得这些牺牲?不同类型的全局声明之间是否有值得注意的区别?


请给出一个例子来说明你所说的“如果你可以在不使用全局变量的情况下解释如何编程”…你需要告诉我为什么要使用全局变量。 - Goikiu
这个问题充满了误导,其中最大的一个是:如果您可以硬编码var的值,那么它怎么能是一个变量呢? - Jon
变量不等于常量。 - Salman A
1
你应该使用define来定义常量值,不仅为了可读性的原因。使用define定义常量是一种设计声明,意味着:这个值不应该被应用程序更改。常量的内部处理在许多方面与变量不同。它们可以在脚本解析的早期阶段进行翻译。请记住,PHP脚本首先被翻译成其AST,然后到IR,最后再编译。因为PHP解释器是一个三重编译器,所以在执行这三个解析步骤时会发生许多事情。 - Peter
语句将被转换:echo "This is {$someVar}" 将被转换为 echo "This is";echo $someVar。常量将被替换为它们的值。但变量不会被替换为它们的值。 - Peter
显示剩余2条评论
2个回答

3

全局变量并不是因为内存使用或处理器成本而被认为是一种不好的实践。这是因为允许程序中的任何部分修改它们可能引起的问题。随着时间的推移,理解哪些部分读取或写入您的全局变量变得困难。


虽然如此,我真的不知道你如何避免像我举的例子中那样的常量。我愿意听取其他想法,但如果我有一个常量值,例如指向我的图形文件路径或允许的小部件最大数量,我应该把这些信息放在哪里以避免硬编码呢? - not_a_generic_user
1
你可以毫无问题地使用常量。与变量不同,它们是不可变的,应用程序的其他部分将无法修改它。为了不污染全局常量空间,我认为使用类常量会更合适,正如Artefacto在这个问题的答案中建议的那样:https://dev59.com/9mw15IYBdhLWcg3wQpXS - Guilherme Sehn
如果我可以快速澄清一下:全局变量和常量之间的唯一功能区别是标准的整洁性吗?也就是说,它让人们感觉更舒适,但除此之外并没有太大的不同行为表现? - not_a_generic_user
1
@not_a_generic_user 常量和全局变量的区别在于常量不可变,所以一旦设置了其值,就无法修改。今天你肯定知道,你不会修改一个旨在存储常量信息的全局变量,但你应该考虑到将来可能会有其他人对这段代码进行维护,或者你自己在将来忘记了这个细节。在这个时候做出正确的设计决策将会使你的代码更加健壮。 - Guilherme Sehn
@GuilhermeSehn,非常好的观点。所以人们“讨厌全局变量”的真正原因是因为你应该使用常量(至少对于不变的值)。 - not_a_generic_user
显示剩余2条评论

0

全局变量(单例)的替代方案。它将为您提供细粒度的访问控制: 例如:

 class ConfigParamSingelton {
     private var $value;
     private static $mInstance = null;

     public function getValue() { 
         return $this->value;
     }

     public function getInstance() {
         if(self::$mInstance == null) {
            self::$mInstance = new ConfigParamSingelton();
         }
         return self::$mInstance;
     }

现在你可以选择:

     protected function setValue($val) { // is immuteable by clients of the object
          $this->value = $val;
     }

或者

     public function setValue($val) {// is muteable
          $this->value = $val;
     }

这就是单例模式。在这种情况下,您不需要全局变量。


虽然单例模式也被认为是不好的实践,但Symfony2提供了一个CDI容器。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接