sae的网络请求有限制,超过8MB的文件只能返回8MB的内容,为了下载大文件,需要分段下载,
附上源码抛砖引玉.此代码用KV缓存已经下载过的文件,下载的文件会保存到domin中.
<?php
use sinacloud\sae\Storage as Storage;
function responsefilecontents($contents,$filenm=NULL){
$rst=$contents;
if(is_null($filenm)){
$filenm="downloadfile";
}
Header("Content-type: application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Accept-Length: ".strlen("$rst"));
Header("Content-Disposition: attachment; filename=\"".$filenm."\"");
echo $rst;
exit ;
}
function r404(){
header('HTTP/1.1 404 Not Found');
header("status: 404 Not Found");
echo "not found";
die();
}
function geturl_sina($url){
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec( $ch );
$response = curl_getinfo( $ch );
$length=$response["download_content_length"];
curl_close ( $ch );
//echo "totle $length ";
$rst=array();
$maxfetch=7<<20;//8MB but here use 7MB
//$maxfetch=100<<10; //for test 100KB
$start=0;
while(true){
$ch=curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
if($start+$maxfetch>=$length){
curl_setopt( $ch, CURLOPT_RANGE, "$start-" );
//echo "option $start- ";
$contents = curl_exec( $ch );
array_push($rst,$contents);
curl_close ( $ch );
break;
}
else {
$end=$start+$maxfetch-1;
curl_setopt( $ch, CURLOPT_RANGE, "$start-$end" );
//echo "option $start-$end ";
$start=$end+1;
$contents = curl_exec( $ch );
array_push($rst,$contents);
curl_close ( $ch );
}
// $response = curl_getinfo( $ch );
// var_dump($response);
// var_dump($contents);
// die();
}
// echo "pices:".count($rst)." ";
//
// echo substr($rst[0],0,10);
// echo substr($rst[0],strlen($rst[0])-10,10);
// echo "------";
// echo substr($rst[1],0,10);
$rst_f=implode('',$rst);
return $rst_f;
//die();
}
if(($url=$_GET["url"])==""){
r404();
}
else{
//echo "$url";
//"http://down.newly-tech.com/brushlattest.apk"
// $url="http://down.newly-tech.com/tb.zip";
$kv = new SaeKV();
// 初始化KVClient对象
$ret = $kv->init();
$k_rst=$kv->get($url);
$s = new Storage();
$domin="cache";
$gi=strrpos($url,"/")+1;
$fn=substr($url,$gi,strlen("$url")-$gi);
//die($fn);
if($k_rst && !$_GET["update"]){
$rst=$s->getObject($domin, "$url");
$rst=$rst->body;
//var_dump($rst);
//echo $rst->body;
responsefilecontents($rst,"$fn");
}
else {
//@ $rst=file_get_contents("$url");
// $f=new SaeFetchurl();
// @ $rst=$f->fetch("$url");
$rst=geturl_sina($url);
if($rst=="") {
//echo $f->errmsg();
r404();
}
// 上传一个字符串到test这个Bucket中,设置此Object名为string.txt,并且设置其Content-type
$s->putObject("$rst", "cache", "$url");
$kv->set($url,time());
responsefilecontents($rst,"$fn");
}
//test k if not have
//save k-v fetch url
//return file
//echo strlen($rst);
}