I had always just accepted the fact that downloading and uploading an entire site is a time-consuming process. I would sit there and watch the FTP progress bar tell me how many hours I had left, as it individually made requests for each and every file on the system. I started to realize that it wasn't the sheer size of the files as a whole that was taking so long, but the fact that each one had to be requested individually. By zipping the entire site before downloading, or unzipping a file after it is uploaded to the server, you reduce the transaction to just one request, and then your upload/download speeds are the only bottleneck at that point.
I knew that this could be done, but thought that I would need shell access to the server, something that many hosts to do not provide (including EngineHosting, which hosts this site). After a bit of research, some trial and error, I figured out not only how to zip an entire directory on the server and download it, but also how to unzip a file that I had uploaded, all from with a couple of PHP files that I uploaded to the server via FTP. No shell access needed.
The Project
My project this morning was to move EE Spotlight from my unreliable overloaded shared hosting that I used previously to EngineHosting's rock-solid servers. I thought that this would take me the entire afternoon, but in fact took me around 10 minutes total. I won't go into migrating databases and changing settings, as these items are described elsewhere, but I will explain how I downloaded the entire site as a zip file, uploaded it to the new server via FTP, and then extracted it once it was uploaded.
The Packing and Download
After Googling and trying different scripts for zipping a directory and everything in it, the one that I found easiest to use was referenced on Stack Overflow:
<?php
function Zip($source, $destination)
{
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, 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));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString(basename($source), file_get_contents($source));
}
printf('done');
return $zip->close();
}
// Change the below values
Zip('./directory_to_compress/', './compressed_file_name.zip');
?>
To use, create a blank PHP file on your server, paste this code in there, and change the values on the last line. You will then simply navigate to that file that you just created via your web browser, and after about 1 minute you should see the compressed file on your FTP server ready to download (just drag it to your desktop). You should then immediately delete these files on your server so that nobody else can run them or download your site as a zip, as it may contain private information (like your database settings!). For that matter, you should use a crazy obscure filename for your zip file anyway so that it isn't found even when it lies on your server for a brief moment.
The Uploading and Unpacking
I did come across some scripts that allowed you to upload the FTP file via a web form and unzip it, but because my file was 39MB, I wasn't sure if it would run up against the server's PHP file upload limit, and thought that a direct access script must exist out there somewhere.
What I found was a simple script that allowed me to specify the location of the zip file, and a simple navigation to that file would unzip everything. After I uploaded the zipped file via FTP to the new server, I just had to navigate to the following script, which was found on Brendon Wildbore's site:
<?php
$zip = new ZipArchive;
$res = $zip->open('compressed_file_name.zip');
if ($res === TRUE) {
$zip->extractTo('unzipped/');
$zip->close();
echo 'unzipped';
} else {
echo 'failed';
}
?>
In the above example, you will need to replace the "compressed_file_name.zip" with whatever your zip file is (and in this example the script existed in the same directory as the zip file). I also unzipped things into an "unzipped" directory, just to look them over before I moved them into the site root. Moving things in an FTP program takes no time at all once they are uploaded already.
The Final Result
Like I mentioned already, both of these scripts, including the upload/download time took me around 10 minutes. I decided to use the time leftover that I had allotted to document what I had done here, not only to help you out, but also to serve as a reminder for myself in the future.
If you have any more tips, security implications that we should be aware of, or anything else to add, please do so in the comments. I will update this article as needed from information shared. Thanks!
subscribe to RSS
subscribe via e-mail
@ee_spotlight













Contributors
9 Comments...