dongpang9573 2015-02-04 16:14 采纳率: 0%
浏览 40
已采纳

PHP cURL - 获取剩余下载时间

I am offering my users to use remote-upload to download the content directly on my server from (for example) their own server instead of local uploads. For that I'm using cURL. And now I want to get the remaining time cURL needs to complete the download (bitrate would be fine too).

Is there a way I can return the remaining time cURL needs to finish the download via the PHP curl module or do I need to run the command-line interface and somehow put the output in a file and then read from there (since PHP blocks execution when using shell_exec() or exec())?

I'm already getting the bytes expected to download and how many curl already downloaded. This is the associated code as far:

function write_progress($ch, $original_size, $current_size, $os_up, $cs_up) {
    global $anitube, $cache;

    $cache->write("webupload-progress-".$anitube->input['inputname'], serialize(array("total" => $original_size, "loaded" => $current_size)));
}

ini_set('max_execution_time', '0');
$handle_file = "/tmp/file-".$anitube->generate(20).".tmp";
if(DIRECTORY_SEPARATOR == "\\") {
    $handle_file = IN_DIR.$handle_file;
}

$file = fopen($handle_file, "w+");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, urldecode(trim($anitube->input['filename'])));
curl_setopt($ch, CURLOPT_FILE, $file);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, "write_progress");
if($anitube->users['ip'] == "127.0.0.1") {
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}

$data = curl_exec($ch);
if(curl_errno($ch) > 0) {
    file_put_contents(IN_DIR."/logs/curl_errors.txt", date("d.m.Y H:i:s")." - Errno: ".curl_errno($ch)." - Error: ".curl_error($ch)." -  cURL 4: ".print_r(curl_getinfo($ch), true)."
", FILE_APPEND);
    die(json_encode(array("success" => 0, "response" => $language->word('remote_file_not_available'))));
} elseif(curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
    file_put_contents(IN_DIR."/logs/curl_errors.txt", date("d.m.Y H:i:s")." - Error: Connection denied - HTTP-Response-Code: ".curl_getinfo($ch, CURLINFO_HTTP_CODE)." -  cURL 4: ".print_r(curl_getinfo($ch), true)."
", FILE_APPEND);
    die(json_encode(array("success" => 0, "response" => $language->word('remote_file_not_available'))));
}

curl_close($ch);
fclose($file);
  • 写回答

1条回答 默认 最新

  • dongtu1789 2015-02-07 03:36
    关注

    PHP's cURL library does not appear to provide the estimated time remaining, but it is fairly trivial to calculate this from PHP using the CURLOPT_PROGRESSFUNCTION callback function. I've created a working example below. Note that if GZIP compression is enabled, the output will probably be delayed until the entire request is complete.

    Example:

    <?php
    
    header( 'Content-Type: text/plain' );
    
    //A helper function to flush output buffers.
    function flush_all() {
        while ( ob_get_level() ) {
            ob_end_flush();
        }
        flush();
    }
    
    $download_start_time = null;
    function write_progress( $ch, $original_size, $current_size, $os_up, $cs_up ) {
        global $download_start_time;
        //Get the current time.
        $now = microtime( true );
        //Remember the start time.
        if ( ! $download_start_time ) {
            $download_start_time = $now;
        }
        //Check if the download size is available yet.
        if ( $original_size ) {
            //Compute time spent transfering.
            $transfer_time = $now - $download_start_time;
            //Compute percent already downloaded.
            $transfer_percentage = $current_size / $original_size;
            //Compute estimated transfer time.
            $estimated_tranfer_time = $transfer_time / $transfer_percentage;
            //Compute estimated time remaining.
            $estimated_time_remaining = $estimated_tranfer_time - $transfer_time;
            //Output the remaining time.
            var_dump( $estimated_time_remaining );
            flush_all();
        }
    }
    
    //Example usage.
    $file = fopen( 'tmp.bin', "w+");
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, 'https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/35.0.1/win32/en-US/Firefox%20Setup%2035.0.1.exe' );
    curl_setopt( $ch, CURLOPT_FILE, $file );
    curl_setopt( $ch, CURLOPT_NOPROGRESS, false );
    curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'write_progress' );
    $data = curl_exec( $ch );
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 对于知识的学以致用的解释
  • ¥50 三种调度算法报错 有实例
  • ¥15 关于#python#的问题,请各位专家解答!
  • ¥200 询问:python实现大地主题正反算的程序设计,有偿
  • ¥15 smptlib使用465端口发送邮件失败
  • ¥200 总是报错,能帮助用python实现程序实现高斯正反算吗?有偿
  • ¥15 对于squad数据集的基于bert模型的微调
  • ¥15 为什么我运行这个网络会出现以下报错?CRNN神经网络
  • ¥20 steam下载游戏占用内存
  • ¥15 CST保存项目时失败