如何确保我们在属性上使用__invoke而不是在主对象上使用__call?

Moł*_*łot 7 php oop

我们假设我们有以下代码:

<?php
class Worker {
  public function __invoke() {
    echo "invoked\n";
  }
}

class Caller {
  public $worker;

  public function __construct($worker) {
    $this->worker = $worker;
  }

  public function __call($name, $arguments) {
    echo "called\n";
  }
}

$c = new Caller(new Worker());
echo $c->worker();
?>
Run Code Online (Sandbox Code Playgroud)

结果是called.该怎么办invoked

bwo*_*ebi 4

这个问题也存在于工作相同的匿名函数中。您有几种方法可以解决:

1)修改你的 __call 以检查它是否是一个方法,如果不是,则调用该属性:

if (property_exists($this, $name) && is_object($this->$name) && method_exists($this->$name, "__invoke")) {
    call_user_func_array($this->name, $args);
}
Run Code Online (Sandbox Code Playgroud)

2)__invoke直接调用:$c->worker->__invoke();

3) 将属性保存到临时变量中:

$tempVar = $c->worker;
$tempVar();
Run Code Online (Sandbox Code Playgroud)

4)(几乎与3相同)(来源:http://marc.info/? l=php-internals&m=136336319809565&w=4 )

${'_'.!$_=$c->worker}();
Run Code Online (Sandbox Code Playgroud)

5) 使用call_user_funccall_user_func_array

call_user_func($c->worker);
Run Code Online (Sandbox Code Playgroud)