18

我对 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()violates还是conforms语言结构的大图。或者它完全是一种新的语言结构。

4

3 回答 3

17

__callStatic()为开发人员提供了对方法调用做出反应的可能性,static即使该方法不存在无法从类外部(being 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;                      
        }

    }

}

尝试调用:

// these ones does not *really* exist
Test::foo('bar');
Test::helloWorld('hek2mgl');

// this one wouldn't be accessible
Test::myProtected('foo');
于 2013-11-07T16:16:21.290 回答
4

为什么这样做?

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

你能在其他地方做类似的事情吗,比如 C++ 或 Java?

不,他们没有类似的魔法方法。

我正在寻找关于语言中的静态和动态函数的简短且内容丰富的解释

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

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

它是一种动态语言的构造。不确定此功能是否存在于所有动态语言中,但它存在于 PHP 中。它没有违反任何内容,只是在您调用的函数在当前范围内不存在/不可访问时引入了贯穿全能函数的新范例。

于 2013-11-11T22:01:00.067 回答
1

我不完全确定为什么 __callStatic() 在这里相关?

我不太明白两者之间的区别:

class Foo {

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

  function quux() {
    return "whatever";
  }

}

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

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

你知道__call吗?它与 __callStatic 做同样的事情,但用于对象而不是类。例如 $foo->myMissingMethod(); 如果 $foo 是其实例的类存在这样的方法,则将转到 __call。

于 2013-11-07T16:40:19.680 回答