保护对象属性,而不事先知道其名称

时间:2010-09-17 22:18:40

标签: php object properties

这可能是不可能的,但我认为在我重写整件事之前我会问:

我有一个可以接收“片段”的对象类,它们也是对象。它基本上是这样的:

class myObject {
    //Receives an associative array of "Piece" objects
    function __construct($objects) {
        foreach( $objects as $k=>$v ) {
            $this->{$k} = $v;
        }
    }
}

我明显省略了很多代码,但我希望这会给你一个想法。基本上我有很多不同的“片段”对象做不同的事情,如果我把它们的数组传递给myObject那么myObject就变成了一个非常灵活和有用的类来做各种不同的事情。

所以,我可以使用它来创建一个Book对象,并且包含一个包含“作者篇”和“ISBN片段”的部分,这些部分将知道如何验证数据等。所以我可能有$book将对象设置为成员变量authorisbn

这很棒,因为我可以做以下事情:

echo $book->author; //all Pieces have a __toString() method.
echo $book->author->firstName;
$book->author->showBio();
$book->author->contactForm();

......等等。

现在到了这一点。这个系统效果很好,其中一个很棒的东西就是我可以挑选任何我喜欢的作品并将它们粘贴到一个对象中以将它们绑定在一起。

但问题是,我不希望以后可能会使用该代码的其他人尝试:

$book->author = "John Doe";

...因为那时他们只有一个值而不是作者对象。我想要给他们一个错误,并指示他们这样做:

$book->author->setName("John Doe");

因为我事先并不知道任何单个对象中可能包含哪些部分(并且整个观点是能够自由地立即组装任何类型的对象),我不能只设置{{ 1}}在类声明中。

我尝试使用private $author__get()进行了一些愚弄,但是我无法在不牺牲对象功能的情况下使其工作。

所以,就像我说的,我知道这可能是不可能的,但在我放弃之前,我想我会问。有没有办法在创建对象后保护对象的属性而不在类定义中声明它?

1 个答案:

答案 0 :(得分:3)

这绝对不是不可能的。你应该覆盖魔术__get和__set函数

像这样:

class myObject {
  protected $data = array();

  public function __construct($objects) {
    foreach( $objects as $k=>$v ) {
      $this->data[$k] = $v;
    }
  }

  /* your code */

  public function __get($name) {
    if(array_key_exists($name, $this->data)) {
      return $this->data[$name];
    }
    return null;
  }