MartyIX
MartyIX

Reputation: 28648

How to download part of a file via FTP in PHP?

I would like to download parts of files on a FTP server. I've got this solution:

  $opts = array('ftp'=>array('overwrite'=>false, 'resume_pos'=> 5*16+12));      
  $context = stream_context_create($opts);

  $version = file_get_contents
    (
     'ftp://'.$ftpAccount["username"].':'.$ftpAccount["password"].'@'.$ftpAccount["server"].'/firm/'.$file, FILE_BINARY, $context, -1, 20
    );

I don't like this solution because it opens new connection for every file. Does anybody know a better solution (effective one)?

Upvotes: 1

Views: 2439

Answers (2)

Wouter
Wouter

Reputation: 9

I came across this page, when looking for a solution for this problem myself. I found nothing, so I made something up myself.

May not be the prettiest solution, but this worked for me:

It downloads the remote file in chunks of 512000 bytes. When all chunks are downloaded, it puts together the local file and removes the chunks. It always overwrites the local file (in fact it deletes the local file before starting to write the chunks to it).

I hope this helps someone.

I guess if I was willing to make it cleaner I could use curl as well to determine the remote file size. But I am more of the 'duct-tape-programmer'. It works this way and that's all that matters to me :-)

$server = '...'; //for example ftp.testftp.nl
$full_remoteURI = '...'; // for example ftp://ftp.testftp.nl/exports/dump.xml
$username = '...';
$passwrd = '...';
$remote_ftp_path = '...'; // for exmple /exports
$remote_filename = '...';
$local_filename = '...';

    $ftpconnect = ftp_connect($server);
    if($ftpconnect) $login = ftp_login($ftpconnect, $username, $passwrd);
    else print "<p>FTP verbinding mislukt.</p>\n";
    if($login) {
    ftp_chdir($ftpconnect, $remote_ftp_path);
    $fsize = ftp_size($ftpconnect, $remote_filename);
        if(isset($_GET['f'])) $f = $_GET['f'];
        else $f = 0;
        if($f > 0) $start = ($f * 512001);
        else $start = 0;
        if($start < $fsize) {
        $curl = curl_init();
        $file = fopen($local_filename . $f, 'w');
        curl_setopt($curl, CURLOPT_URL, $full_remoteURI); #input
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_FILE, $file); #output
        curl_setopt($curl, CURLOPT_RANGE, $start . "-" . ($start + 512000));
        curl_setopt($curl, CURLOPT_USERPWD, $username . ":" . $passwrd);
        curl_exec($curl);
        $voltooid = number_format(100 * $start / $fsize, 0, '','');
        print "<p>XML bestanden downloaden $voltooid %.</p>
        <script type=\"text/javascript\">
        <!--
        document.onload = top.location = 'sync.php?f=" . ($f + 1) . "';
        -->
        </script>\n";
        }
        else {
            $del = unlink($local_filename);
            if(!$del) print "<p>Oude bestand verwijderen mislukt!</p>\n";
            $fh = fopen($local_filename, 'w');
            for($i = 0; $i < $f; $i++) {
                $data = file_get_contents($local_filename . $i);
                fwrite($fh, $data);
                unlink($local_filename . $i);
            }
            fclose($fh);
            print "<p>Downloaden voltooid.</p>\n";
        }
    }
    else print "<p>Login failed</p>\n";

Upvotes: 0

goat
goat

Reputation: 31813

Heres a similar question asked of the curl library. http://curl.haxx.se/mail/lib-2005-01/0176.html

Looks like you can't reuse connections with ftp, unlike http.

Upvotes: 1

Related Questions