命令行下进度条的实现 CMD / Linux

命令行下进度条的实现 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();
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页