【问题描述】:

这可能很简单,但我无法弄清楚如何为 Google 提出问题,所以这里是:

所以,我经常做这样的事情……

class foo {
    private $bar = array();
}

... 将某些类属性设置为数组。但是,我想将私有属性改为对象,如下所示:

class foo {
    private $bar = new stdClass();
}

我尝试了几种变体,但都没有奏效。这可以做到吗?对于奖励积分,您可以将私有属性分配为任何其他类别的对象吗?

谢谢!

【问题讨论】:

    标签: php class object properties private


    【解答1】:

    您不能在类成员声明中使用函数(包括构造函数)。而是在类的构造函数中设置它。

    class Foo {
    
      private $bar;
    
      private $baz;
    
      public function __construct() {
    
        $this->bar = new stdClass();
        $this->baz = new Bat();
    
      }
    
      public function __get($key) {
          if(isset($this->$key) {
            return $this->$key;
          }
    
          throw new Exception(sprintf('%s::%s cannot be accessed.', __CLASS__, $key));
      }
    
    }
    
    
    $foo = new Foo();
    
    var_dump($foo->bar);
    var_dump($foo->bat);
    

    当你扩展类并且需要重写构造函数但仍然想要父类构造函数中的东西时:

    class FooExtended
    {
       protected $coolBeans;
    
       public function __construct() {
    
          parent::__construct(); // calls the parents constructor
    
          $this->coolBeans = new stdClass();
       }
    }
    
    $foo = new FooExtended();
    
    var_dump($foo->bar);
    var_dump($foo->bat);
    var_dump($foo->coolBeans);
    

    还应注意,这与属性的可见性无关...无论其 protectedprivate 还是 公开.

    【问题讨论】:

    • 好的,这行得通。但是,如果我希望这个类可以被其他可能覆盖构造函数的类扩展呢?有没有办法确保 $bar 保持对象?
    • 查看我的笔记编辑...并查看类和对象手册:php.net/manual/en/language.oop5.php
    • 感谢扩展示例,我知道你是怎么做到的。我希望您可以简单地将某些东西声明为对象,就像您可以将其声明为数组一样。这将使我能够更好地“防止”代码:我不喜欢要求用户调用父构造函数,因为他们似乎总是忘记并且无法弄清楚为什么事情不工作。然而,有时你必须做你必须做的事。感谢您的帮助!
    • 大多数人会知道这样做...如果他们不知道,那么他们就不太了解 OOP PHP,所以这不是你的错 :-) 此外,如果你可以添加创建对象的 getter它还没有初始化...
    • 当你扩展父类时,所有子类都应该得到你的stdclass对象,如果你不想让其他人覆盖它,你可以在父类中声明它为私有,然后使用“对象变量的 getter 和 setter 的 final" 关键字,因此 $bar 将保留为对象,希望这会有所帮助。