Skip to content

Instantly share code, notes, and snippets.

@milesrichardson
Created July 1, 2011 14:06
Show Gist options
  • Save milesrichardson/1058609 to your computer and use it in GitHub Desktop.
Save milesrichardson/1058609 to your computer and use it in GitHub Desktop.
PHP FTP Class (+Simple logging)
<?php
class Ftp {
private $conn, $current_dir;
public $log;
public function __construct($host, $username, $password, $passive = false) {
$this->log = new Log;
$this->connect($host, $username, $password, $passive);
}
private function connect($host, $username, $password, $passive = false) {
$this->conn = ftp_connect($host);
$login = ftp_login($this->conn, $username, $password);
ftp_pasv($this->conn, $passive);
if(!$this->conn || !$login)
$this->log->error('There was a login problem.', true);
$this->log->message('Sucessfully connected.');
}
public function ls($dir = '.', $raw = false) {
$ls = ($raw) ? ftp_rawlist($this->conn, $dir) : ftp_nlist($this->conn, $dir);
if(!$ls)
$this->log->error("Could not list contents of $dir", true);
return $ls;
}
public function isDir($dir) {
$original_dir = ftp_pwd($this->conn);
$result = @ftp_chdir($this->conn, $dir);
if($result) {
ftp_chdir($this->conn, $original_dir);
return true;
}
return false;
}
public function isFile($file) {
return in_array($file, $this->ls());
}
public function chmod($path, $mode_dec) {
$mode_oct = octdec(str_pad($mode_dec, 4, '0' ,STR_PAD_LEFT));
$result = ftp_chmod($this->conn, $mode_oct, $path);
if(!$result)
$this->log->error("Error changing permissions for $path to $mode_dec", true);
$this->log->message("Permissions for $path are now $mode_dec");
}
public function cd($dir) {
$result = ftp_chdir($this->conn, $dir);
if(!$result)
$this->log->error("Could not change directory to $dir", true);
$this->log->message('Current directory is now' . ftp_pwd($this->conn));
}
public function mkdir($dir, $mode_dec = null) {
$current_dir = ftp_pwd($this->conn);
$result = ftp_mkdir($this->conn, $dir);
if(!$result)
$this->log->error("Could not make directory $dir in " . ftp_pwd($this->conn), true);
$this->log->message("Made directory $dir in " . ftp_pwd($this->conn));
if(!is_null($mode_dec))
$this->chmod($dir, $mode_dec);
}
public function rmdir($dir) {
if($dir == '.' || $dir == '..')
return false; // quietly return
$result = ftp_rmdir($this->conn, $dir);
if(!$result)
$this->log->error("Could not remove directory $dir - you should ensure that it is empty.", true);
$this->log->message("Removed directory $dir");
}
public function delete($path) {
$result = ftp_delete($this->conn, $path);
if(!$result)
$this->log->error("Could not delete file $path", true);
$this->log->message("Deleted file $path");
}
public function upload($from_path, $to_path, $mode = null) {
if($mode != 'ascii' || $mode != 'binary' || $mode != FTP_ASCII || $mode != FTP_BINARY)
$mode = self::determineUploadMode($from_path);
else if(!defined($mode))
$mode = constant('FTP_' . strtoupper($mode));
$result = ftp_put($this->conn, $to_path, $from_path, $mode);
if(!$result)
$this->log->error("Error uploading $from_path to $to_path", true);
$this->log->message("Successfully uploaded $from_path to $to_path");
}
public function download($from_path, $to_path) {
$mode = self::determineUploadMode($to_path);
$result = ftp_get($this->conn, $to_path, $from_path, $mode, 0);
if(!$result)
$this->log->error('Error downloading $from_path to $to_path');
$this->log->message('Successfully downloaded $from_path to $to_path');
}
public static function determineUploadMode($path) {
$ascii_always = array('.htm', '.html', '.shtml', '.php', '.pl', '.cgi', '.js', '.py', '.cnf', '.css', '.forward', '.htaccess', '.map', '.pwd', '.txt', '.grp', '.ctl');
$extension = array_pop(explode('.', $from_path));
if(in_array($extension, $ascii_always))
return FTP_ASCII;
return FTP_BINARY;
}
public function __destruct() {
if($this->conn) ftp_close($this->conn);
}
}
class Log {
private $stack = array();
public function __construct(Log $base_log = null) {
if(!is_null($base_log))
$this->stack = $base_log->getAllItems();
}
public function message($item) {
$this->add($item, 'message');
}
public function error($item, $throw_exception = false) {
$this->add($item, 'error');
if($throw_exception)
throw new Exception($this->getLastItem()->message);
}
private function add($item, $type = null) {
if(!is_a($item, 'LogItem') && $type == null)
throw new Exception('$item passed to Log::add() must be LogItem or $type must be defined');
if(!is_a($item, 'LogItem')) $item = new LogItem($item, $type);
$this->stack[] = $item;
}
public function getLastItem() {
return end($this->stack);
}
public function getAllItems() {
return $this->stack;
}
}
class LogItem {
public $message, $type;
public function __construct($message, $type = 'error') {
$this->message = $message;
$this->type = $type;
}
public function isType($type) {
return ($this->type == $type);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment