cURL download progress in PHP

后端 未结 3 1882
我在风中等你
我在风中等你 2020-11-27 05:48

I\'m pretty new to cURL so I\'ve been struggling with this one for hours. I\'m trying to download the source of a website in an iframe using cURL and while it\'s loading to

相关标签:
3条回答
  • 2020-11-27 06:09

    What you need is

    <?php
    ob_start();
    
    echo "<pre>";
    echo "Loading ...";
    
    ob_flush();
    flush();
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://stackoverflow.com");
    //curl_setopt($ch, CURLOPT_BUFFERSIZE,128);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress');
    curl_setopt($ch, CURLOPT_NOPROGRESS, false); // needed to make progress function work
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    $html = curl_exec($ch);
    curl_close($ch);
    
    
    function progress($resource,$download_size, $downloaded, $upload_size, $uploaded)
    {
        if($download_size > 0)
             echo $downloaded / $download_size  * 100;
        ob_flush();
        flush();
        sleep(1); // just to see effect
    }
    
    echo "Done";
    ob_flush();
    flush();
    
    ?>
    
    0 讨论(0)
  • 2020-11-27 06:15

    This is how the callback looks in C:

    typedef int (*curl_progress_callback)(void *clientp,
                                          double dltotal,
                                          double dlnow,
                                          double ultotal,
                                          double ulnow);
    

    Probably in PHP it should look like

    curl_progress_callback($clientp, $dltotal, $dlnow, $ultotal, $ulnow)
    

    So, assuming you have page.html which loads a .php file in an iframe.

    In your php script, you will require the following functions:

    curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, 'curl_progress_callback');    
    curl_setopt($curl, CURLOPT_BUFFERSIZE,64000);    
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    

    which should produce an output similar to the following:

    0
    0.1
    0.2
    0.2
    0.3
    0.4
    ...
    

    then on the iframe page, you will have a progress bar

    <div id="progress-bar">
        <div id="progress">0%</div>
    </div>
    

    CSS would be something like this

    #progress-bar {
        width: 200px;
        padding: 2px;
        border: 2px solid #aaa;
        background: #fff;
    }
    
    #progress {
        background: #000;
        color: #fff;
        overflow: hidden;
        white-space: nowrap;
        padding: 5px 0;
        text-indent: 5px;
        width: 0%;
    }
    

    The javascript

    var progressElement = document.getElementById('progress')
    
    function updateProgress(percentage) {
        progressElement.style.width = percentage + '%';
        progressElement.innerHTML = percentage + '%';
    }
    

    You can have it output JavaScript and have it update the progress bar for you, for example:

    <script>updateProgress(0);</script>
    <script>updateProgress(0.1);</script>
    <script>updateProgress(0.2);</script>
    

    You might be interested in some more example code

    0 讨论(0)
  • 2020-11-27 06:25

    To use the callback inside a class, you must do it like this:

    curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array($this, 'progress'));
    

    or if using static functions, like this:

    curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array('self', 'progress'));
    

    ... to a callback function to do whatever you need:

    private static function progress($resource, $downloadSize, $downloaded, $uploadSize, $uploaded)
    {
        // emit the progress
        Cache::put('download_status', [
            'resource' => $resource,
            'download_size' => $downloadSize,
            'downloaded' => $downloaded,
            'upload_size' => $uploadSize,
            'uploaded' => $uploaded
        ], 10);
    }
    
    0 讨论(0)
提交回复
热议问题