17

PHP 5.4.5、こちら。他のオブジェクトのメンバーとして保存されているオブジェクトを呼び出そうとしています。このように(非常に大まかに)

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

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

もちろん、aと呼ばれるメソッドがないため、これによりランタイムエラーが発生します。しかし、私がこのように呼び出しを書くと:

($this->a)();

次に、構文エラーが発生します。

もちろん、私は書くことができます

$this->a->__invoke();

しかし、それは耐え難いほど醜いようであり、むしろファンクターのポイントを弱体化させます。より良い(または公式の)方法があるかどうか疑問に思っていました。

4

3 に答える 3

22

次の 3 つの方法があります。

__invokeすでに言及した を直接呼び出す:

$this->a->__invoke();

変数に代入することにより:

$a = $this->a;
$a();

を使用してcall_user_func

call_user_func($this->a);

最後のものはおそらくあなたが探しているものです。任意の callable で動作するという利点があります。

于 2012-09-26T14:02:43.017 に答える
11

参考までに、オブジェクト内のコールバックを囲む 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)(); 

結果:

invoke!
bar!
于 2016-08-14T04:55:25.350 に答える
4

これが遅い答えであることは知っていますが、親で __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);
        }
      }
    }
}

次に、探しているシンタックス シュガーを実現できるはずです。

$b = new B();
$b->a("Hello World\n");
于 2014-10-20T05:34:22.247 に答える