21,886
社区成员
发帖
与我相关
我的任务
分享
function curl_115($durl,$saveto,$range){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $durl);
curl_setopt($ch, CURLOPT_RANGE, ''.(($range-1)*1024*1024).'-'.($range*1024*1024-1).'');//每次保存10MB
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$out = curl_exec($ch);
curl_close($ch);
file_put_contents($saveto, $out, FILE_APPEND);
}
function check_url_115($durl){
$handle = curl_init($durl);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($handle, CURLOPT_TIMEOUT,5);
$response = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
return $httpCode;
}
if(check_url_115($url)=='200'){
curl_115($url,'1.rar',1);
}else{
echo '手动更换URL';
}
利用file_put_contents的FILE_APPEND来断点保存文件
有一点不很自信,手动更改$range值,即CURLOPT_RANGE ''.(($range-1)*1024*1024).'-'.($range*1024*1024-1).'', 这个计算对吗?
按照你的注释,
如果$range=1,则 0-1048575 //从 0 偏移起取 1048576 的字节
如果$range=2,则 1048576-2097151 //从 1048576 偏移起取到2097152的字节
这样的话,注释里有2个1048576,会不会重复保存导致最后的rar文件被破坏?
此外 if(check_url_115($url)=='200') 这个判断基本没什么用处,这里还有一个恐怖的问题,即CURLINFO_HTTP_CODE = 200,但下载到一半时URL失效,下一次的CURLOPT_RANGE就不是10M的倍数了。
方案一:保守一点$range每改10次,手动跟新一次URL地址。
方案二:干脆不要限制10M,利用PHP的filesize(),URL失效后读取保存到硬盘的rar大小,然后再手动设置CURLOPT_RANGE,但是害怕filesize()取出的值真的等于CURLOPT_RANGE重新开始的值吗?这个精确到字节的数字,万一有什么偏移,整个rar还是给毁了。
望进一步指点,谢谢。
$url = 'http://blog.51edm.org/content/uploadfile/201303/dc7f1364286796.zip';
function curl_get($durl) {
$cookiejar = realpath('cookie.txt');
$t = parse_url($durl);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$durl);
// curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RANGE, '0-300'); //从 0 偏移起取 301 的字节
// curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_TIMEOUT,5);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_REFERER, "http://$t[host]/");
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiejar);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'head_func');
curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function");
$r = curl_exec($ch);
curl_close($ch);
return $r;
}
echo '<xmp>';
curl_get($url);
//回调函数 $str 为读到的内容
function progress_function($ch,$str) {
//print_r(curl_getinfo($ch));
echo PHP_EOL, strlen($str);//,':',substr($str,0,20);
return strlen($str);
}
//回调函数,用于获得头信息
function head_func($ch, $str) {
echo $str;
return strlen($str);
}
头信息中类似
Content-Length: 301
Content-Range: bytes 0-300/1806285
这样的玩意就很有用了(不支持断点续传的就没有这个,比如 http://bbs.csdn.net/topics/390455233)