当前位置: 首页 > 后端技术 > PHP

【CLI】使用Curl下载文件并显示实时进度条

时间:2023-03-29 23:50:46 PHP

最近一直在研究命令行下的编程。下载文件始终是一个困难的过程。如果有进度条就更好了!!!首先,进度条的扩展包还是不错的。https://github.com/dariuszp/cli-progress-bar还是不错的!curl是一种很常见的PHP下载方式,这里简单介绍一下使用方法;//初始化一个curl$ch=curl_init();//设置请求的urlcurl_setopt($ch,CURLOPT_URL,$url);//curl_setopt($ch,CURLOPT_HEADER,0);//不直接输出,而是通过返回curl_execcurl_setopt($ch,CURLOPT_RETURNTRANSFER,1);如果(false===($stream=curl_exec($ch))){thrownew\Exception(curl_errno($ch));}curl_close($ch);return$stream;上面是一个很简单的例子,如果一个文件很大,那么用户需要等待很长时间,这时我们应该加上进度条的效果:classRequest{protected$bar;//是否下载完成protected$downloaded=false;publicfunction__construct(){//初始化一个进度条$this->bar=newCliProgressBar(100);$this->bar->display();$this->bar->setColorToRed();}函数下载($url){$ch=curl_init();//从配置文件中获取根路径curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,0);//开启进度条curl_setopt($ch,CURLOPT_NOPROGRESS,0);//进度条的触发函数curl_setopt($ch,CURLOPT_PROGRESSFUNCTION,'progress');//ps:如果目标页面跳转,它也跳转//curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);如果(false===($stream=curl_exec($ch))){thrownew\Exception(curl_errno($ch));}curl_close($ch);返回$流;}/***进度条下载。**@param$ch*@param$countDownloadSize总下载*@param$currentDownloadSize当前下载*@param$countUploadSize*@param$currentUploadSize*/publicfunctionprogress($ch,$countDownloadSize,$currentDownloadSize,$countUploadSize,$currentUploadSize){//当等于0时,应该在预读资源不等于0的时候开始下载。//这里的每一个判断都是一个坑,试试看就知道了if(0===$countDownloadSize){返回false;}//有时候会下载两次,第一次很小,应该是重定向下载if($countDownloadSize>$currentDownloadSize){$this->downloaded=false;//继续显示进度条}//下载完成后,再发送三个请求elseif($this->downloaded){returnfalse;}//双方是平等的,下载完成而不是必须结束,elseif($currentDownloadSize===$countDownloadSize){returnfalse;}//开始计数$bar=$currentDownloadSize/$countDownloadSize*100;$this->bar->progress($bar);}}(newRequest)->download('http://www.shiguopeng.cn/database.sql');下载回调的判断一定要注意陷阱!!!还有一个问题:跳转下载,如果设置curl为跳转,返回的文件会有问题。我下载了一个zip文件,会导致文件头包含第一个请求的HTTP响应头的内容。所以你需要curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);