具有普通和静态接口的类

时间:2014-04-01 14:12:15

标签: php class

我需要一个允许用户利用普通(非静态)方法和静态方法的类。实际的实现将驻留在静态方法中,静态方法将通过魔术__call方法由同名的虚拟非静态方法调用。但问题是,当以这种方式调用非静态方法时,PHP认为程序员犯了一个错误,而静态方法实际上是要调用的:

class AClass
{
    public static function method ()
    {
        // implementation
    }

    public function __call ($name, $arguments)
    {
        var_dump("Hello");
        call_user_func_array("AClass::$name", $arguments);
    }
}

$obj = new AClass;
$obj->method();

因此,在对象上调用method方法时,不会输出“Hello”,但是在尝试调用具有任何其他名称的方法时正在输出。在保留方法命名的同时实现正确行为的任何方法?

1 个答案:

答案 0 :(得分:1)

我真的不明白为什么你会尝试这样做,但这似乎有效:

class AClass
{
    protected static function method ()
    {
        echo "method()\n";
    }

    public function __call ($name, $arguments)
    {
        echo("Hello normal\n");
        call_user_func_array("self::$name", $arguments);
    }

    public static function __callStatic($name, $arguments)
    {
        echo("Hello static\n");
        call_user_func_array("self::$name", $arguments);
    }
}

$obj = new AClass;

// Normal call
$obj->method();

// Static call
AClass::method();

输出:

Hello normal
method()
Hello static
method()

就其文档而言,只有在函数无法从您调用它的上下文中访问时才使用__call方法。

因此,在您的情况下,该功能是公共的,因此无需使用它(即使使用某些设置也会显示警告)。

如果你做到了#34;受保护"或者"私有",它不能从外部调用,然后使用__call。

因为__call并不关心静态调用,所以如果仍然需要从类外部调用AClass :: method,则还必须使用__callStatic(在PHP> = 5.3中可用)。