【问题标题】:How to make variable global across entire class如何在整个班级中使变量成为全局变量
【发布时间】:2012-02-11 13:46:16
【问题描述】:

非常简单的问题,是否可以将一个从类外部检索到的变量设为“全局”到整个类,这样我就不必在每个方法的开头调用“全局 $variable” ?

这是我目前正在做的事情:

class test{
    public function testing(){
        global $globalVariable,

        // Do something
    }
    public function testing_two(){
        global $globalVariable,

        // Do something
    }
}

换句话说,我可以将变量导入构造函数,从而使整个类都可以访问它们,而不必为每个方法调用“全局”吗?

更新

不确定我是否对我想要实现的目标说得太清楚了。请看下面:

$globalVariable = 'hello';

class test{
    public function testing(){
        global $globalVariable,

        // Do something
    }
    public function testing_two(){
        global $globalVariable,

        // Do something
    }
}

【问题讨论】:

  • 只需将其作为参数传递给构造函数并将其分配给私有属性即可。
  • @FelixKling 如果他需要一个真正的全局变量,这将中断,因为它在类之外被更改。想到全局数据库连接资源。
  • @Eugen:无论如何,全局变量都是一个糟糕的设计决策,恕我直言。如果代码增长,代码将变得更加难以维护和重构。
  • @Ben:为什么它们是全球性的?您是否在脚本运行期间更改数据库连接?为什么不将它作为参数传递给构造函数(依赖注入)。有许多设计模式可以避免使用全局变量(有充分的理由)。
  • @BenCarey:你大错特错。继续这样做,你会学到很多东西。

标签: php class


【解决方案1】:

要弄清楚如何做到这一点:

你很可能想做这样的事情 include('database.php');。那时,您包含的所有内容对您的脚本都是全局的。现在,如果你有一个像上面这样的类,你可以添加一个构造函数:

class testclass
{
    private $db;

    public function __construct($db)
    {
       $this->db = $db;
    }

    public function yourmethod()
    {
       $this->db->prepare(); // And so on
    }
}

假设您的全局变量在全局范围内称为 $db。您现在可以使用new testclass($db); 构造您的对象。现在,当您在所有方法中使用 $this->db 时,无需使用 global 语句。

【讨论】:

  • 谢谢!!这正是我想要的,我想要的只是确认。出于兴趣,参考的好处(点)是什么?
  • 上述方法有几个好处。首先,它使您的代码更清晰。从您的文档中检查该类的每个人现在都会看到该类依赖于传递给它的数据库对象。此外,您可以为您的连接定义一个接口,并将不同类型的连接传递到类中,只要它们实现该接口即可。如果您想稍后测试您的代码,这也很有帮助。这样你就可以简单地交换对象。总体而言,监督所有内容要好得多,因为您不必依赖全局状态来满足您在课堂上的需要。
【解决方案2】:

仅使用参考:

class test{
    private $myvar;

    //use __ or old syntax to your liking
    function test() {
        global $globalVariable;
        $myvar =& $globalVariable;
    }

    public function testing(){
        //Use $this->myvar

        // Do something
    }
    public function testing_two(){
        //USe $this->myvar

        // Do something
    }
}

【讨论】:

  • 引用已被弃用,不是吗?
  • @BenCarey:绝对不是。但是,您尝试实现的目标看起来特别错误,您应该修改您想要做的事情,因为必须有更好的东西。
  • @Ben:不,他们不是。不推荐在调用时传递引用:php.net/manual/en/language.references.pass.php
  • 恕我直言,如果此功能将消失,该判决仍然无法确定:我个人认为它是该语言的重要组成部分,而删除它将是一个致命的举动。其他人可能同意或不同意。 (谈论引用,而不是传递引用!)
  • 啊,我的印象是他们,抱歉。我很确定这个答案正是我想要的。但是,我可以不只是忘记引用并在构造中调用“global $globalVariable”,然后在方法周围使用 $globalVariable 吗?
【解决方案3】:

将该变量作为类的属性传递

class test
{
    private $globalVariable = '';

    public function testing()
    {
        $this->globalVariable = 'set-som-value';
    }

    public function testing_two()
    {
        $this->globalVariable = 'Do Extra Work';
    }
}

您可以使用 privatepublicprotected 来更改变量的可见性,其中 private 使变量只能在该类中访问, protected 使变量在扩展该特定类的类中可用,而 public 使变量可以从任何地方访问。

类外全局

global $globalVar;
$globalVar = 'SomeVal';

class test
{
    public function testing()
    {
        global $globalVar;
    }
}

【讨论】:

  • 感谢您的建议,但我没有足够详细地解释我想要实现的目标。 '$globalVariable' 是在类之外定义的,因此上述答案不相关。我的错,道歉。
  • 再说一次,这不是我想要的。我不想为每种方法调用“全局”。我希望整个班级都可以访问该变量。查看@dan 的回答
【解决方案4】:

这可能会有所帮助。我在课堂外有一个用于 mysqli 的 var。

             <?php
             $DB_NAME = 'database';
             $DB_HOST = 'host';
             $DB_USER = 'user';
             $DB_PASS = 'password';

             $linkID = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);

             if (mysqli_connect_errno()) {
                  printf("Connect failed: %s\n", mysqli_connect_error());
                  exit();
             }


             $Test = new Test($linkID);


                 class Test {

                     public $linkID;

                     function __construct($linkID){ $this->linkID = $linkID; }

                     public function new_mysql($sql) {
                         $result = $this->linkID->query($sql) or die($this->linkID->error.__LINE__);
                         return $result;
                     }

                     public function do_query() {
                         $sql = "SELECT `name` FROM `contacts`";
                         $result = $this->new_mysql($sql);
                         while ($row = $result->fetch_assoc()) {
                             print "Test $row[name]<br>";
                         }
                      }
                 }

         ?>

现在数据库详细信息作为助手传递给类。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多