PHP Cli下显示一个进度条

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
喜欢就支持一下吧
点赞3 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称常用语 夸夸
夸夸
还有吗!没看够!
表情代码图片快捷回复

    暂无评论内容