Search code examples
phpphp-5.4

How to bind $this to a closure that is passed as a method parameter in PHP 5.4?


Is there any way to bind $this to a closure that is passed as a parameter? I read and reread everything I could find in manual or over the internet, but no one mentions this behaviour, except this blog post: http://www.christophh.net/2011/10/26/closure-object-binding-in-php-54/ which mentions it but doesn't show how to do it.

So here's an example. When calling the get(function() {}) method I want the callback function that is passed to it was bound to the object i.e. bound to $this, but unfortunately it doesn't work. Is there any way I can do it?

class APP
{
    public $var = 25;

    public function __construct() {

    }
    public function get($callback) {
        if (!is_callable($callback)) {
            throw new InvalidArgumentException('Paran must be callable.');
        }
        // $callback->bindTo($this);
        $callback->bindTo($this, $this);
        $callback();
    }
}

$app = new APP();
$app->get(function() use ($app) {
    echo '<pre>';
    var_dump($app);
    echo '<br />';
    var_dump($this);
});

$app works. $this is NULL.


Solution

  • I actually didn't understand why using the bindTo method didn't work in this case, but I could get it to work using Closure::bind

    public function get($callback) {
        if (!is_callable($callback)) {
            throw new InvalidArgumentException('Param must be callable.');
        }
    
        $bound = Closure::bind($callback, $this);
        $bound();
    }
    

    Edit

    Aparently the bindTo method has the same behavior, so you should reassign its return value to $callback. For example:

    public function get($callback) {
        if (!is_callable($callback)) {
            throw new InvalidArgumentException('Param must be callable.');
        }
    
        $callback = $callback->bindTo($this);
        $callback();
    }