cURL download progress in PHP

Discussion in 'PHP' started by shuman202, Jan 15, 2013.

  1. #1
    i have the following code which works fine

    
        $url  = 'http://www.example.com/a-large-file.zip';
        $path = '/path/to/a-large-file.zip';
    
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
        $data = curl_exec($ch);
    
        curl_close($ch);
    
        file_put_contents($path, $data);
    
    Code (markup):
    i need to show a progress bar
    is there any way to show a progressbar using ajax or javascript
     
    shuman202, Jan 15, 2013 IP
  2. goliath

    goliath Active Member

    Messages:
    308
    Likes Received:
    11
    Best Answers:
    0
    Trophy Points:
    60
    #2
    Progress bars are not often accurate, except for some local (same system) operations.

    That's why you see so many "loading" gif are just spinning or other loopable animations.

    You can set innerHTML to a loading or progress animation and then reset it when you get a response, or finish your download.

    Unless you have live code on both servers verifying all file size information and actively monitoring bits sent/recevied vs file size and only update the progress bar when each package is received at the "client" side you will not have an accurate status bar for an internet file transfer.


    EDIT:

    Even then your progress bar will indicate progress on the transfer (bits received) but has no way to indicate the time that will be required to complete the operation.
     
    goliath, Jan 15, 2013 IP
  3. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #3
    
    bps = time elapsed / size received;
    Remaining Time = (Total size - size received) * bps
    
    Code (markup):
     
    ThePHPMaster, Jan 15, 2013 IP
  4. goliath

    goliath Active Member

    Messages:
    308
    Likes Received:
    11
    Best Answers:
    0
    Trophy Points:
    60
    #4
    Past performance is no indication of future results :)
     
    goliath, Jan 15, 2013 IP
  5. SteveSRS

    SteveSRS Member

    Messages:
    5
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    31
    #5
    very true.. better idea is just to display total amount of kb (mb) to download and display how much kb/mb is already downloaded.
    You can make it graphical by assigning say 1 px wide for every kb and so filling the bar using ajax calls.
     
    SteveSRS, Jan 15, 2013 IP
  6. goliath

    goliath Active Member

    Messages:
    308
    Likes Received:
    11
    Best Answers:
    0
    Trophy Points:
    60
    #6
    Sure bit then it makes 1024 ajax calls to the server per MB updated (at that rate). Even if yo umeter a bar to approximately 1% that's 100 transactions to process for any transfer regardless of size.

    On a slow connection you're wrecking the bandwidth for the status and on a good connection you might be sending multiple ajax requests before receiving a response.

    It's a classic problem, the more you make the bar precise, the more it destroys your throughput or hobbles your other resources.

    In most cases, something that indicates "it's working" will be enough.
     
    goliath, Jan 15, 2013 IP
  7. SteveSRS

    SteveSRS Member

    Messages:
    5
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    31
    #7
    hmm yes in retrospect agree with you goliath..
    That is why those 'loading' animated gifs (/pngs) are popular ;)
     
    SteveSRS, Jan 16, 2013 IP
  8. ironmankho

    ironmankho Active Member

    Messages:
    393
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    55
    #8
    <?php
    
    file_put_contents( 'progress.txt', '' );
    
     
    
    $targetFile = fopen( 'testfile.iso', 'w' );
    
     
    
    $ch = curl_init( 'http://ftp.free.org/mirrors/releases.ubuntu-fr.org/11.04/ubuntu-11.04-desktop-i386-fr.iso' );
    
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    curl_setopt( $ch, CURLOPT_NOPROGRESS, false );
    
    curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'progressCallback' );
    
    curl_setopt( $ch, CURLOPT_FILE, $targetFile );
    
    curl_exec( $ch );
    
    fclose( $ch );
    
     
    
    function progressCallback( $download_size, $downloaded_size, $upload_size, $uploaded_size )
    
    {
    
    static $previousProgress = 0;
    
    if ( $download_size == 0 )
    
    $progress = 0;
    
    else
    
    $progress = round( $downloaded_size * 100 / $download_size );
    
    if ( $progress > $previousProgress)
    
    {
    
    $previousProgress = $progress;
    
    $fp = fopen( 'progress.txt', 'a' );
    
    fputs( $fp, "$progress\n" );
    
    fclose( $fp );
    
    }
    
    }
    
     
    
    ?>
    PHP:
     
    ironmankho, Jan 16, 2013 IP
  9. shuman202

    shuman202 Well-Known Member

    Messages:
    638
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    145
    Digital Goods:
    1
    #9
    thank you it really helps
     
    shuman202, Jan 16, 2013 IP