如何在类中调用成员变量的__invoke方法

Jul*_*May 10 php function member invoke functor

PHP 5.4.5,这里.我正在尝试调用一个存储为其他对象成员的对象.像这样(非常粗略)

class A {
    function __invoke () { ... }
}

class B {
    private a = new A();
 ...
    $this->a();  <-- runtime error here
}
Run Code Online (Sandbox Code Playgroud)

当然,这会产生运行时错误,因为没有名为a的方法.但如果我像这样写电话:

($this->a)();
Run Code Online (Sandbox Code Playgroud)

然后我得到一个语法错误.

当然,我可以写

$this->a->__invoke();
Run Code Online (Sandbox Code Playgroud)

但这似乎难以忍受,而且破坏了仿函数的重点.我只是想知道是否有更好的(或官方的)方式.

igo*_*orw 14

有三种方式:

直接打电话__invoke,你已经提到过:

$this->a->__invoke();
Run Code Online (Sandbox Code Playgroud)

通过分配变量:

$a = $this->a;
$a();
Run Code Online (Sandbox Code Playgroud)

使用call_user_func:

call_user_func($this->a);
Run Code Online (Sandbox Code Playgroud)

最后一个可能就是你要找的东西.它的好处是它适用于任何可调用的.

  • 因为它很暧昧。`$this-&gt;a()` 可以是方法 `a` 或成员 `$a`。在 PHP 中,这两者是分开的(例如,与 JS 不同)。 (2认同)

drm*_*mad 8

仅供参考,PHP 7+ 括号中的对象内部回调现在可以使用:

class foo {                                                                     
    public function __construct() {                                             
        $this -> bar = function() {                                             
            echo "bar!" . PHP_EOL;                                              
        };                                                                      
    }                                                                           

    public function __invoke() {                                                
        echo "invoke!" . PHP_EOL;                                               
    }                                                                           
}                                                                               

(new foo)();                                                                    

$f = new foo;                                                                   
($f -> bar)(); 
Run Code Online (Sandbox Code Playgroud)

结果:

invoke!
bar!
Run Code Online (Sandbox Code Playgroud)


Kri*_*Oye 5

我知道这是一个迟到的答案,但在父类中使用 __call() ,在子类中使用 __invoke() 的组合:

class A {
  function __invoke ($msg) {
    print $msg;
  }
}

class B {
    private $a;

    public function __construct() { $this->a = new A(); }

    function __call($name, $args)
    {
      if (property_exists($this, $name))
      {
        $prop = $this->$name;
        if (is_callable($prop))
        {
          return call_user_func_array($prop, $args);
        }
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

那么你应该能够实现你正在寻找的语法糖:

$b = new B();
$b->a("Hello World\n");
Run Code Online (Sandbox Code Playgroud)