I was recently working on a project that involved FTP and I thought it would be a great chance to get away from the built-in PHP functionality and use the CodeIgniter FTP library instead.
I was pretty surprised to find that there was no download functionality in the base FTP library as of CI 1.7.2. I’ve extended the library to incorporate file download and will share that here.
<?php // This codes goes in the 'application/libraries' folder with a // file name of MY_Ftp.php class MY_Ftp extends CI_Ftp { /** * Constructor **/ function MY_Ftp() { parent::CI_Ftp(); } /** * Download a file from a FTP server * @param <string> $rem_path Remote path of the file to download * @param <string> $loc_path Local path destination for download * @param <string> $mode Transfer mode, defaults to auto **/ function download($rem_path, $loc_path, $mode='auto') { // check for an active connection if ( ! $this->_is_conn()) { return FALSE; } // get remote folder/filename $rem_folder = dirname($rem_path); $rem_filename = basename($rem_path); // if a local directory was passed handle differently. // Otherwise, treat same as remote. if (@is_dir($loc_path)) { $loc_folder = rtrim($loc_path, '/'); $loc_filename = $rem_filename; } else { $loc_folder = dirname($loc_path); $loc_filename = basename($loc_path); } // check that the loc path exists if ( $loc_folder != '.' && ! @is_dir($loc_folder)) { $this->_error('ftp_bad_loc_path'); return FALSE; } // check that loc path and file are writable elseif ( ! @is_writable($loc_folder) OR (file_exists($loc_folder.'/'.$loc_filename) && ! @is_writable($loc_folder.'/'.$loc_filename))) { $this->_error('ftp_loc_not_write'); return FALSE; } // store old paths $old_rem_path = @ftp_pwd($this->conn_id); $old_loc_path = getcwd(); // move to the local path if ( ! @chdir($loc_folder)) { $this->_error('ftp_bad_loc_path'); return FALSE; } // move to the remote path if ( $rem_folder != '.' && ! $this->changedir($rem_folder)) { $this->_error('ftp_bad_rem_path'); return FALSE; } // check that the file exists remotely $found_file = FALSE; $files = $this->list_files(); if (count($files) > 0) { foreach ($files as $f) { if ($f == $rem_filename) { $found_file = TRUE; break; } } } if ( ! $found_file) { $this->_error('ftp_bad_rem_file'); return FALSE; } // Set the mode if not specified if ($mode == 'auto') { // Get the file extension so we can set the upload type $ext = $this->_getext($rem_path); $mode = $this->_settype($ext); } $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY; // download the file $result = @ftp_get($this->conn_id, $loc_folder.'/'.$loc_filename, $rem_filename, $mode); if ($result === FALSE) { if ($this->debug == TRUE) $this->_error('ftp_unable_to_download'); return FALSE; } // move back to the root path $this->changedir($old_rem_path); @chdir($old_loc_path); return TRUE; } } ?>
As a side note, you will need to tweak your language file to include all of the message codes (e.g., ftp_bad_loc_path) passed to _error() for proper error display in your app.








Comments
3 Comments
Thank you for this! Really weird that it isn’t default in CI.
Anyway, I has to put the document root in local path parameter to get it to work. So my call would be:
download(‘file/to/get’, $_SERVER['DOCUMENT_ROOT'] . ‘/images/’);
If anyone doesn’t get it to work!
Thanks for the tip, Victor. Great point!
Thanks for posting this code, however I found something need to be added in. In case remote file is not exists add
@chdir($old_loc_path); before return false.
Thanks