I recently had the need to do a full website backup (WordPress in this instance). I needed to zip up the main website files and MySQL database. After much trail and error, I have come up with a fairly simple solution.
WARNING: Never place zip files in a publicly accessible folder.
<?php
/**
* function to zip files and folders
*
* @author Drew Gauderman
* @version v1.0.0 Tuesday, March 24th, 2020.
* @global
* @param string $source
* @param string $destination
* @param string $prependPath
* @return void
*/
function zipIt($source = './', $destination = './website.zip', $prependPath = '')
{
// make sure the zip extension is enabled
if (!extension_loaded('zip')) {
throw new Exception('extension zip must be loaded!');
}
// zip up folder/file check
$source = realpath($source);
if (!is_dir($source) && !is_file($source)) {
throw new Exception('source must be a valid path to a folder or file!');
}
// start ZipArchive
$zip = new ZipArchive();
// create or overwrite the zip file
if ($zip->open($destination, ZIPARCHIVE::CREATE || ZIPARCHIVE::OVERWRITE) === true) {
// convert to realpath once file is created
$destination = realpath($destination);
// if folder, use recursive to grab all the contents
if (is_dir($source)) {
$iterator = new RecursiveDirectoryIterator($source);
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
// go through each file
foreach ($files as $path) {
echo "path: $path<br>";
// file full path
$path = realpath($path);
// zip entire directory
if (is_dir($path)) {
$zip->addEmptyDir($prependPath . str_replace($source . DIRECTORY_SEPARATOR, '', $path . DIRECTORY_SEPARATOR));
}
// zip file (but not the main zip file)
elseif (is_file($path) && $path !== $destination) {
$zip->addFile($path, $prependPath . str_replace($source . DIRECTORY_SEPARATOR, '', $path));
}
}
} else {
// add file to the zip
$zip->addFile($source, $prependPath . basename($source));
}
}
// close ZipArchive
$zip->close();
}
// file locations
$folderBackup = './folderToBackup';
$databaseBackup = './backup/database.sql';
$backupZip = './backup.zip';
// mysql server details
$databaseServer = 'server_url';
$databaseUsername = 'database_username';
$databasePassword = 'database_password';
$databaseName = 'database_name';
// dump the database to .sql file. "(*) 2>&1" helps to get any error messages.
$response = exec("(mysqldump --user=$databaseUsername --password='$databasePassword' --host=\"$databaseServer\" $databaseName --result-file=$databaseBackup) 2>&1");
// echo "response: $response";
// zip up the website
zipIt($folderBackup, $backupZip);
echo "Done.";
Breakdown
The main “zipIt” function takes 3 arguments:
- source: The folder to zip.
- destination: where you want to zip to be saved.
- prependPath: Allows you prepend a name, or specify a different folder path for files/folders.
Further Examples
// zip the WordPress config file to a ZIP file not in www root, and put it into a different folder within the zip
zipIt('./wp_config.php', '../backup.zip', 'siteBackups/'); // file will be saved into the zip as "siteBackups/wp_config.php
View on GitHub at https://github.com/maddog986/docker-php-website-zip
Follow
X