PHP Cli下显示一个进度条:
function smoothProgressBar($current, $total, $startTime) {
// 获取终端宽度
$termWidth = (int)shell_exec('tput cols') - 10;
$barWidth = max(20, $termWidth - 40);
// 计算进度
$progress = min(max($current / $total, 0.0), 1.0);
$filledWidth = (int)round($barWidth * $progress);
// 动态头部符号(使用等宽符号)
static $spinStates = ['▏','▎','▍','▌','▋','▊','▉','█'];
$headIndex = (int)(microtime(true)*10 % count($spinStates));
$headChar = $spinStates[$headIndex];
// 构建进度条
$bar = "3[48;5;238m" . "3[38;5;46m";
$bar .= str_repeat('▉', $filledWidth);
$bar .= ($progress < 1.0) ? ("3[38;5;51m" . $headChar) : '▉';
$bar .= "3[38;5;46m" . str_repeat('░', max($barWidth - $filledWidth - 1, 0));
$bar .= "3[0m";
// 固定宽度信息格式
$elapsed = time() - $startTime;
$eta = ($current > 0) ? round(($elapsed / $current) * ($total - $current)) : '--';
$info = sprintf("3[38;5;226m" . "%6.1f%% %s %4d/%-4d %02d:%02d|%s" . "3[0m",
$progress * 100,
$bar,
$current,
$total,
floor($elapsed / 60),
$elapsed % 60,
is_numeric($eta) ? sprintf("%02d:%02d", floor($eta/60), $eta%60) : '--:--'
);
// 输出控制
echo "3[?25l" . "3[2K" . "\r" . $info;
}
// 使用示例
$totalItems = 150;
$startTime = time();
// 注册终止处理确保显示光标
register_shutdown_function(function() {
echo "3[?25h";
});
ob_implicit_flush(true);
for ($i = 0; $i <= $totalItems; $i++) {
smoothProgressBar($i, $totalItems, $startTime);
usleep(30000);
// 实际任务代码...
}
echo "\n3[32m✓ 处理完成!3[0m\n";
echo "3[?25h"; // 确保始终恢复光标
ob_implicit_flush(false);
exit;
© 版权声明
THE END
暂无评论内容