php支持断点续传、分块下载的类
本文是为大家分享php支持断点续传、分块下载的类,供大家参考,具体内容如下
<?php /** *User:djunny *Date:2016-04-29 *Time:17:18 *Mail:199962760@qq.com *支持断点下载的类 */ classdownloader{ /** *downloadfiletolocalpath * *@param$url *@param$save_file *@paramint$speed *@paramarray$headers *@paramint$timeout *@returnbool *@throwsException */ staticfunctionget($url,$save_file,$speed=10240,$headers=array(),$timeout=10){ $url_info=self::parse_url($url); if(!$url_info['host']){ thrownewException('UrlisInvalid'); } //defaultheader $def_headers=array( 'Accept'=>'*/*', 'User-Agent'=>'Mozilla/4.0(compatible;MSIE8.0;WindowsNT5.1;Trident/4.0)', 'Accept-Encoding'=>'gzip,deflate', 'Host'=>$url_info['host'], 'Connection'=>'Close', 'Accept-Language'=>'zh-cn', ); //mergeheade $headers=array_merge($def_headers,$headers); //getcontentlength $content_length=self::get_content_size($url_info['host'],$url_info['port'],$url_info['request'],$headers,$timeout); //contentlengthnotexist if(!$content_length){ thrownewException('Content-LengthisNotExists'); } //getexistslength $exists_length=is_file($save_file)?filesize($save_file):0; //gettmpdatafile $data_file=$save_file.'.data'; //gettmpdata $exists_data=is_file($data_file)?json_decode(file_get_contents($data_file),1):array(); //checkfileisvalid if($exists_length==$content_length){ $exists_data&&@unlink($data_file); returntrue; } //checkfileisexpire if($exists_data['length']!=$content_length||$exists_length>$content_length){ $exists_data=array( 'length'=>$content_length, ); } //writeexistsdata file_put_contents($data_file,json_encode($exists_data)); try{ $download_status=self::download_content($url_info['host'],$url_info['port'],$url_info['request'],$save_file,$content_length,$exists_length,$speed,$headers,$timeout); if($download_status){ @unlink($data_file); } }catch(Exception$e){ thrownewException($e->getMessage()); } returntrue; } /** *parseurl * *@param$url *@returnbool|mixed */ staticfunctionparse_url($url){ $url_info=parse_url($url); if(!$url_info['host']){ returnfalse; } $url_info['port']=$url_info['port']?$url_info['host']:80; $url_info['request']=$url_info['path'].($url_info['query']?'?'.$url_info['query']:''); return$url_info; } /** *downloadcontentbychunk * *@param$host *@param$port *@param$url_path *@param$headers *@param$timeout */ staticfunctiondownload_content($host,$port,$url_path,$save_file,$content_length,$range_start,$speed,&$headers,$timeout){ $request=self::build_header('GET',$url_path,$headers,$range_start); $fsocket=@fsockopen($host,$port,$errno,$errstr,$timeout); stream_set_blocking($fsocket,TRUE); stream_set_timeout($fsocket,$timeout); fwrite($fsocket,$request); $status=stream_get_meta_data($fsocket); if($status['timed_out']){ thrownewException('SocketConnectTimeout'); } $is_header_end=0; $total_size=$range_start; $file_fp=fopen($save_file,'a+'); while(!feof($fsocket)){ if(!$is_header_end){ $line=@fgets($fsocket); if(in_array($line,array("\n","\r\n"))){ $is_header_end=1; } continue; } $resp=fread($fsocket,$speed); $read_length=strlen($resp); if($resp===false||$content_length<$total_size+$read_length){ fclose($fsocket); fclose($file_fp); thrownewException('SocketI/OErrorOrFileWasChanged'); } $total_size+=$read_length; fputs($file_fp,$resp); //checkfileend if($content_length==$total_size){ break; } sleep(1); //fortest //break; } fclose($fsocket); fclose($file_fp); returntrue; } /** *getcontentlength * *@param$host *@param$port *@param$url_path *@param$headers *@param$timeout *@returnint */ staticfunctionget_content_size($host,$port,$url_path,&$headers,$timeout){ $request=self::build_header('HEAD',$url_path,$headers); $fsocket=@fsockopen($host,$port,$errno,$errstr,$timeout); stream_set_blocking($fsocket,TRUE); stream_set_timeout($fsocket,$timeout); fwrite($fsocket,$request); $status=stream_get_meta_data($fsocket); $length=0; if($status['timed_out']){ return0; } while(!feof($fsocket)){ $line=@fgets($fsocket); if(in_array($line,array("\n","\r\n"))){ break; } $line=strtolower($line); //getlocation if(substr($line,0,9)=='location:'){ $location=trim(substr($line,9)); $url_info=self::parse_url($location); if(!$url_info['host']){ return0; } fclose($fsocket); returnself::get_content_size($url_info['host'],$url_info['port'],$url_info['request'],$headers,$timeout); } //getcontentlength if(strpos($line,'content-length:')!==false){ list(,$length)=explode('content-length:',$line); $length=(int)trim($length); } } fclose($fsocket); return$length; } /** *buildheaderforsocket * *@param$action *@param$url_path *@param$headers *@paramint$range_start *@returnstring */ staticfunctionbuild_header($action,$url_path,&$headers,$range_start=-1){ $out=$action."{$url_path}HTTP/1.0\r\n"; foreach($headersas$hkey=>$hval){ $out.=$hkey.':'.$hval."\r\n"; } if($range_start>-1){ $out.="Accept-Ranges:bytes\r\n"; $out.="Range:bytes={$range_start}-\r\n"; } $out.="\r\n"; return$out; } } #useage /* try{ if(downloader::get('http://dzs.aqtxt.com/files/11/23636/201604230358308081.rar','test.rar')){ //todo echo'DownloadSucc'; } }catch(Exception$e){ echo'DownloadFailed'; } */ ?>
以上就是本文的全部内容,希望对大家的学习有所帮助。