0

次のコードがあるとします。

class SomeClass{

    private $somePrivateField;


    public function __get($name){
        $function = "get".ucfirst($name);
        return $function;
    }

     public function __set($name,$value){
        $function = "set".ucfirst($name);
        return $function($value);
    }

    public function __call($name, $arguments) {
        //if function being called is getSomething
        //getThat private/protected field if exists and return
        //if not raise exception

        // similar for setSomething...
    }

}

これは、いくつかのチュートリアルからの一節です。

__get() メソッドは、設定されるプロパティの名前を表す引数を受け入れます。$obj->property の場合、引数はプロパティになります。

次に、__get() メソッドはこれを getProperty に変換します。これは、__call() メソッドで定義したパターンと一致します。これが意味することは、$obj->property は最初に同じ名前のパブリック プロパティを設定しようとし、次に __get() に移動し、次にパブリック メソッド setProperty() の呼び出しを試み、次に __call() に移動し、最後に保護された $_property を設定します。

だから、コードのどこかで言うと

$obj->property

最初に public フィールドにアクセスしようとしたことは理解できます.なぜ最初に __get() に行くのですか? なぜ __set() ではないのですか? では、なぜ __set() に行くのでしょうか?

誰か説明してくれませんか?ありがとう...

4

1 に答える 1

1
  • __get()おそらく存在しない関数の名前を含む文字列のみを返します。
  • __set()実際にそれが構築する名前の関数を呼び出しますが、その理由を特定するのに苦労しています...
  • __call()呼び出している関数が実際に「セッター」または「ゲッター」関数であるかどうかを判断する必要があるように見えます。これは、そもそものポイント全体__get()です__set()
  • $obj->property実際にはそれ自体では何もしない無意味なコードの断片です。
// assuming $obj->property is declared as private, or does not exist in the class.

$var = $obj->property; // invokes __get('property')

$obj->property = $var; // invokes __set('property', $var)

$obj->someFunction($var1, $var2, ...);
// invokes __call('someFunction', array($var1, $var2, ...)), but only if
// the specified function is private, or otherwise does not exist.

サンプル コードを書き直して、ある程度意味のあるものにするには、次のようにします。

class SomeClass{

    private $somePrivateField;

    public function __get($name){
        if( isset($this->$name) ) {
            return $this->$name;
        } else {
            Throw new Exception("Object property $name does not exist.");
        }
    }

     public function __set($name,$value){
        if( isset($this->$name) ) {
            $this->$name = $value;
        } else {
            Throw new Exception("Object property $name does not exist.");
        }
    }
}
$obj = new SomeClass();
$obj->somePrivateField = $var; // uses __set()
$var = $obj->somePrivateField; // uses __get()

allを使用__call()する必要はめったにありません。この例では確かにそうではありません。

または、最初に明示的に宣言することなく、プライベート/パブリック プロパティを設定/取得できるようにしたい場合:

class SomeClass{

    private $properties = array();

    public function __get($name){
        if( isset($this->properties['name']) ) {
            return $this->properties['name'];
        } else {
            Throw new Exception("Object property $name does not exist.");
        }
    }

     public function __set($name,$value){
        $this->properties[$name] = $value;
    }

    // it's also a good idea to define __isset() and __unset() in this case as well
    public function __isset($name) {
        return isset($this->properties['name']);
    }

    public function __unset($name) {
        return unset($this->properties['name']);
    }
}
于 2013-01-30T19:56:07.047 に答える