1
\$\begingroup\$

I'm attempting to backup lots of website using this php code. The script basically goes through the whole public_html directory and adds all the folders and files recursively and zips them.

Here's what I've got so far:

if (!file_exists('/home/sites/'.$_SERVER['SERVER_NAME'].'/cbitsbackup/')) {
mkdir('/home/sites/'.$_SERVER['SERVER_NAME'].'/cbitsbackup/', 0777, true);
}
$filefront = '/home/sites/'.$_SERVER['SERVER_NAME'].'/cbitsbackup/backup-'.$_SERVER['SERVER_NAME'].'-day1';
$fileend = '.zip';
$time = time();
if(file_exists($filefront.$fileend)){
$file = $filefront.'-'.$time.$fileend;}
else{$file = $filefront.$fileend;};
zip_directory('/home/sites/'.$_SERVER['SERVER_NAME'].'/public_html',$file);
function zip_directory($source,$tempfile){
if(!extension_loaded('zip') || !file_exists($source)) return false;
$zip = new ZipArchive();
if(!$zip->open($tempfile,ZIPARCHIVE::CREATE)) return false;
$source = str_replace('\\','/',realpath($source));
if(is_dir($source) === true){
 $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
 foreach($files as $file){
 $file = str_replace('\\', '/', realpath($file));
 if(is_dir($file) === true) $zip->addEmptyDir(str_replace($source . '/','', $file . '/'));
 else if(is_file($file) === true) $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));}}
elseif(is_file($source) === true) $zip->addFromString(basename($source), file_get_contents($source));
return $zip->close();}

The main problem at the moment is memory constraints (64M) because I'm running on a shared hosting platform. As far as I can see, the zip file is stored in memory until it is 'completed'. This is problem because I have a lot of websites which are much over this size. Is there anyway to write the zip file progressively to disk so my script isn't killed by the system? Could I even write this in Perl to get around this limit?

200_success
146k22 gold badges190 silver badges479 bronze badges
asked Nov 1, 2014 at 11:12
\$\endgroup\$
5
  • \$\begingroup\$ Welcome to Code Review! This is one of the gray areas of code review. Given enough memory, your script works, but not given enough memory, it breaks. I personally find your question on the good side of this line. While it may be possible that rewriting it in another language can solve it, the primary focus of Code Review is making the code you put here better. \$\endgroup\$ Commented Nov 1, 2014 at 13:05
  • \$\begingroup\$ @simon-andre-forsberg Okay thank you. I was very unsure whether to put my question here or whether it would be better suited on StackOverflow. Do you think I might have some more answers on there? \$\endgroup\$ Commented Nov 1, 2014 at 13:22
  • \$\begingroup\$ I would not recommend cross posting. Only ask on StackOverflow if your question gets closed here, currently it does not look like it will get closed here. (no close votes) \$\endgroup\$ Commented Nov 1, 2014 at 13:42
  • \$\begingroup\$ Why do you need to backup the files? Isn't this what a revision control system is for? \$\endgroup\$ Commented Nov 6, 2014 at 15:59
  • \$\begingroup\$ @MikeBrant This is pretty much an impossible task without SSH access. Something like rsync would have been nice to use, but to get access to SSH with Heart Internet requires a handwritten form per website. Being a reseller (with 98 sites) this would be very impractical. \$\endgroup\$ Commented Nov 6, 2014 at 16:05

2 Answers 2

2
\$\begingroup\$

As you are using Linux, use this in a PHP file:

<?php system('zip -r backup *'); ?>

This will create a ZIP of all files/directories exists in the directory.

answered Nov 1, 2014 at 11:17
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Thats an idea... Do you think I'm allowed to use system executables on shared hosting? \$\endgroup\$ Commented Nov 1, 2014 at 11:20
  • \$\begingroup\$ It depends hosting to hosting. But this can be an easy solution, if you have access to. Give it a try at-least. \$\endgroup\$ Commented Nov 1, 2014 at 11:21
  • \$\begingroup\$ I contracted my host and they replied saying that i can not use system() or exec() calls. Trying to do this in my script confirmed it. Oddly, they don't block passthru() calls so this is what I'm know using. Thanks for your answer \$\endgroup\$ Commented Nov 3, 2014 at 7:46
  • \$\begingroup\$ Why not <?php `zip -r backup *`;? The backtick operator is way shorter and does exactly the same job. Read more on php.net/manual/en/language.operators.execution.php \$\endgroup\$ Commented Aug 4, 2015 at 8:43
1
\$\begingroup\$

Depending on your intent, it might be better to skip PHP altogether and just run archiving programs on the command line (if your shared host allows SSH access), or through a cron job. Here are a few examples using programs commonly found on servers:

# Create a Gzipped TAR archive
tar -czf ~/backup.tar.gz /directory/to/archive
# Create a zip archive (`zip` isn't as common as tar in my experience)
zip -ur backup.zip /directory/to/archive

If you want dated backups of each site, that's still well within the scope of a shell command or script:

# This will iterate over all files and directories in the sites folder, so might
# need adjusting if there are other files in /home/sites/
for dir in /home/sites/*;
 do tar -czvf $dir/cbitsbackup/backup-$(date +%y-%m-%d).tar.gz -C $dir public_html;
done;

I'd consider the implications of archiving a site and downloading via a single HTTP request as it looks like you're trying to do: is this exposed/publicly accessible? If it isn't locked down, what is the impact of someone viewing any code in a site or sending many requests to the script (ie. denial of service)?

answered Nov 1, 2014 at 22:49
\$\endgroup\$
2
  • \$\begingroup\$ My host is heart internet that don't allow ssh access without sending a handwritten form with proof of ID. This has to be done on a site by site basis and with over 90 websites (reselling) this would be impractical \$\endgroup\$ Commented Nov 3, 2014 at 7:39
  • \$\begingroup\$ The script is also secured on an IP whitelist with htaccess \$\endgroup\$ Commented Nov 3, 2014 at 7:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.