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

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

使用php脚本下载文件并显示进度条

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();

你可能感兴趣的:(PHP,Linux)