PHP从Object方法中调用回调函数

时间:2017-10-06 08:22:06

标签: php laravel callback

我正在构建一个调度程序,它将采用一个回调函数,并将执行该函数给定的次数,并在给定的延迟量之间。下面是功能看起来的接口。

附注我正在使用Laravel框架;

public function testBasicTest()
{
    $count = 0;
    $schedule = new NodeScheduler();
    $schedule->retries(2)->delay(100000)->do(function() use ($count) {
        $count++;
    });
    $this->assertEquals($count === 1);
}

这是我对这一功能的测试,你可以看到我希望在结尾时数等于2。

我的班级看起来像这样;

class NodeScheduler
{
    protected $retries = 1;
    protected $milliseconds = 10000;

    public function __construct()
    {
        return $this;
    }

    public function retries($numberOfRetries)
    {
        $this->retries = $numberOfRetries;
        return $this;
    }

    public function delay($milliSeconds)
    {
        $this->milliSeconds = $milliSeconds;
        return $this;
    }

    public function do($callback)
    {
        for($i = 0; $i < $this->retries; $i++){
            $callback(); // <<<<<< How Do I Inject The $count Variable Here?
            usleep($this->milliseconds);
        }
        return;
    }
}

我的测试失败了:

Failed asserting that 2 matches expected 0.

奇怪的是,我没有得到$ count未定义。

我想我很亲近,任何帮助都非常感激

2 个答案:

答案 0 :(得分:1)

当你use()来自函数内外部作用域的变量时,会在函数的内部作用域中创建一个 copy 变量(如果你是{{1则例外)一个对象)。

如果要从外部范围导入变量并修改它,则需要通过引用传递它:

use()

编辑:此外,@ Arno和@Oniyo指出:使用$schedule->retries(2)->delay(100000)->do(function() use (&$count) { $count++; }); 或使用assertEquals(1, $count)

答案 1 :(得分:0)

我认为你做错了两件事

首先:正如@Arno指出的那样,

$this->assertEquals($expected, $actual);

其次:从我在代码中看到的,循环将运行$this->retries的迭代。所以,$this->assertEquals($expected, $actual)应该是

$this->assertEquals(2, count);
祝你好运!