php 加curl http范围请求实现分片下载

php 加curl http范围请求实现分片下载

public function download_file($file)
{
    $file = "https://www.inbeijing.org/people_snake.mp4";
    $range = "0-1";
    $response = $this->curl_get_with_head($file, array(
        "Range: bytes={$range}"
    ));
    $eTag = $response['etag'];
    $length = $response['length'];
    $chunkCount = 100;
    $step = ceil($length / $chunkCount);
    for($i=0;$i<$chunkCount;$i++) {
        $start = $i * $step;
        $end = (($i+1) * $step) -1;
        if($end > $length) {
            $end = $length;
        }
        $range = $start. '-'. $end;
        $con = $this->curl_get_with_body('https://www.inbeijing.org/people_snake.mp4', $range);
        file_put_contents('c:\\snake.mp4', $con, FILE_APPEND);
        echo("总大小{$length},共计{$chunkCount}片,第{$i}片下载完成, range:". $range ."\n");
    }
}
//get请求
public 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];
    }
}
//get请求获取body体
public 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;
    }
}

调用:

download_file($file);

3 thoughts on “php 加curl http范围请求实现分片下载

回复 北漂小兄弟 取消回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据