Location: PHPKode > scripts > Backup Class > backup-class/class.backup.php
<?php
/*
* This class backups folders from your local filesystem.
* It saves them on a selected ftp server or on your local filesystem.
* Old backups are deleted (see $max_age) but you can ensure that there will be always a certain number of backups (see $min_backup_num)
* Author: Mark Simkin, Germany;
* mail: hide@address.com;
* version: 1.0 /31.07.2006
* 
*/ 

class backupclass {
	
	// This is an array containing all paths to the Folders and Files, which will be archived
	var $backup_dirs; 
	
	//This Variable shows the max age of the archives in days, every archiv older then this variable is going to be deleted!
	var $max_age = 5;

	// With this Variable you can secure, that you will have at least $min_backup_num of archivs, even though the are older then $max_age
	var $min_backup_num = 1;
	
	// This is the path where tar is installed, eventually you have to change it.
	var $tar_path = '/bin/'; 
	
	// This array is saving all error_messages
	var $log = array(); 
	
	//This is the data needed to connect to the ftp server
	var $host;
	var $user;
	var $pass;
	
	//This is the stream to the ftp server. Use the config_ftp function to open a stream.
	var $ftphandler; 
	
	/*
	* backupclass
	* This is the Constructor.
	* param $backup_dirs	array paths to the folders which will be archived.
	*
	* return bool	Return true on success, false on failure
	*/
	function backupclass($backup_dirs) { 
		if(!is_array($backup_dirs)) {
			$this->log [] = '$backup_dirs isnĀ“t an array!';
			return false;
		}
		foreach($backup_dirs as $current_dir)
		{
			if(!$this->add_backup_dir($current_dir)) return false;
		}
		return true;
	}
	
	/*
	* add_backup_dir
	* With this function one can add dirs
	* param $dir	string the path of the folder which is going to be achived.
	* 
	* return bool	Return true on success, false on failure
	*/
	function add_backup_dir($dir) {
		if(!$this->check_dir($dir))return false;
		$this->backup_dirs[] = realpath($dir);
		return true;		
	}
	
	/*
	* config ftp
	* This function is trying to connect to the ftp server.
	* param $host	string Host of the ftp server
	* param $user	string user of the ftp server
	* param $password	string password of ftp server
	* 
	* return bool	Return true on success, false on failure
	*/
	function config_ftp($host,$user,$password) { 
		$this->host = $host;
		$this->user = $user;
		$this->pass = $password;
		
		/*
		If there is already an other ftp stream, then the old stream will be shut down and the new one will be created
		*/
		if(!empty($this->ftphandler)) { 
			ftp_quit($this->ftphandler);
			unset($this->ftphandler);
		}
		/*
		If the connection fails, then an error message will be written into the log array $log
		*/
		if(@!$this->ftphandler = ftp_connect ($this->host)) { 
			$this->log[] = "not able to connect to '" . $this->host . "'";
			return false;
		}
		/*
		When the password or the username is wrong, then there will be written an errormessage into the log array $log
		*/
		if(@!ftp_login ( $this->ftphandler , $this->user, $this->pass)) {
			$this->log[] = "Login or password incorrect";
			return false;
		}
		return true;
	}

	/*
	* set_max_age
	* This is the setter function for $max_age. The max age shows how old an archiv can be.
	* param $days	int	maximum age in days of an archive.
	*
	* return bool	Return true on success, false on failure
	*/
	
	function set_max_age($days) { 
		$this->max_age = intval($days);
		if($this->max_age > 0) {
			return true;
		}
		else {
			$this->log[] = '$max_age can not be smaller then 1';
			return false;
		}
	}
	
	/*
	* set_min_backup_number
	* This is the setter function for $min_backup_num. The min_backup_num shows how much archivs of one folder must be at least kept
	* param	$number	int min number of archivs
	*/
	function set_min_backup_number($number) { 
		$this->min_backup_num = intval($number);
	}

	/*
	* set_tar_path
	* Here you can change the tar path.
	* param $path	string the path to tar
	* 
	* return bool	Return true on success, false on failure
	*/
	function set_tar_path($path) { 
		if(!$this->check_dir($path)){
			$this->log[] = 'Wrong tar path "' . $path . '"';
			return false;
		}
	}
	
