opis / closure

Serialize closures (anonymous functions)

Home Page:https://opis.io/closure

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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!