PHP - 使用静态方法动态扩展父 class

PHP - dynamically extend parent class with static methods

考虑以下因素:

class A
{
    public static function bark()
    { echo 'woof'; }
}

class B extends A
{
    public static function speak()
    { echo 'hello'; }
}

A::speak();

// Fatal error: Call to undefined method A::speak()

如何使用您需要在 class 中全局可用的方法扩展 class 以及未知但在 运行 处加载的方法-时间,取决于您的应用程序流程?

是的,我们可以制作 traits 并将 use 放在 class 中,例如:

trait B
{
    public static function speak()
    { echo 'hello'; }
}

class A
{
    use B;
    public static function bark()
    { echo 'woof'; }
}

A::speak();

// hello

有没有人知道如何以干净的方式完成此操作?我的意思是我通过使用单例、命名空间、回调和作品看到了一些令人印象深刻的方法,但在每种情况下,它都需要比真正需要的更多的代码和重复编程。 要么,要么我完全错过了船哈哈! 提前致谢,我们将不胜感激并慷慨投票。

我认为只要发挥一些创造力,您就可以使用 __call 魔术方法。 你可以这样做:

class A
{
    /**
     * @var array
     */
    protected $methods = [];

    public function __call($name, $arguments)
    {
        if (!empty($this->methods[$name]) && is_callable($this->methods[$name])) {
            return call_user_func_array($this->methods[$name], $arguments);
        }
    }

    public function addMethod($name, Closure $method)
    {
        $this->methods[$name] = $method;
    }
}

// get class instance (A have no methods except of addMethod)
$instance = new A();

// add methods on runtime
$instance->addMethod('sum', function($num1, $num2) {
    return $num1 + $num2;
});

$instance->addMethod('sub', function($num1, $num2) {
    return $num1 - $num2;
});

// use methods exactly the same way as implemented fixed on class
echo $instance->sum(2, 2);
echo $instance->sub(3, 2);

当然您也可以将 __callStatic 用于静态方法。如果你想让它更复杂一点,也可以使用依赖注入的概念来添加对象而不是方法。然后在注入的对象中查找被调用的方法,找到后调用。 我希望这至少能给你一个好主意。