Skip to content
Advertisement

How to use bindTo in PHP

it is not exactly a question, but I found a following example and I can’t understand how does it work, can someone explain it?

<?php
class Number {
    private $v = 0;
    
    public function __construct($v) {
        $this->v = $v;
    }
    
    public function mul() {
        return function ($x) {
            return $this->v * $x; 
        };
    }
}

$one = new Number(1);
$two = new Number(2);
$double = $two->mul()->bindTo($one);
echo $double(5);

I understand the code, but putting together it doesn’t make sanse to me. The answer should be 5 btw.

Thank you in advance.

Advertisement

Answer

The example in your question is a bit more complicated than it needs to be to just explain how bindTo works. I assume the point is that you can re-bind $this, rather than just binding an object to a closure, but I think that probably makes everything a bit harder to understand.

The whole idea is that for a given closure, you can create a clone for which you have set the surrounding scope. The simplest example would be something like this (demo here):

$closureThatShowsTheProperty = function() {
    echo $this->prop;
};

$objectThatHasTheProperty = new class() {
    public $prop = 123;
};

$closureThatShowsTheProperty->bindTo($objectThatHasTheProperty)();

123

Note that the class and the function are completely independent until the call to bindTo. Your example is demonstrating that even a closure that is generated within an instance of a class can be rebound to a different instance, but that’s probably not the most common use-case.

One difference is that a closure generated within an existing class instance will have that class as its scope, so will allow accessing private + protected properties. If you wanted to replicate that using an anonymous function from elsewhere in your code, you would need to use the second argument to bindTo to set the scope:

$closureThatShowsTheProperty = function() {
    echo $this->prop;
};

$objectThatHasTheProperty = new class() {
    private $prop = 123;
};

$closureThatShowsTheProperty->bindTo($objectThatHasTheProperty)();

Fatal error: Uncaught Error: Cannot access private property…

$closureThatShowsTheProperty->bindTo($objectThatHasTheProperty, $objectThatHasTheProperty)();

123

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement