返回

如何在PHP中直接调用分配给对象属性的闭包?

php

直接调用分配给对象属性的闭包

问题

在 PHP 中,直接调用分配给对象属性的闭包会引发错误 Fatal error: Call to undefined method stdClass::callback()。这是因为对象没有内置的方法来直接调用闭包。

原因

PHP 中的闭包是匿名函数,而不是对象。因此,当尝试直接调用分配给对象属性的闭包时,PHP 会将该属性解释为一个不存在的方法。

解决方法

要解决这个问题,有两种主要方法:

方法 1:使用匿名函数

可以通过使用匿名函数将闭包分配给对象属性。这将创建一个匿名类,继承自 Closure 类,允许你直接调用闭包。

方法 2:使用回调方法

也可以定义一个回调方法来调用分配给对象属性的闭包。这可以通过实现 __call() 魔术方法来实现。

哪种方法更好?

方法 2(使用回调方法)适用于需要在多个对象之间共享闭包的情况。方法 1(使用匿名函数)适用于闭包仅用于一个对象的情况。

示例

方法 1:匿名函数

class MyClass {
    private $callback;

    public function setCallback(Closure $callback) {
        $this->callback = $callback;
    }

    public function callCallback() {
        $this->callback->__invoke();
    }
}

$myClass = new MyClass();
$myClass->setCallback(function() {
    echo "Hello World!";
});

$myClass->callCallback();

方法 2:回调方法

class MyClass {
    private $callbacks = [];

    public function __call($name, $arguments) {
        if (isset($this->callbacks[$name])) {
            return call_user_func_array($this->callbacks[$name], $arguments);
        }

        throw new BadMethodCallException("Method $name does not exist.");
    }

    public function setCallback($name, Closure $callback) {
        $this->callbacks[$name] = $callback;
    }
}

$myClass = new MyClass();
$myClass->setCallback('callback', function() {
    echo "Hello World!";
});

$myClass->callback();

结论

虽然 PHP 中的对象没有内置的方法来直接调用分配给它们的闭包,但使用匿名函数或回调方法可以实现这一目标。根据闭包的使用方式,选择一种方法要优于另一种方法。

常见问题解答

  • 问:为什么不能直接调用分配给对象属性的闭包?
    • 答:因为 PHP 中的对象没有内置的方法来调用闭包。
  • 问:匿名函数和回调方法有什么区别?
    • 答:匿名函数创建了一个匿名类,而回调方法通过实现 __call() 魔术方法来调用闭包。
  • 问:哪种方法更好?
    • 答:方法 2 适用于需要在多个对象之间共享闭包的情况,而方法 1 适用于闭包仅用于一个对象的情况。
  • 问:如何设置回调方法?
    • 答:使用 setCallback() 方法将闭包分配给回调方法名称。
  • 问:如何调用回调方法?
    • 答:就像调用常规方法一样,直接使用回调方法名称。