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

问题描述 投票:12回答:3

我很困惑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都是语言结构的大图。或者它完全是一种新的语言结构。

php static instantiation magic-methods
3个回答
10
投票

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

3
投票

为什么这样做?

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

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

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

我正在寻找关于语言中静态和动态函数的简短而详细的解释

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

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

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


1
投票

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

我不太看到以下区别:

class Foo {

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

  function quux() {
    return "whatever";
  }

}

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.