thedethfox
thedethfox

Reputation: 1741

Anonymous functions in a class

is there a better way to call an anonymous function inside a class? Here is a simple example that clearifies what I mean.

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();

* Update 1: Please ignore any syntax error as I have written this on the fly for demo puposes. *

Inside foo:provokeCallBacks, I am trying to call the anonymous functions how ever the first way does not works and gives an error. The second one works but it's a bit stupid that I have to use a temp variable called "$method" to make the call.

I want to know if there exists a better way to call the anonymous function.

Upvotes: 2

Views: 3367

Answers (5)

Baba
Baba

Reputation: 95101

I know your question has been answered but you can try changing your approch ..

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

Upvotes: 1

moonwave99
moonwave99

Reputation: 22817

Being PHP loosely typed, it can't do like {$this -> callback}(); you have to store it in a temp variable or to use call_user_func() either.

EDIT - consider something like this:

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

Upvotes: 1

Vikko
Vikko

Reputation: 1406

Dirty and dangerous, but you might succeed using 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();

Upvotes: 1

Björn
Björn

Reputation: 29381

No, it's not possible to call an anonymous function via $this.

Another options is;

call_user_func($this->call_back_1);

Upvotes: 2

Glavić
Glavić

Reputation: 43552

call_user_func($this->call_back_1);

Upvotes: 4

Related Questions