Callbacks using local variables not working
davizuku opened this issue · comments
<?php
require_once __DIR__ . '/vendor/autoload.php';
class CallbackCaller
{
private $callback;
public function setCallback(callable $callback)
{
$this->callback = $callback;
}
public function callCallback()
{
call_user_func($this->callback);
}
}
$numCalls = 0;
$c = new CallbackCaller();
$c->setCallback(function () use (&$numCalls) {
$numCalls++;
});
$c->callCallback();
$c->callCallback();
$c->callCallback();
echo "Num calls after calling 3 times on \$c: $numCalls\n";
$serializedStr = \Opis\Closure\serialize($c);
$newC = \Opis\Closure\unserialize($serializedStr);
$numCalls = 0;
$newC->callCallback();
$newC->callCallback();
$newC->callCallback();
echo "Num calls after calling 3 times on \$newC: $numCalls\n";
Using:
$ php --version
PHP 5.5.11 (cli) (built: Apr 9 2014 15:01:49)
The snippet above outputs:
Num calls after calling 3 times on $c: 3
Num calls after calling 3 times on $newC: 0
Expected output:
Num calls after calling 3 times on $c: 3
Num calls after calling 3 times on $newC: 3
Your expected output is not something that php can handle
<?php
$x = 1;
$y = ['ref' => &$x];
$y['ref']++;
echo $x, PHP_EOL; // 2
$y = unserialize(serialize($y));
$y['ref']++;
echo $x, PHP_EOL; // still 2 (NOT 3)
Since PHP cannot handle it, opis/closure will not handle it too.
I think this is the easiest way to explain why your code will never produce the desired output.
You're right! Thank you @sorinsarca for your explanation!