php url分片下载大文件

源代码
//get请求获取body体
function curl_get_with_body($url, $range)
{
    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "GET",
        CURLOPT_POSTFIELDS => "",
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_HTTPHEADER => array(
            "Range: bytes={$range}"
        ),
    ));

    $response = curl_exec($curl);
    $err = curl_error($curl);
    curl_close($curl);

    if ($err) {
        return "cURL Error #:" . $err;
    } else {
        return $response;
    }
}
//get请求
function curl_get_with_head($url, $header)
{
    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "HEAD",
        CURLOPT_POSTFIELDS => "",
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 2,
        //CURLINFO_HEADER_OUT => TRUE,    //获取请求头
        CURLOPT_HEADER => true, //获取响应头
        CURLOPT_NOBODY => true, //不需要响应正文
        CURLOPT_HTTPHEADER => $header,
    ));

    $response = curl_exec($curl);
    $err = curl_error($curl);
    curl_close($curl);
    $responseHeader = explode("\r\n", $response);
    $totalLength = $eTag = '';
    foreach($responseHeader as $response) {
        if($response){
            //获取文件总长度
            if(strpos($response, 'Content-Range:', 0) !== false) {
                $totalLength = explode(':', $response);
                $totalLength = array_pop($totalLength);
                $totalLength = explode('/', $totalLength);
                $totalLength = array_pop($totalLength);
            }
            //获取文件etag
            if(strpos($response, 'ETag:', 0) !== false) {
                $eTag = explode(':', $response);
                $eTag = array_pop($eTag);
                $eTag = trim(str_replace('"', '', $eTag));
            }
        }

    }

    if ($err) {
        return "cURL Error #:" . $err;
    } else {
        return ['length' => $totalLength, 'etag' => $eTag];
    }
}

function download_file($file_url,$file_path,$rname,$ext)
{
//    $file = "http://public.geek-in.net/clouddisk/NYsrTpPRjz.mp4";
    $range = "0-1";
    $response = curl_get_with_head($file_url, array(
        "Range: bytes={$range}"
    ));
    $eTag = $response['etag'];
    $length = $response['length'];
    if(file_exists($file_path.$rname.'.'.$ext)) {
        if (filesize($file_path . $rname . '.' . $ext) != $length) {//大小不一样重新下载
            try {
                unlink($file_path . $rname . '.' . $ext);
            }catch (Exception $exception){
                echo "删除文件失败:{$file_path}{$rname}.{$ext}" . PHP_EOL;
            }
            $chunkCount = 100;
            $chunkCount = $length/10000000;
            $step = ceil($length / $chunkCount);
            echo 11111;
            $fp=fopen("{$file_path}{$rname}.{$ext}", 'w+');
            for($i=0;$i<$chunkCount;$i++) {
                $start = $i * $step;
                $end = (($i+1) * $step) -1;
                if($end > $length) {
                    $end = $length;
                }
                $range = $start. '-'. $end;
                $con = curl_get_with_body($file_url, $range);
//        file_put_contents("{$file_path}{$rname}.{$ext}", $con, FILE_APPEND);

                fwrite($fp, $con);
                echo("总大小{$length},共计{$chunkCount}片,第{$i}片下载完成, range:". $range .PHP_EOL);
            }
            echo "下载完成,总大小:{$length},";
            fclose($fp);
        }
    }

}

download_file("http://www.www.ss.mp4","D:\","cc","mp4")
posted @ 2020-07-18 17:02  办公魔盒  阅读(687)  评论(0)    收藏  举报