__callStatic():从静态上下文实例化对象?

时间:2013-11-07 16:11:59

标签: php static instantiation magic-methods

我很困惑PHP中的“静态”和“动态”函数和对象如何协同工作,特别是关于__callStatic()。

  

__callStatic()如何运作:

     

你可以拥有一个普通的MyClass类,你可以在类中找到它   放一个名为__callStatic()的静态函数,只调用它   当MyClass没有你想要的名字的静态功能。

     

即。我打电话给MyClass::newFunction();

     静态调用

newFunction()MyClass没有   宣布它。那么,然后__callStatic()被调用   在里面你可以说

$myObject=new SomeOtherClass();
$myObject->newFunction();
     

调用你想要的功能但是在其他一些对象上。

简短版本:

换句话说,__ callStatic()执行此操作:

MyClass::newFunction();

隐藏了这个:

(new SomeOtherClass())->newFunction();

现在说什么?从类中调用静态函数的代码看起来就是从其他类调用该函数并通过实例化调用它,而不是静态调用。

请解释一下!

为什么要这样做?你可以在其他地方做这样的事情,比如C ++或Java吗?我正在寻找短期&关于语言中静态和动态函数的简明但有用的解释,在这种情况下,__callStatic()violatesconforms是否构成了语言结构的大图。或者它完全是一种新的语言结构。

3 个答案:

答案 0 :(得分:10)

__callStatic()为开发人员提供了对static方法调用做出反应的可能性,即使这些方法不存在也无法从类外部访问(正在{ {1}})。这对动态通用代码生成很有用。


示例:您有这个类:

protected

尝试致电:

class Test {

    protected static function myProtected($test) {
        var_dump(__METHOD__, $test);
    }

    public static function __callStatic($method, $args) {
        switch($method) {
            case 'foo' :
                echo 'You have called foo()';
                var_dump($args);
                break;

            case 'helloWorld':
                echo 'Hello ' . $args[0];
                break;

            case 'myProtected':
                return call_user_func_array(
                    array(get_called_class(), 'myProtected'),
                    $args
                );
                break;                      
        }

    }

}

答案 1 :(得分:3)

  

为什么要这样做?

这是一个存在主义的问题,但我认为答案是“因为你可以”。 PHP是一种动态语言,这些结构__call__callStatic()展示了它的强大功能,这种功能在某些情况下非常有用。

  

你可以在其他地方做这样的事情,比如C ++或Java吗?

没有。他们没有类似的魔术方法。

  

我正在寻找短期&关于语言中静态和动态函数的简明但有用的信息

静态函数封装代码。即使没有实例化类,它们也存在。您可以使用范围解析运算符来调用它们。 动态功能很好,动态

  

.. __callStatic()违反或符合语言结构的大图。或者它完全是一种新的语言结构。

它是动态语言的构造。不确定所有动态语言中是否存在此功能,但它确实存在于PHP中。它没有违反任何内容,只是在您调用的函数不存在/当前范围内无法访问时引入了直通catch-all函数的新范例。

答案 2 :(得分:1)

我不完全确定为什么__callStatic()与此相关?

我不太明白:

之间的区别
class Foo {

  static function bar() {
    $obj = new Foo();
    $obj->quux();
  } 

  function quux() {
    return "whatever";
  }

}

和你的榜样?在这两种情况下,您都在调用一个静态方法,该方法在同一个类的对象上调用另一个方法。

是的,那是可能的。实际上这样做表明你可能想要重构你的代码。在该示例中,您将使用其默认状态实例化对象,在其上执行方法然后将对象抛弃。这表明无论方法做什么,实际上并不需要对象状态。这意味着它要么不属于这个类,要么可以简单地重写为静态方法本身。

你知道__call吗?它与__callStatic的作用相同,但是对象而不是类。例如。 $ foo-> myMissingMethod();如果$ foo是一个实例的类存在这样的方法,那么会转到__call。