Skip to content

Instantly share code, notes, and snippets.

@sukum
Forked from toddsby/backup.php
Last active June 25, 2016 07:49
Show Gist options
  • Save sukum/1921ec3198e6cfdc9f4f73c2b8d2c90d to your computer and use it in GitHub Desktop.
Save sukum/1921ec3198e6cfdc9f4f73c2b8d2c90d to your computer and use it in GitHub Desktop.
backup.php
<?php
/*
* PHP: Recursively Backup Files & Folders to ZIP-File
* (c) 2012-2014: Marvin Menzerath - http://menzerath.eu
* contribution: Drew Toddsby
* contribution: sukum, http://stackoverflow.com/questions/15369291/how-to-ignore-directories-using-recursiveiteratoriterator
*/
// Make sure the script can handle large folders/files
ini_set('max_execution_time', 600);
ini_set('memory_limit','1024M');
// To determine line delimiter for terminal or browser
$sapi_type = php_sapi_name();
if (substr($sapi_type, 0, 3) != 'cli') {
define('LINE_DELIMITER', "<br />".PHP_EOL);
} else {
define('LINE_DELIMITER', PHP_EOL);
}
// Start the backup!
zipData('/path/to/folder', '/path/to/backup.zip');
// To exclude folders 'cache' and 'upload'
// zipData('/path/to/folder', '/path/to/backup.zip', array('cache', 'upload'));
echo 'Finished.'.LINE_DELIMITER;
// Here the magic happens :)
function zipData($source, $destination, $exclude_dirs=array()) {
if ( ! extension_loaded('zip')) {
echo 'Zip extension not present.'.LINE_DELIMITER;
return false;
}
if ( ! file_exists($source)) {
echo "Source does not exist: ".$source.LINE_DELIMITER;
return false;
}
$zip = new ZipArchive();
if ( ! $zip->open($destination, ZIPARCHIVE::CREATE)) {
echo "Could not open destination file. Check permission. - ".$destination.LINE_DELIMITER;
return false;
}
$source = realpath($source);
if (is_dir($source)) {
$iterator = new RecursiveDirectoryIterator($source);
// skip dot files while iterating
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
// Allow folders to be excluded
$filtered = new DirFilter($iterator, $exclude_dirs);
$files = new RecursiveIteratorIterator($filtered, RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = realpath($file);
if (is_dir($file)) {
//$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
// Print directory name if it is in first level
if ($files->getDepth () == 0) {
echo $file.LINE_DELIMITER;
flush();
}
} else if (is_file($file)) {
//$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
$zip->addFile($file, str_replace($source . DIRECTORY_SEPARATOR, '', $file));
}
}
} else if (is_file($source)) {
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
// To exclude directories with given array of names
class DirFilter extends RecursiveFilterIterator {
protected $exclude;
public function __construct($iterator, array $exclude) {
parent::__construct($iterator);
$this->exclude = $exclude;
}
public function accept() {
return !($this->isDir() && in_array($this->getFilename(), $this->exclude));
}
public function getChildren() {
return new DirFilter($this->getInnerIterator()->getChildren(), $this->exclude);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment