2

クラス内で無名関数を呼び出すより良い方法はありますか? これが私の言いたいことを明確にする簡単な例です。

class foo
{
     private $call_back_1 = null;
     private $call_back_2 = null;

     function __construct($func1, $func2)
     {
          $this->call_back_1 = func1;
          $this->call_back_2 = func2;
     }


     function provokeCallBacks()
     {
          //this does not work, and gives an error  
          $this->call_back_1();


          //I would like to avoid this
          $method = $this->call_back_2;
          $method(); 
     }
}

$call1 = function(){ echo "inside call 1"};
$call2 = function(){ echo "inside call 2"};

$test = new foo(call1, call2);

$test->provokeCallBacks();

* 更新 1: デモ用にその場で書いたので、構文エラーは無視してください。*

foo:provokeCallBacks 内で、匿名関数を呼び出そうとしていますが、最初の方法が機能せず、エラーが発生します。2番目のものは機能しますが、「$ method」という一時変数を使用して呼び出しを行う必要があるのは少しばかげています。

無名関数を呼び出すためのより良い方法が存在するかどうかを知りたいです。

4

5 に答える 5

2

いいえ、 を介して無名関数を呼び出すことはできません$this

別のオプションは次のとおりです。

call_user_func($this->call_back_1);
于 2012-09-26T13:30:13.143 に答える
2

PHP は緩く型付けされているため、次のようにすることはできません{$this -> callback}()。一時変数に保存するcall_user_func()か、どちらかを使用する必要があります。

編集 - 次のようなものを検討してください。

class Lambdas
{

    protected $double;
    protected $triple;  

    public function __construct($double, $triple)
    {

        $this -> double = $double;
        $this -> triple = $triple;      

    }

    public function __call($name, $arguments)
    {

        if( is_callable($this -> {$name}) ){

            return call_user_func_array($this -> {$name}, $arguments);

        }

    }

}

$lambdas = new Lambdas(
    function($a){ return $a * 2;},
    function($a){ return $a * 3;}
);

echo $lambdas -> double(2); // prints 4
echo $lambdas -> triple(2); // prints 6
于 2012-09-26T13:31:41.653 に答える
1

汚くて危険ですが、eval を使えば成功するかもしれません。

class foo
{
  private $call_back_1 = null;
  private $call_back_2 = null;

  function __construct($func1, $func2)
  {
      $this->call_back_1 = func1;
      $this->call_back_2 = func2;
  }


  function provokeCallBacks()
  {
      eval($this->call_back_1);
      eval($this->call_back_2);
  }
}

call1 = 'echo "inside call 1"';
call2 = 'echo "inside call 2"';

$test = foo(call1, call2);

$test->provokeCallBacks();
于 2012-09-26T13:34:27.333 に答える
1

あなたの質問が答えられたことは知っていますが、アプローチを変更してみてください..

class Foo {
    private $calls = array();
    function __set($key, $value) {
        $this->calls[$key] = $value;
    }
    function __call($name, $arg) {
        if (array_key_exists($name, $this->calls)) {
            $this->calls[$name]();
        }
    }

    function __all() {
        foreach ( $this->calls as $call ) {
            $call();
        }
    }
}

$test = new Foo();

$test->A = function () {
    echo "inside call 1";
};

$test->B = function () {
    echo "inside call 2";
};

$test->A(); // inside call 1
$test->B(); // inside call 2
$test->__all(); // inside call 1 & inside call 2
于 2012-09-26T13:40:15.010 に答える