【问题标题】:Making a global variable accessible for every function inside a class使类中的每个函数都可以访问全局变量
【发布时间】:2009-02-06 04:15:32
【问题描述】:

我在全局范围内有一个名为 ${SYSTEM} 的变量,其中 SYSTEM 是一个已定义的常量。我有很多类的函数需要访问这个变量,我发现每次都声明 global ${SYSTEM}; 很烦人。

我尝试声明一个类变量:public ${SYSTEM} = $GLOBALS[SYSTEM];,但这会导致语法错误,这很奇怪,因为我有另一个类以这种方式声明类变量并且似乎工作正常。我唯一能想到的是常量没有被识别。

我已经设法通过构造函数解决了这个问题,但在求助之前我正在寻找一个更简单的解决方案。


编辑 全局 ${SYSTEM} 变量是一个包含许多其他子数组的数组。不幸的是,似乎没有办法使用构造函数来解决......

【问题讨论】:

    标签: php class function variables global


    【解决方案1】:

    好的,希望我已经掌握了您想要实现的目标

    <?php
        // the global array you want to access
        $GLOBALS['uname'] = array('kernel-name' => 'Linux', 'kernel-release' => '2.6.27-11-generic', 'machine' => 'i686');
    
        // the defined constant used to reference the global var
        define(_SYSTEM_, 'uname');
    
        class Foo {
    
            // a method where you'd liked to access the global var  
            public function bar() {
                print_r($this->{_SYSTEM_});
            }
    
            // the magic happens here using php5 overloading
            public function __get($d) {
                return $GLOBALS[$d];  
            }
    
        }
    
        $foo = new Foo;
        $foo->bar();
    
    ?>
    

    【讨论】:

      【解决方案2】:

      这就是我在没有全局的情况下全局访问事物的方式。

      class exampleGetInstance 
      {
      
      private static $instance;
      
      public $value1;
      public $value2;
      
      
      private function initialize() 
      {
          $this->value1 = 'test value';
          $this->value2 = 'test value2';
      
      }
      
      public function getInstance()
      {
          if (!isset(self::$instance))
          {
              $class = __CLASS__;
              self::$instance = new $class();
              self::$instance->initialize();
          }
          return self::$instance;
      }
      
      }
      
      $myInstance = exampleGetInstance::getInstance();
      
      echo $myInstance->value1;
      

      $myInstance 现在是对exampleGetInstance 类实例的引用。

      固定格式

      【讨论】:

        【解决方案3】:

        你可以使用这样的构造函数:

        class Myclass {
          public $classvar; 
          function Myclass() {
            $this->classvar = $GLOBALS[SYSTEM];
          }
        }
        

        编辑:感谢您指出错字,彼得!

        这也适用于数组。如果不需要分配,也可以参考:

        $this->classvar =& $GLOBALS[SYSTEM];
        

        EDIT2:以下代码用于测试此方法并在我的系统上运行:

        <?php
        define('MYCONST', 'varname');
        $varname = array("This is varname", "and array?");
        
        class Myclass {
          public $classvar;
          function Myclass() {
            $this->classvar =& $GLOBALS[MYCONST];
          }
          function printvar() {
            echo $this->classvar[0]; 
            echo $this->classvar[1];
          }
        };
        
        $myobj = new Myclass;
        $myobj->printvar();
        ?>
        

        【讨论】:

        • 应该是'$this->classvar = ...'?
        【解决方案4】:

        成员变量的直接说明不能包含对其他变量的任何引用(class {public $membervar = $outsidevar;} 也是无效的)。请改用构造函数。

        但是,当您处理常量时,为什么不使用 php 的 constantclass constant 设施?

        【讨论】:

          【解决方案5】:

          你在这里尝试做一些非常不寻常的事情,所以你可以预料它会很尴尬。使用全局变量永远不会令人愉快,尤其是使用 SYSTEM 常量选择动态名称时更是如此。我个人建议你在任何地方都使用$GLOBALS[SYSTEM],或者...

          $sys = $GLOBALS[SYSTEM];
          

          ...如果您要经常使用它。

          【讨论】:

            【解决方案6】:

            您也可以尝试单例模式,虽然在某种程度上它在 OOP 圈子中不受欢迎,但它通常被称为类的全局变量。

            <?php
            class Singleton {
            
              // object instance
              private static $instance;
            
              // The protected construct prevents instantiating the class externally.  The construct can be
              // empty, or it can contain additional instructions...
              protected function __construct() {
                ...
              }
            
              // The clone and wakeup methods prevents external instantiation of copies of the Singleton class,
              // thus eliminating the possibility of duplicate objects.  The methods can be empty, or
              // can contain additional code (most probably generating error messages in response
              // to attempts to call).
              public function __clone() {
                trigger_error('Clone is not allowed.', E_USER_ERROR);
              }
            
              public function __wakeup() {
                trigger_error('Deserializing is not allowed.', E_USER_ERROR);
              }
            
              //This method must be static, and must return an instance of the object if the object
              //does not already exist.
              public static function getInstance() {
                if (!self::$instance instanceof self) { 
                  self::$instance = new self;
                }
                return self::$instance;
              }
            
              //One or more public methods that grant access to the Singleton object, and its private
              //methods and properties via accessor methods.
              public function GetSystemVar() {
                ...
              }
            }
            
            //usage
            Singleton::getInstance()->GetSystemVar();
            
            ?>
            

            这个例子是从维基百科稍微修改的,但你可以理解。尝试使用谷歌搜索单例模式以获取更多信息

            【讨论】:

            • 我看不出这与单例有什么关系。
            • 这有什么关系?一个解释似乎更合适。
            【解决方案7】:

            我想说最让我印象深刻的两件事是:

            1. 您不需要在变量名周围加上方括号,您可以简单地使用 public $system 或 public $SYSTEM。
            2. 虽然 PHP 可能并不总是需要它,但标准做法是将非数字数组索引封装在单引号或双引号中,以防您使用的字符串在某些时候变为常量。

            这应该是你要找的

            class SomeClass {
              public $system = $GLOBALS['system'];
            }
            

            你也可以使用类常量来代替

            class SomeClass {
              const SYSTEM = $GLOBALS['system'];
            }
            

            这可以在类中使用 'self::SYSTEM' 和外部使用 'SomeClass::SYSTEM' 进行引用。

            【讨论】:

            • 这是否意味着常量> 变量名?
            • 问题中SYSTEM是常量,不是变量名。
            • 我不知道你在说什么,但 ${SYSTEM} 绝对与 $SYSTEM 不一样...
            • @E3,你指的是我的评论吗?我是说 Steven 可能把 SYSTEM 误认为是一个变量。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-16
            • 1970-01-01
            • 1970-01-01
            • 2015-02-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多