Created
July 1, 2011 14:06
-
-
Save milesrichardson/1058609 to your computer and use it in GitHub Desktop.
PHP FTP Class (+Simple logging)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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