Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

__staticCallじゃなくて__callStatic

がっ!逆かよ!


> Etienne Kneuss provided me a patch to handle static called class methods
> properly - it works fine. Now i need antother patch for:
>
> __static_call_patch
> __static_set
> __static_get
>
> where can i find it?
>
__staticCall() is already in PHP6. __staticGet/Set/Isset/Unset don't
exist (yet).

これがあったので、ずっと__staticCallとばかり思ってましたが。確かに「フツーはcall staticじゃね〜の?」みたいなフォローがあったのは覚えてたんですが。。。orz
まあ、PHP6から新しいマジックメソッド「__callStatic」が追加される、という話です。で、PHP6-devと先ほどのPHP5.3で試したところ、両者とも動作しました。ポイントとしては、

  • メソッド名は「__staticCall」じゃなくて「__callStatic」
  • 当然、staticメソッドとして定義する

といったあたりです。以下のサンプルは、PHP: オーバーロード - Manualの「__call を使ったオーバーロードの例」に追記したものです。

<?php
class Caller
{
    private $x = array(1, 2, 3);
    private static $y = array(4, 5, 6);

    public function __call($m, $a)
    {
        print "Method $m called:\n";
        var_dump($a);
        return $this->x;
    }

/**
    public static function __staticCall($m, $a)
    {
        print "Static method $m called:\n";
        var_dump($a);
        return $this->x;
    }
*/

    /**
     * this method name '__callStatic' is case-insensitive,
     */
    public static function __callStatic($m, $a)
    {
        print "Static method $m called:\n";
        var_dump($a);
        return self::$y;
    }
}

$foo = new Caller();
$a = $foo->test(1, "2", 3.4, true);
var_dump($a);
echo '<hr>';

$a = Caller::test(5, "6", 7.8, true);
var_dump($a);
echo '<hr>';

$a = $foo::test(9, "0", 1.2, true);
var_dump($a);
echo '<hr>'; 

なお、実際の動作は以下からどうぞ。