PHP cURL - 获取剩余下载时间

时间:2015-02-04 16:14:55

标签: php curl

我正在为我的用户提供远程上传功能,以直接从我的服务器上下载内容(例如)他们自己的服务器而不是本地上传。为此,我正在使用cURL。现在我想得到cURL需要完成下载的剩余时间(比特率也可以。)

有没有办法可以返回cURL需要通过PHP curl模块完成下载的剩余时间,还是我需要运行命令行界面并以某种方式将输出放在一个文件中然后从那里读取(因为使用shell_exec()exec())时,PHP会阻止执行吗?

我已经获得了预期下载的字节数和已下载的curl数。到目前为止,这是相关的代码:

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)."\n", 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)."\n", FILE_APPEND);
    die(json_encode(array("success" => 0, "response" => $language->word('remote_file_not_available'))));
}

curl_close($ch);
fclose($file);

1 个答案:

答案 0 :(得分:5)

PHP的cURL库似乎没有提供剩余的估计时间,但使用CURLOPT_PROGRESSFUNCTION回调函数从PHP计算它是相当简单的。我在下面创建了一个工作示例。请注意,如果启用GZIP压缩,输出可能会延迟,直到整个请求完成。

实施例

<?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 );