2012-02-27 3 views
4

PHPクラス(v5.3.8)でこの奇妙な動作が見つかりました。あなたが持っている__callStatic()を非静的メソッドからトリガーする奇妙な動作

class foo { 
    function __call($func, $args) { 
    if ($func == 'bar') 
     echo "non-static __call"; 
    } 

    static function __callStatic($func, $args) { 
    if ($func == 'bar') 
     echo "__callStatic"; 
    } 

    function callMe() { 
    self::bar(); 
    } 
} 

は、次に、あなたが実行します。

foo::bar() // outputs '__callStatic' as expected. 
$f = new foo; 
$f->callMe(); // outputs 'non-static __call', as I did not expect. 

あなたが見る、非静的関数から呼び出さ存在しない静的メソッドは、__call()代わりの__callStatic()をトリガします。私はこれがこのように動作するはずか、これは何らかのバグですか?

[EDIT]

私はcallMe()static::bar();をしようとするのを忘れたが、いや、それはどちらか動作しませんでした。

私はinhanのコメントを理解していますが、それでもなおインスタンスやオブジェクトではなくクラスそのものを呼び出すと、即座に論理が__callStatic()を起動する必要があると言います。しかたがない。

あなたの回答/コメントありがとうございます。

+1

PHPには、これらの奇妙な振る舞いの巨大な山があります。:/マニュアルには、静的な*コンテキスト*でアクセスできないメソッドを呼び出すと__callStaticがトリガされると記載されています。確かにそれほど意味をなさない。それは全く直感的ではありません –

+2

'callMe'は**非静的関数**です(オブジェクトスコープ内にあります)。存在しないメソッドを呼び出していても、オブジェクトインスタンス自体を扱っているので、 __call'が実行されます。 – inhan

+0

しかし、それは変です。 'self :: bar();'を 'foo :: bar()'に変更すると、静的呼び出しであっても非静的に呼び出されます。 – webbiedave

答えて

3

あなたはこれらの事は、クラスメソッドのコンテキスト内から何を意味するかによって混同される可能性があります「fooという名前の静的メソッドを呼び出す」を意味

class B extends A { 
    public function test() { 
    A::foo(); 
    self::foo(); 
    static::foo(); 
    } 
} 

なしこれらのこれは単に、コロンの残っているものによって指定された継承ツリーの場所で、 "fooという名前のメソッドを呼び出す"ことを意味します。

通常、マジックなしでは、fooという名前の関数が1つしかないので、意味は簡単です。しかし、の両方でという魔法の方法でオーバーロードすると、の曖昧なメッセージが呼び出されます。 PHPのデフォルト値は、__callStatic()の前に__call()です。

1

静的メソッドでは、変数はオブジェクトではないクラスに属しているので、これはこのように動作するはずです。

+0

huh?もう少し説明できますか?私は接続が表示されません –

+0

いくつかの説明:http://en.wikipedia.org/wiki/Method_(computer_programming)#Class_methods –

+0

あなたは* me *に説明する必要はありません。だから、もう一度、なぜこのように動作すると思われるのですか? –

関連する問題