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();
...

私は通常、マジック メソッドを使用せずにゲッターとセッターを作成します。これはクイック ガイドで見たことがありますが、なぜこれが必要なのかわかりません。

誰でも私を助けることができますか?

どうもありがとう

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

「独自の」ゲッターとセッターを作成する場合は、プロパティごとに と の 2 つの関数を作成することになりgetPropname()ますsetPropname。PHP の「マジック メソッド」セッター/ゲッターを使用すると、プロパティごとに個別のメソッドを記述する必要がなくなります。プロパティを public であるかのように設定/取得できます。オーバーロード関数内で、各プロパティに固有のロジックを追加します。例:

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->commentsこれで、set または getを使用してコメントにアクセスできるようになりました。

オーバーロードを使用せずに上記の機能を実現するには、代わりに 4 つの異なるメソッドを記述する必要がありました。これは、実際のファイルの観点からも、プロジェクト内のオブジェクトの標準化されたインターフェイスを作成するという観点からも、コード編成に関するものです。

私は個人的には、複雑なゲッター/セッターが必要なプロパティごとに個別のメソッドを作成して、あなたと同じようにすることを好みます。私には、それはより明確に整理されており、オブジェクトの「単純な」プロパティと、より複雑または一対多の関係を持つプロパティとの間に明確な分離があります。

于 2011-04-25T16:25:27.637 に答える
1

__getおよび__setマジック メソッドが存在する理由は2つあります。

  1. すべてのプロパティのバニラ アクセサー メソッドの作成に時間を費やす必要がないようにします。

  2. プロパティのオーバーロードを実装できるようにします。

特別な処理が必要なプロパティがある場合、魔法のメソッドは適していません。ただし、プロパティにデータが含まれているだけで依存関係がない場合は、魔法のメソッドを使用しない理由はありません。

于 2011-04-25T16:19:48.973 に答える
1

__get()さらにチュートリアルでは、 andメソッドを変更して__set()、それらが存在する理由を確認します。

このような魔法の処理を行うことで、「読み取り専用」プロパティを作成するなどのきちんとしたことを行うことができ、ゲッター/セッターの乱雑な負荷でクラスが肥大化するのを防ぐことができます。

于 2011-04-25T16:21:45.610 に答える
0

__set子クラスのセッター機能を使用してオーバーライドしたい場合は、問題が発生します。__set1つの特定のセッター関数を単に上書きするのではなく、コード全体をコピーして特定の部分のみを変更する必要があります->冗長なコード

setterこの問題は、特定のinを呼び出すことで回避できます(ヒントについてはcHao__setに感謝します)。

例:

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 に答える