3

Matt Zandstraは、彼のテキスト「PHP Objects Patterns and Practice」で、__ get()メソッドを説明するために次の例を示しています。

class Person {
    function __get( $property ) {
        $method = "get{$property}";
        if ( method_exists( $this, $method ) ) {
            return $this->$method();
        }
    }
    function getName() {
        return "Bob";
    }
    function getAge() {
        return 44;
    }
}

実際には、そのような静的な値を返すためにそのようなメソッド(getNameおよびgetAge)を実際に作成することは決してないことはわかっていますが、代わりに、オブジェクトにnameプロパティとageプロパティを作成し、$this演算子を使用してそれらを返します。

私の質問は、この例が実際に有用性を示しているかどうかです。そうでない場合、誰かが同じ種類の目的で__get()を使用する理由のより良い例を提供できますか?

尋ねる理由

オブジェクトでnameプロパティとageプロパティを使用する場合、これらのプロパティを次のように取得しようとするため、__ get()関数は実行されません。

$person = new Person();
$name = $person->name;

nameプロパティがパブリックの場合は実際に返されるか、プライベートまたは保護されている場合は可視性エラーが発生します。__get()関数は、これらの「実際の」ケースのいずれでも実行されません...何かが足りませんか?

上記のコードが機能することを十分に認識しています。私はそれが実際的な例であるとは確信していません。

4

4 に答える 4

1

あなたは絶対に正しいです-あなたが本から引用していることに感銘を受けました.その例はただひどいです.

__getメソッドを呼び出すために魔法のメソッドを使用するのは間違っています。そのような使用法のための魔法のメソッドが他にもあります。

  • __call()
  • __callStatic()
  • __invoke()

__get()宣言されていないオブジェクトプロパティの__set()読み取りと書き込みに使用する必要があります。

于 2011-04-27T23:07:35.703 に答える
0

php.netの状態として

「__get() は、アクセスできないプロパティからデータを読み取るために使用されます。」

これは、__get()(定義されている場合) 存在しない、または非公開/保護されているプロパティにアクセスしようとするたびに呼び出されることを意味します。上記の例は、誰かが値を取得しようとするたびにアクセサー (ゲッター) を呼び出すことによって、これらのプライベート プロパティの値を取得する方法を示しています。

たとえば、

echo $a -> publicPropery or echo $a -> getPublicProperty()

同じ結果になります。ただし、 $a -> privateProperty を呼び出すと、エラーが発生し、

$a -> getPrivateProperty() 

大丈夫でしょう。

ただし__get()、を呼び出すたびにを定義すると$a -> privateProperty__get()が実行され、 にリダイレクトされ$a -> getPrivateProperty()ます。この場合、常に値を取得することに成功し、セキュリティを念頭に置きます。さらに、プロパティ ゲッターの存在をチェックするため、__get()誰かが存在しないプロパティにアクセスしようとすると、適切なエラーを表示したり、例外をスローしたりできます。これにより、php の可視性エラーが上書きされます。

于 2011-04-27T23:18:57.487 に答える
0

魔法のメソッドの実際の機能は、開発者が適切と考える方法で処理するかどうかに完全に任されています。違いは、それらが呼び出される方法にあります。

$obj->property; // invokes __get(), if defined
$obj->method(); // invokes __call(), if defined
$obj(); // invokes __invoke() if defined (php 5.3+)

__get()など。したがって、内部でメソッドを呼び出したい場合は、できます。どのように処理するかは、アプリケーションをどのように設計するかに完全に依存します。

について__get()、 public メンバーを持っていて で呼び出そうとすると、 は起動し->ませ__get()ん。ただし、アクセスできないメンバー (保護されている、プライベート、または存在しない) にアクセスしようとすると、__get()発生し、好きなように処理できます。

__get()少なくとも php によると、主な目的はすべてのメンバーに対してゲッターを記述する必要をなくすことであると私は理解しています。__set()セッターの場合と比較してください。ここでは深入りしたくありませんが、getter/setter を使用することは、設計に関して警告を発するべきだと思います。ただし、__get()アプリケーションを開発する側の基準を除いて、その使用目的に固執する必要はありません。

使用方法の 2 つの例は__get()、インスタンス化時に (たとえば DB クエリによって) 必要とされない可能性があるプロパティを初期化し、オーバーヘッドを削減することです。別の可能性としては、プロパティが配列に格納されている場合、魔法の get が要求されたプロパティのキーにマップされた値を返すことがあります。

php マジック関数を使用すると、いくつかの非常に優れた処理を行うことができ、これらの特別な呼び出しを使用して、より拡張可能なコードを作成できます。私がやりたいこと:

class application {
   public function __call($_, $_) {
      throw new Exception("PUT and DELETE not supported");
   }
   public function POST() {
      //update data
      header("Location: $_SERVER[PHP_SELF]", true, 303);
   }
   public function GET() {
      //display data
   }
   public static function inst() {
      return new self;
   }
}

application::inst()->$_SERVER['REQUEST_METHOD']();

もちろん、これは__call()ではなくを使用して__get()いますが、原理は同じです。この場合、それは単なる健全性チェックです。

于 2011-04-27T23:28:09.850 に答える
0
    <?php
        class data {
            public $name="Ankur DalsaniYa"; \\ I wont to change name

            public function __get($var) {
                print "Attempted to retrieve '<b>$var</b>' and failed...\n";
                //$var is print the Unknown and Not Define but call variable print  
            }
        }

        $data = new data;
        echo "<br> Not Define Variable Call : ";
        print $data->title; // Not Defined variable Call then call __get function
        echo "<br><br> Define Variable Call : ";
        print $data->name;  // Define variable Call then Not call __get function
    ?>
于 2015-07-14T17:46:43.767 に答える