8

I'm trying to write a script that will download files from an FTP server. They're all fairly large (nearly 2GB each). The script starts running, but then eventually terminates with the above error. Is it size related? Is there a way around this? Here's the code:

<?php

$ftp_server = "ftp.EXAMPLE.com";
$conn_id = ftp_connect ($ftp_server) or die("Couldn't connect to $ftp_server");
$login_result = ftp_login($conn_id, "USERNAME", "PASSWORD");
if ((!$conn_id) || (!$login_result)) die("FTP Connection Failed");
ftp_sync("download");   
ftp_close($conn_id); 

$mkdir = date('Y-m-d');
mkdir('encrypted/'.$mkdir, 0777);
smartCopy("./download/", 'encrypted/'.$mkdir);
chmodr("encrypted/".$mkdir, 0777);

function ftp_sync ($dir) {

    global $conn_id;

    if ($dir != ".") {
        if (ftp_chdir($conn_id, $dir) == false) {
            echo ("Change Dir Failed: $dir<BR>\r\n");
            return;
        }
        if (!(is_dir($dir)))
            mkdir($dir);
        chdir ($dir);
    }

    $contents = ftp_nlist($conn_id, ".");
    foreach ($contents as $file) {

        if ($file == '.' || $file == '..')
            continue;

        if (@ftp_chdir($conn_id, $file)) {
            ftp_chdir ($conn_id, "..");
            ftp_sync ($file);
        }
        else
            ftp_get($conn_id, $file, $file, FTP_BINARY);
    }

    ftp_chdir ($conn_id, "..");
    chdir ("..");

}

function chmodr($path, $filemode) {
    if (!is_dir($path))
        return chmod($path, $filemode);

    $dh = opendir($path);
    while (($file = readdir($dh)) !== false) {
        if($file != '.' && $file != '..') {
            $fullpath = $path.'/'.$file;
            if(is_link($fullpath))
                return FALSE;
            elseif(!is_dir($fullpath) && !chmod($fullpath, $filemode))
                    return FALSE;
            elseif(!chmodr($fullpath, $filemode))
                return FALSE;
        }
    }

    closedir($dh);

    if(chmod($path, $filemode))
        return TRUE;
    else
        return FALSE;
}

function smartCopy($source, $dest, $folderPermission='0777',$filePermission='0777'){

    $result=false;

    if (is_file($source)) {
        if(is_dir($dest)) {
            if ($dest[strlen($dest)-1]!='/') 
                $__dest=$dest."/";
            $__dest .= basename($source);
            }
        else { 
            $__dest=$dest;
            }
        $result=copy($source, $__dest);
        chmod($__dest,$filePermission);
        }
    elseif(is_dir($source)) { 
        if(!is_dir($dest)) {
            @mkdir($dest,$folderPermission);
            chmod($dest,$folderPermission);
            }
        if ($source[strlen($source)-1]!='/') 
            $source=$source."/";
        if ($dest[strlen($dest)-1]!='/') 
            $dest=$dest."/";

        $return = true;
        $dirHandle=opendir($source);
        while($file=readdir($dirHandle)) { 
            if($file!="." && $file!="..") { 
                $result=smartCopy($source.$file, $dest.$file, $folderPermission, $filePermission);
                }
            }
        closedir($dirHandle);
        }
    else {
        $result=false;
        }
    return $result;
}

function deleteDirectory($dir) {
    if (!file_exists($dir)) return true;
    if (!is_dir($dir) || is_link($dir)) return unlink($dir);
        foreach (scandir($dir) as $item) {
            if ($item == '.' || $item == '..') continue;
            if (!deleteDirectory($dir . "/" . $item)) {
                chmod($dir . "/" . $item, 0777);
                if (!deleteDirectory($dir . "/" . $item)) return false;
            };
        }
        return rmdir($dir);
    } 
?>
whitman6732
  • 465
  • 3
  • 8
  • 12

5 Answers5

21

I was having a similar problem and using the following solved it for me.

ftp_pasv($conn_id, TRUE);  
animuson
  • 53,861
  • 28
  • 137
  • 147
Silverback
  • 2,116
  • 1
  • 16
  • 7
7

For anyone who might come by this question because of having the same issue. For me it was rather simple, the target location for the download didn't have enough free space for the file.

Oliver Salzburg
  • 21,652
  • 20
  • 93
  • 138
  • Seems like a strange warning for that, and I'd have expected an error instead. – Lightness Races in Orbit May 20 '11 at 15:34
  • This was my problem too. Thanks! – Tyler V. Jan 10 '15 at 00:23
  • A similar error message may occur when uploading files and reaching disk space limit. Raw FTP data reveals the details: ```Response: 150 Opening BINARY mode data connection for foobar.csv Response: 552 Transfer aborted. Disk quota exceeded Error: File transfer failed after transferring 15.217.020 bytes in 13 seconds ``` – marcovtwout Sep 28 '22 at 11:15
2

Try to increase FTP_TIMEOUT (the default value is 90)

ftp_set_option($conn_id, FTP_TIMEOUT_SEC, 180);

It worked perfectly for me.

http://www.php.net/manual/en/function.ftp-set-option.php

Daryl Gill
  • 5,464
  • 9
  • 36
  • 69
Svoka
  • 39
  • 2
0

Try using ftp_close and ftp_connect as to reset your FTP connection.

I had spent a good day on this one, trying everything I could find (ftp_pasv, ftp_alloc, changing to FTP_ASCII/FTP_BINARY), with no success.

Some servers have limits on how much you can upload per session.

Zuul
  • 16,217
  • 6
  • 61
  • 88
0

Are you sure each file is binary?

You may try to guess the file type from its extension in order to adjust the download mode, as suggested in this comment: http://www.php.net/manual/fr/function.ftp-get.php#86516

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055