7

在 Zend 快速入门指南http://framework.zend.com/manual/en/learning.quickstart.create-model.html我们可以看到:

class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;

    public function __set($name, $value);
    public function __get($name);


    public function setComment($text);
    public function getComment();
...

我通常不使用任何魔术方法来创建我的 getter 和 setter。我在快速指南上看到了这个,我不明白为什么我们需要这个。

谁能帮我吗?

非常感谢

4

5 回答 5

10

你(通常)从不打电话__set__get直接打电话。如果不可见且存在,$foo->bar将自动调用。$foo->__get('bar')bar__get

在您链接到的教程中,getter 和 setter 被设置为自动调用适当的单个 get/set 函数。所以$foo->comment = 'bar'会间接调用$foo->setComment('bar')。这没有必要……这只是一种方便。

在其他情况下,__get创建看起来像只读变量的内容可能很有用。

于 2011-04-25T16:24:13.610 回答
9

如果您“制作自己的”getter 和 setter,您将为每个属性制作两个函数:getPropname()setPropname. 通过使用 PHP 的“魔术方法”setter/getter,您不必为每个属性编写单独的方法。您可以设置/获取属性,就好像它们是公共的一样。在重载函数中,您添加特定于每个属性的逻辑。例子:

public function __set($name, $value) {
 switch ($name) {
   case 'comments':
     // do stuff to set comments
     break;
   case 'parent_user':
     // do stuff to set parent user
     break;
 }
}
public function __get($name) {
 switch ($name) {
   case 'comments':
     // do stuff to get comments
     break;
   case 'parent_user':
     // do stuff to get parent user
     break;
 }
}

现在我可以使用$obj->commentsset 或 get 来访问评论。

要在不使用重载的情况下实现上述功能,我将不得不编写 4 种不同的方法。这实际上更多的是关于代码组织,无论是在实际文件方面,还是在为项目中的对象创建标准化接口方面。

我个人更喜欢像你一样为我需要复杂的 getter/setter 的每个属性编写单独的方法。对我来说,它的组织更清晰,对象的“简单”属性与具有更大复杂性或一对多关系的属性之间有明显的区别。

于 2011-04-25T16:25:27.637 回答
1

__get和魔法方法的__set存在有两个原因:

  1. 这样您就不必花时间为所有属性创建 vanilla 访问器方法。

  2. 允许您实现属性重载。

如果您有需要特殊处理的属性,那么魔法方法不适合您。但是,如果您的属性仅包含数据并且没有依赖关系,那么没有理由不使用魔术方法。

于 2011-04-25T16:19:48.973 回答
1

在本教程的进一步内容中,您可以修改__get()__set()方法,以便您了解它们为何存在。

拥有这样的魔法处理可以让你做一些简洁的事情,比如甚至制作“只读”属性,并且可以防止你的类因一堆杂乱的 getter/setter 而臃肿。

于 2011-04-25T16:21:45.610 回答
0

当您使用__set并想要覆盖子类中的设置器功能时,您会遇到问题。您必须复制整个代码__set并仅更改特定部分,而不是简单地覆盖一个特定的 setter 函数 -> 冗余代码

这个问题可以通过调用特定setter的 in来避免__set(感谢cHao的提示)。

例子:

class Foo1 {
   protected $normal;
   protected $special;

   public function setSpecial($special) {
      if ($special == isReallySpecial()) {
         $this->special = $special;
      }
   }

   public function __set($key, $value) {
      switch ($key) {
         case 'normal':
            $this->normal = $value;
            break;
         case 'special':
            $this->setSpecial($value);
      }
   }
}

class Foo2 extends Foo1 {
   public function setSpecial($special) {
      if ($special == isNotReallySpecial()) {
         $this->special = $special;
      }
   }
}
于 2012-12-05T20:05:25.060 回答