`Fiber` 命令行加载动画
Fiber
更加方便异步, 比 yield
更加便于理解和操作
- 代码参考
public function run(Input $input, Output $output): void
{
if (strpos(PHP_VERSION, '8.1') !== 0) {
$output->writeLine('需要 8.1 版本以上!!!');
return;
}
//doSomething
//光标隐藏/恢复
$hideCursor = $this->hideCursor();
$output->write("\033[s");
$output->write('loading ');
//加载进度
$dotLoad = $this->dotLoader();
$dotLoad->start(1);
for ($i = 1; $i <= 100; $i++) {
# code...
usleep(100000);
$dotLoad->resume($i%100);
}
$output->writeLine('finished !!!');
$hideCursor->resume();
}
/**
* 协程加载动画
*
* @return \Fiber
*/
private function dotLoader(): \Fiber
{
return new \Fiber(function () {
$jump = '·';
$load = ['.', '.', '.', '.', '.', '.', '.', '.','.'];
echo "\033[32;1m 00% " . implode('', $load) . "\033[0m";
while(true) {
for ($i=0; $i < 9; $i++) {
$temp = $load;
$temp[$i] = $jump;
$tmpStr = "\033[32;1m {step}". implode('', $temp) . "\033[0m";
$step = \Fiber::suspend();
if ( $step === 0) {
break 2;
}
echo "\033[14D";
echo str_replace('{step}', sprintf('%02d%% ', $step), $tmpStr);
}
}
echo "\033[u\033[K";
});
}
/**
* 协程光标隐藏/恢复
*
* @return \Fiber
*/
private function hideCursor(): \Fiber
{
$f = new \Fiber(function () {
echo "\033[?25l";
\Fiber::suspend();
echo "\033[?25h";
});
$f->start();
return $f;
}
优秀啊: