2013-08-08 7 views
5

誰でもこの現象で私に論理を説明できますか?奇妙な__set()魔法の機能

class EPPDomain 
{ 
    protected $myField; 

    public static function buildEPPDomain($fieldValue) 
    { 
     $me = new self(); 
     $me->myField = $fieldValue; 
     return $me; 
    } 

    public function __set($name, $value) 
    { 
     $this->$name = "prefix_".value; 
    } 
} 

class EPPDomainFactory 
{ 
    public static function buildEPPDomain($fieldValue) 
    { 
     $me = new EPPDomain(); 
     $me->myField = $fieldValue; 
     return $me; 
    } 
} 

ので

prefix_myValue 

実際

myValue 
を期待
$dmn = EPPDomain::buildEPPDomain("myValue"); 
echo $dmn->myField; 

は、次のような状況を考えてみましょう3210

アクセスできないプロパティにデータを書き込む際に明らかに、__set()

http://www.php.net/manual/en/language.oop5.overloading.php#object.set

に__set説明による

prefix_myValue 

を出力予想通り

$dmn = EPPDomainFactory::buildEPPDomain("myValue"); 
echo $dmn->myField; 

作品が実行されます。

EPPDomainクラスの静的メソッドでEPPDomainのインスタンスを作成すると、すべての保護されたプロパティにアクセスできなくなってしまいます。したがって__setが呼び出される必要がありますが、それは私はそれがまた、オブジェクトコンテキストでのみ作品の過負荷を

プロパティを言う知っ

ではありません。これらの魔方法 は、静的コンテキストではトリガされません。したがって、これらのメソッド は静的であると宣言されるべきではありません。 PHP 5.3.0以降、 のいずれかの魔法のオーバーロードメソッドが静的であると宣言された場合、警告が発行されます。

しかし、私は、__setメソッドはクラスメンバ関数であるべきであり、静的であってはならないと述べています。それはそれであり、私が直面している状況とは何の関係もないようです。

これはバグか予期される動作ですか?

+1

このコード例を簡略化することができれば、非常に有益です。それはあまりにもあなたのポイントを示すために巻き込まれています。 – deceze

+0

完了、申し訳ありませんが、私のコードははるかに複雑で、できるだけ簡略化しようとしていました。おそらく十分に頑張っていないでしょう。このバージョンは良く見えるはずです –

答えて

5

protectedプロパティが同じかクラスを継承して、すべてのコードにアクセスです。重点はクラスです。

class Foo { 

    protected $bar; 

    public function foo() { 
     $foo = new self; 
     $foo->bar = 'baz'; 
    } 

} 

これはうまくいきます。 クラスは、インスタンスで動作しており、独自のプロパティにアクセスできます。それは "外国人のインスタンス"についてではなく、それはクラスについてです。

保護されたプロパティのポイントは、その存在または実装がそれらを定義するクラスにのみ関連する必要があることです。他のコードで直接それらを混乱させるべきではありません。クラスはそれ自身のプロパティをどのように扱うかを知っていると考えることができるので、クラスは、その型のオブジェクトのプロパティを操作するために信頼されます。

+1

いいえ、オブジェクトが同じクラスに属する静的ファクトリメソッドで作成されていても、プライベート/保護されたプロパティにはまだアクセスできないことに気づいていませんでした。効果的には、開発者は異なるクラスのファクトリメソッドを持つ必要があります。これを指摘していただきありがとうございます –

0

メソッドはそのクラスのインスタンスの保護された(さらにはプライベートな)プロパティにアクセスできるため、これは正常な動作です。