This is a really basic non-blocking ftp client. Just put it together for fun to see if it would work. It does but I'm not sure if this is the best way of going about it.
It connects to the server and downloads all the files in the given directory.
<?php
if( $_SERVER['argc'] != 5 ) die( "Expecting 5 parameters, {$_SERVER['argc']} recieved\n" );
define( 'DL_PATH', '/home/bubblenut/ftpdownload/' );
define( 'POOL_SIZE', 10 );
$server = $_SERVER['argv'][1];
$user = $_SERVER['argv'][2];
$pass = $_SERVER['argv'][3];
$path = $_SERVER['argv'][4];
// Create the connection pool
for( $i=0; $i < POOL_SIZE; $i++ ) {
echo("Creating Connection $i...");
$ftp_pool[$i] = ftp_connect( $server ) or die( "Failed to connect to server $i) $server\n" );
ftp_login( $ftp_pool[$i], $user, $pass ) or die("Failed to log in $i) $user:$pass\n");
echo("DONE\n");
}
// Initialize the active connections array
$ftp_active = array();
// Fetch the file list
$files = ftp_nlist( $ftp_pool[0], $path ) or die( "Failed to fetch files from server" );
print_r($files);
// Set the count of the number of files we're downloading and the number of finished downloads
// This is how we decide to terminate the loop
$files_c = count($files);
$done_c = 0;
// Used to see if we have to continue dishing out connections
$more_files = true;
// Loop until we've downloaded all the files
while( $done_c < $files_c ) {
// Loop until the connection pool is empty
while( count( $ftp_pool ) && $more_files ) {
// if there's no files left to download then set a complete flag and break
if( !count( $files ) ) { $more_files=false; break; }
// fetch an ftp connection and pair it with a file
$con = array_pop( $ftp_pool );
$file = array_pop( $files );
// Use up one of the pooled connections on one of the files awaiting download.
$ftp_active[] = array( $con, ftp_nb_get( $con, DL_PATH . $file, $file, FTP_BINARY ) );
}
// While there's no available connection in the pool or while there's no more files to get but still active downloads
while( !count( $ftp_pool ) || ( !$more_files && count( $ftp_active ) ) ) {
// Loop through the active downloads array
for($i=0; $i < count($ftp_active); $i++) {
if( !isset( $ftp_active[$i][1]) ) print_r( $ftp_active );
if( $ftp_active[$i][1] == FTP_MOREDATA ) {
// If there's more data then continue the download
$ftp_active[$i][1] = ftp_nb_continue( $ftp_active[$i][0] );
} elseif( $ftp_active[$i][1] == FTP_FINISHED ) {
// If the download is finished then swap the connection reference back to the pool
// and remove this item from the active downloads array
$ftp_pool[] = $ftp_active[$i][0];
unset( $ftp_active[$i] );
$ftp_active = array_values( $ftp_active );
$done_c++;
}
}
}
}
?>
Cheers