6

Javaから来たので、私はPHPに休暇で数回しか訪問していません。魔法のgetメソッドとsetメソッドを見ると、私の(Javaの影響を受けた)おなかが痛くなり始めています。プロパティに直接アクセスしているように見えます(もちろん、実際には__getと__setを使用しています)。

つまり、作成する必要のあるコードが少ないことを除いて、従来のgetX()/ setX()メソッドの代わりにマジックゲッターメソッドとセッターメソッドを使用することに利点はありますか?PHPをコーディングするときにそれらを使い始める必要がありますか?

ありがとう、そして最高!

4

7 に答える 7

2

の唯一の利点は__get()コードが少なくて済むことですが、それでも必ずしもそうとは限りません。たとえば、10 個のプライベート メンバーのセットがあり、getter に 5 個を公開させたい__get()場合、疑似可視メンバーの 1 つが呼び出された場合に送信するように記述する必要があります。それ以外の場合は、エラーを発行するか (エラーがなくても自然に発生するか、実際には役に立たない__get()ような値を返します。null

ゲッターとセッターを一般的に使用することを提案する人を非難する必要があります。これは通常、アーキテクチャに問題があることを示しています。たとえば、次の 2 つのコード ブロックの概念的な違いを説明してください。

class _ {
   public $_;
}

対。

class _ {
   private $_;
   public function get_() {
      return $this->_;
   }
}

違いはありません。

ただし、getter を使用することの利点として、多くの人が指摘するように、これにより、何らかの方法で戻り値を透過的に変更して、受信者に役立つようにすることができます。ただし、アーキテクチャの問題に戻ります。何らかの理由でクラスの内容を公開する必要はまったくありません。代わりに、アクションを実行するようにクラスに指示する必要があります (状態によって異なる場合があります)。ゲッターを使用すると、通常、クラスの状態を照会し、表示された状態に基づいて外部でアクションを実行できます。

セッターとセッターに対して本質的に同じ議論__set()がありますが、あなたができる素晴らしいことが1つあり__set()ます:

class _ {
   private $_ = array();
   public function __set($key, $val) {
      $this->_[$key] = $val;
   }
}

これにより、とても素敵な$_obj->key = 'val'. これと大きな違いはなくadd()、キーと値を取り、同じことを行うような別のメソッドを追加することに注意してください。私はオブジェクトセッター表記を好みます。

于 2011-07-17T15:52:27.163 に答える
1

__get__そして__set__完全に動的です。たとえば、遅延読み込みを有効にするために呼び出された場合、データベース要求を開始できます。もちろん、ゲッターとセッターでもこれを行うことができますが、そうすると毎回これを行う必要があります。すべてのプロパティ呼び出しが 1 つのメソッドを介して渡されるため、AOP のようなこともできます。したがって、全体として、__get__/__set__処理にかかる時間に対してより柔軟に対応できます。あなたはそれを使って本当に高度でクールなことをすることができます。

于 2011-07-17T15:45:59.677 に答える
1

利点は、リファクタリングの際に、コードベース全体をすぐに変更する必要なく直接の割り当て/読み取りを処理できること、コードを多少短くすることができること、文字列をより簡単に作成できることです (例: $title="<title>{$obj->title}</title>";vs. $title='<title>'.$obj->getTitle().'</title>';.

ただし、__get&__setメソッドはかなり急速に大きくなり扱いにくくなる可能性があり、適切に & 明示的にコーディングする場合は、明示的なset/getX()メソッドを使用して明確な関数が呼び出されるようにする方が良いと思います。コードの冗長性のわずかな増加は、私の限りです実際に関数を呼び出しているものとそうでないものを簡単に確認できるため、懸念は正当化されます。考えられる例外は、別のクラス/オブジェクトのデコレーターを構築している場合ですが、それだけです。

于 2011-07-17T15:47:11.453 に答える
1

__set()ゲッター メソッドとセッター メソッドとメソッドの違いはほとんどありませ__get()ん。これらは魔法の方法です! __set()未定義状態をオブジェクトに割り当てたいときに__get()使用し、未定義状態の値を取得するためにも使用します! セッターとゲッターは、定義された状態の値を割り当てまたは取得するために使用されます

于 2011-07-17T15:49:14.553 に答える
0

各属性に対して getX()/setX() を記述する場合、実際には、少なくとも 7 行のコードが必要です。これは、メソッドの開始ブレースが定義と同じ行にあり、メソッドに 1 行のコードを挿入するだけで、終了ブレースが独自の行にあることを前提としています。

重要なオブジェクトの場合は、これに 6 を掛けます (YMMV)。これは、属性アクセス/変更のためだけに 42 行です。これには、入力の検証や正規化は含まれません。別の方法については、 https ://github.com/metaphp/attributes を確認してください。

于 2012-07-30T04:18:31.900 に答える
0

動的プログラミングにはオーバーヘッドがあります (たとえば、魔法のメソッドを使用する)。古いベンチマーク:ベンチマークの魔法

PHP は動的な (そして完全なエンタープライズではない) 言語であるため、多くの場合 (デバッグ、スケーラビリティ、エラーの削減などのために)コード行を減らして数ナノ秒を逃すことは良い考えのようです。

于 2014-02-08T08:29:29.030 に答える
0

書かなければならないコードが少ないことを除いて、従来の getX()/setX() メソッドの代わりに魔法の getter および setter > メソッドを使用する利点はありますか? PHPをコーディングするときにそれらを使い始める必要がありますか?

書くコードが少ないことを考えると、すでにそれらを使い始める強力な理由になっています。
もう 1 つの理由は、すべてのゲッター/セッターに共通の動作を追加できることです。

function __set() {
   //> Do some code in common between all setter

   //> set your var here
}
于 2011-07-17T15:52:30.527 に答える