	/*
	* check_archives
	* This function is checking the max_age and is deleting every overaged archiv if there are more then $min_backup_num
	* param $mode	string setting the mode (ftp or filesystem)
	* param $path	string string the path to the archives 
	* 
	* return bool	Return true on success, false on failure
	*/
	function check_archives($mode,$path = '.') { 
		if($mode == 'ftp') {
			@ftp_mkdir ($this->ftphandler, $path . "/");
			$tmp = ftp_nlist ( $this->ftphandler, $path); //getting a array with the content of $path from ftp
			for($c = 0;$c < count($tmp);$c++) {
				$tmp_r = explode('/', $tmp[$c]);
				$dir[] = $tmp_r[count($tmp_r)-1];
			}
		}
		else if($mode == 'filesys') { //getting a array with the content of $path from filesystem
			
			if(!is_dir($path)){
				mkdir ($path);
				chmod ($path, 0777);
			}
			$handle=opendir($path); 
			while ($file = readdir ($handle)) { 
			    if ($file != "." && $file != "..") { 
			        $dir[] = $file;
			    }
			}
			closedir($handle);
		}
		else {
			$this->log[] = "Unkown mode '" . $mode . "'. Failed to check.";
			return false;
		}
		
		foreach($dir as $current_file) {
			//searching for archives visible by the class-specific filename
			if(preg_match("/^(\d{6}_){2}.+\.tgz$/", $current_file)) {
				$today = mktime(0, 0, 0, date("m")  , date("d"), date("Y"));
				$old_time = mktime(0, 0, 0, substr($current_file,2,2)  , substr($current_file,4,2)+$this->max_age, substr($current_file,0,2));
				
				//if the old timestamp + the max age is smaller then the timestamp from today, then the file is overaged
				if(($today - $old_time) > 0) {
					
					$counter = 0; //counting the number of backups for this file(s)

						for($z = 0;$z < count($dir);$z++) {
							if(substr($dir[$z],14,strlen($dir[$z])) == substr($current_file,14,strlen($dir[$z]))) { 
								$counter++;
							}
						}
						
					//if there are more then min_backup_num backups then the current file will be deleted
					if($counter > $this->min_backup_num) {
						if($mode == 'ftp') {
							$bool = ftp_delete ( $this->ftphandler, $path . "/" . $current_file);
						}

						if($mode == 'filesys') {
							$bool = unlink($path . "/" . $current_file);
						}
						if($bool == false) {
							$this->log[] = 'Could not delete ' . $current_file . ' from filesystem';
							return false;
						}
					}
				}
			}
		}
	return true;
	}

	/*
	* check_dir
	* Checking $dir.Can I find it? Is it readable?
	*
	* param string $dir	Directory to check
	* return bool	Return true on success, false on failure
	*/
	function check_dir($dir) {
		if(!is_dir($dir)) {
			$this->log[] = 'could not found ' . $dir;
			return false;
		}
		if(!is_readable($dir)) {
			$this->log[] = 'permission for ' . $dir . ' denied';
			return false;
		}
		return true;
	}
	
	/*
	* backup
	* This Function is creating the backups on the filesystem or on an ftp server. 
	* If $path is not given, then the backups will be saved in the current folder
	*
	* param $mode	string setting the mode (ftp or filesystem)
	* param $path	string string the path where the archives are going to be saved
	* 
	* return bool	Return true on success, false on failure
	*/
	function backup($mode,$path = '.') {
		if($mode != 'ftp' && $mode != 'filesys') {
			$this->log[] = 'could not create backup. Unkown mode :' . $mode;
			return false;
		}
		foreach($this->backup_dirs as $current) {
			if($path == $current) { //backup folder and target folder can not be the same
				$this->log[] = 'Target Folder can not be the backup folder';
				return false;
			} 
			
			if(substr($current,-1) == '/') {
				$current = substr($current,0,-1);
			}
		
			$tmp_r = explode('/', $current); //detecting the folder
			$dir_name = $tmp_r[count($tmp_r)-1];
		
			$archiv_name = date('ymd_his') . "_" . $dir_name . ".tgz";	
			$archiv_name = str_replace('"', "''", $archiv_name);
			$current = str_replace('"', "'", $current);
			
			if($mode == 'filesys') { //Creating folder if need be
				if(!is_dir($path)){
					mkdir ($path);
					chmod ($path, 0777);
				}
				/*
				this is the command which will be send to the shell.
				*/
				$command = $this->tar_path . "tar cvzf " . escapeshellarg($path . "/" . $archiv_name) . " " . escapeshellarg($current);
				passthru ($command, $return);
			}
			else if($mode == 'ftp') {

				@ftp_mkdir ($this->ftphandler, $path . "/");
				$command = $this->tar_path . "tar cvzf " . escapeshellarg($archiv_name) . " " . escapeshellarg($current);
				passthru ($command, $return);
				if(ftp_put ($this->ftphandler, $path . "/" . $archiv_name, $archiv_name, FTP_BINARY) === false) {
					$this->log[] = 'could not write on ftp';
					return false;	
				}
				unlink($archiv_name);
			}
		}
	}
}
?>
Return current item: Backup Class