0

我有用户可以从其他服务器/URL 下载文件。这是示例代码,但可恢复下载不起作用,尝试下载时从头开始

<?php
$url = "http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/03/windows10.0-kb4012606-x64_e805b81ee08c3bb0a8ab2c5ce6be5b35127f8773.msu";
dl_file_resumable( $url );

function dl_file_resumable( $file, $is_resume = true ) {
    //Gather relevent info about file
    $size     = remotefilesize( $file );
    $fileinfo = pathinfo( $file );

    //workaround for IE filename bug with multiple periods / multiple dots in filename
    //that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
    $filename = ( strstr( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) ) ?
        preg_replace( '/\./', '%2e', $fileinfo['basename'], substr_count( $fileinfo
                                                                          == [ 'basename' ], '.' ) - 1 ) : $fileinfo['basename'];

    $file_extension = strtolower( $fileinfo['extension'] );

    //This will set the Content-Type to the appropriate setting for the file
    switch ( $file_extension ) {
        case 'exe':
            $ctype = 'application/octet-stream';
            break;
        case 'zip':
            $ctype = 'application/zip';
            break;
        case 'rar':
            $ctype = 'application/x-rar-compressed';
            break;
        case 'mp3':
            $ctype = 'audio/mpeg';
            break;
        case 'mpg':
            $ctype = 'video/mpeg';
            break;
        case 'avi':
            $ctype = 'video/x-msvideo';
            break;
        default:
            $ctype = 'application/force-download';
    }

    //check if http_range is sent by browser (or download manager)
    if ( $is_resume && isset( $_SERVER['HTTP_RANGE'] ) ) {
        list( $size_unit, $range_orig ) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );

        if ( $size_unit == 'bytes' ) {
            //multiple ranges could be specified at the same time, but for simplicity only serve the first range
            //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
            list( $range, $extra_ranges ) = explode( ',', $range_orig, 2 );
        } else {
            $range = '';
        }
    } else {
        $range = '';
    }

    //figure out download piece from range (if set)
    list( $seek_start, $seek_end ) = explode( '-', $range, 2 );

    //set start and end based on range (if set), else set defaults
    //also check for invalid ranges.
    $seek_end   = ( empty( $seek_end ) ) ? ( $size - 1 ) : min( abs( intval( $seek_end ) ), ( $size - 1 ) );
    $seek_start = ( empty( $seek_start ) || $seek_end < abs( intval( $seek_start ) ) ) ? 0 : max( abs( intval( $seek_start ) ), 0 );

    //add headers if resumable
    if ( $seek_start > 0 || $seek_end < ( $size - 1 ) ) {
        header( 'HTTP/1.1 206 Partial Content' );
        header( 'Content-Range: bytes ' . $seek_start . '-' . $seek_end . '/' . $size );
        header( 'Content-Length: ' . ( $seek_end - $seek_start + 1 ) );
    } else {

        header( "Content-Length: $size" );
    }

    header( 'Accept-Ranges: bytes' );

    //headers for IE Bugs (is this necessary?)
    //header("Cache-Control: cache, must-revalidate");
    //header("Pragma: public");

    header( 'Content-Type: ' . $ctype );
    header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
    header( "Pragma: public" );
    header( "Expires: -1" );
    header( "Cache-Control: public, must-revalidate, post-check=0, pre-check=0" );
    header( "Content-Disposition: attachment; filename=\"$filename\"" );

    //open the file
    $fp = fopen( $file, 'rb' );
    //seek to start of missing part
    fseek( $fp, $seek_start );

    //start buffered download
    while ( ! feof( $fp ) ) {
        //reset time limit for big files
        set_time_limit( 0 );
        print( fread( $fp, 1024 * 8 ) );
        flush();
        ob_flush();
        usleep(50000);
        if ( connection_status() != 0 ) {
            @fclose( $file );
            exit;
        }
    }

    fclose( $fp );
    exit;
}

function remotefilesize( $url, $user = "", $pw = "" ) {
    ob_start();
    $ch = curl_init( $url );
    curl_setopt( $ch, CURLOPT_HEADER, 1 );
    curl_setopt( $ch, CURLOPT_NOBODY, 1 );

    if ( ! empty( $user ) && ! empty( $pw ) ) {
        $headers = array( 'Authorization: Basic ' . base64_encode( "$user:$pw" ) );
        curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
    }

    $ok = curl_exec( $ch );
    curl_close( $ch );
    $head = ob_get_contents();
    ob_end_clean();

    $regex = '/Content-Length:\s([0-9].+?)\s/';
    $count = preg_match( $regex, $head, $matches );

    return isset( $matches[1] ) ? $matches[1] : "unknown";
}

我测试了一些代码但类似的行为

下载简历

http://www.media-division.com/php-download-script-with-resume-option/

4

0 回答 0