从闭包内部更新全局范围内的变量值

updating a variable value in global scope from inside the closure

我正在尝试对我的数据库对象进行并行处理 (things),我正在使用此程序包并行处理 运行 事情

https://github.com/spatie/async

我想知道我有多少东西被成功处理了,所以我在全局范围内定义了 $stats 数组并尝试从

内部更新它
    $pool   = Pool::create();
    $things = Thing::all();

    $stats = [
        'total'   => count($things) ,
        'success' => [] ,
    ];

    foreach ($things as $thing) {

        $pool->add(function () use ($thing , $stats ) {

            // do stuff 
            return [$thing , $stats]  ;

        })->then(function ($output ) {

            // Handle success
            list( $thing  , $stats) = $output ;
            dump('SUCCESS');
            $stats['success'][$thing->id] = $thing->id ;


        }) ->catch(function ($exception){
            // Handle exception
            dump('[ERROR] -> ' . $exception->getMessage());
        });
    }

    $pool->wait();
    dump($stats);

即使我在输出中看到 SUCCESS 但是当我在最后转储我的 $statssuccess 总是空的

array:3 [▼
  "total" => 3
  "success" => []
]

我也尝试通过 usestats 传递给 then 没有任何区别

})->then(function ($output ) use ($stats) 

当我将 $stats 转储到 then 中时,我可以看到数据工作正常

    })->then(function ($output ) {

        // Handle success
        list( $thing  , $stats) = $output ;
        dump('SUCCESS');
        $stats['success'][$thing->id] = $thing->id ;
        
        dump( $stats);


    })

then

内部转储的输出
array:3 [▼
  "total" => 3
  "success" => array:1 [▼
    2 => 2
  ]
]

您需要做几件事:

通过引用从父范围继承 $stats,在第一个回调中使用以下内容:

use ($thing, &$stats)

然后 return 与引用相同的变量:

return [$thing, &$stats];

最后,在下一个回调中也通过引用取消引用相应的 $output 数组:

list($thing, &$stats) = $output;  // or [$thing, &$stats] = $output;

注意:这看起来有点粗略,我完全不确定这是使用该库的正确方法,但这至少应该有效。