命令行下进度条的实现 CMD / Linux
使用php脚本下载文件并显示进度条
<?php
class Request
{
// 是否下载完成
protected $downloaded = false;
protected $rate = null;
protected $unit = 2;
protected $total = 100;
protected $url = 'http://localhost/dc_u3d_king.sql';
protected $save = 'dc_u3d_king_copy.sql';
public function __construct()
{
}
function download()
{
$ch = curl_init();
// 从配置文件中获取根路径
curl_setopt($ch, CURLOPT_URL, $this->url);
// 不直接输出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 开启进度条
curl_setopt($ch, CURLOPT_NOPROGRESS, 0);
// 进度条的触发函数
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, [$this, 'progress']);
// ps: 如果目标网页跳转,也跟着跳转
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if (false === ($stream = curl_exec($ch))) {
throw new \Exception(curl_errno($ch));
}
curl_close($ch);
file_put_contents($this->save, $stream);
}
/**
* 进度条下载
* @param $ch
* @param $countDownloadSize 总下载量
* @param $currentDownloadSize 当前下载量
* @param $countUploadSize 预计传输中总上传字节数
* @param $currentUploadSize 目前上传的字节数
*/
public function progress($ch, $countDownloadSize, $currentDownloadSize, $countUploadSize, $currentUploadSize)
{
// 等于 0 的时候,应该是预读资源不等于0的时候即开始下载
// 这里的每一个判断都是坑,多试试就知道了
if (0 === $countDownloadSize) {
return false;
}
// 有时候会下载两次,第一次很小,应该是重定向下载
if ($countDownloadSize > $currentDownloadSize) {
$this->downloaded = false;
// 继续显示进度条
}elseif ($this->downloaded) {
// 已经下载完成还会再发三次请求
return false;
}elseif ($currentDownloadSize === $countDownloadSize) {
// 两边相等下载完成并不一定结束,
return false;
}
$rate = ceil($currentDownloadSize * $this->total / $countDownloadSize);
if($rate !== $this->rate && $rate % $this->unit == 0){
$this->rate = $rate;
// \r 用在双引号内,回车,回到当前行首
echo 'progress: ['.str_repeat('#', $rate / $this->unit).str_repeat(' ', $this->total / $this->unit - $rate / $this->unit).'] '.$rate."%\r";
// 或者格式化输出
// %-50s 表示50个字符串长度,字符左对齐,不够的右边补空格
// printf("progress: [%-50s] %d%% Done\r", str_repeat('#', $rate / $this->unit), $rate);
}
}
}
(new Request)->download();
命令行下进度条的实现 CMD / Linux
最新推荐文章于 2023-11-17 14:10:07 发布