Link to home
Start Free TrialLog in
Avatar of Torquil Beavis
Torquil BeavisFlag for Canada

asked on

how to zip *all* folders and files that are children of the parent folder

I need to be able to have a script that automatically zips *all* the folders and files in the parent folder, rather than me entering an array of child folders and files each time as I now have in the script. So the zip would contain /abc123 and on down.
Is there a smart way to do this?

Here are the folder structure and files to be zipped - from abc123 through test_folder_3:
These files are all 1 line text files ..
/zippo                      (This is the parent folder that the zip file will placed in - the zip is called test.zip)
    /abc123                  (contains 1 file: folder_1_file_1.txt)
        /test_folder_2       (contains 1 file: folder_2_file_1.txt)
        /test_folder_3       (contains 3 files: folder_3_file_1.txt, folder_3_file_2.txt, folder_3_file_3.txt)

Open in new window


And the script, so far:
function create_zip($files = array(),$destination = '',$overwrite = false)
{
	//if the zip file already exists and overwrite is false, return false
	if(file_exists($destination) && !$overwrite)
    {
        return false;
    }
	//vars
	$valid_files = array();
	//if files were passed in...
	if(is_array($files))
    {
		//cycle through each file
		foreach($files as $file)
        {
			//make sure the file exists
			if(file_exists($file))
            {
				$valid_files[] = $file;
			}
		}
	}
	//if we have good files...
	if(count($valid_files))
    {
		//create the archive
		$zip = new ZipArchive();
		if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true)
        {
			return false;
		}
		//add the files
		foreach($valid_files as $file)
        {
			$zip->addFile($file,$file);
		}
		//debug

		//close the zip
		$zip->close();

		//check to make sure the file exists
		return file_exists($destination);
	}
	else
	{
		return false;
	}
}

$directory = '../../library/zippo/';     // Enter the directory where the files to be zipped are

$files_to_zip = array(                                   // Enter the individual files for the zip file
	$directory.'abc123/folder_1_file_1.txt',
	$directory.'abc123/test_folder_2/folder_1_file_1.txt',
	$directory.'abc123/test_folder_3/folder_1_file_1.txt',
	$directory.'abc123/test_folder_3/folder_1_file_2.txt',
	$directory.'abc123/test_folder_3/folder_1_file_3.txt'
);
//if true, good; if false, zip creation failed
$result = create_zip($files_to_zip,'../../library/zippo/test.zip');    // Enter the zip file name to be created
?>

Open in new window

SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Torquil Beavis

ASKER

Thanks guys. Following your directions and scripts has led me to this point.

Below is the folder and file structure, and the zip and unzip scripts with their outputs.

Issue: The zipper script is supposed to zip all folders and files from abc123 on down, yet only zips the abc123 folder (and no files).

The zipper script is placing the zip file in the correct folder, base_1, and creates the abc123 folder in the zip file, but no other folders or files.
When the unzip script is run, the abc123 folder is correctly placed in the base_2 folder, without the other folders and files of course since there are no others there.

The class is recursive and should zip all the folders and files from abc123 down. Unfortunately the references that I've studied don't help with this.
Any ideas that I could try?

/*
Folders & files:

/app_folder (zipper script and unzipper script run from here)

    /base_1       (this is where the zip file is - folder not to be created in zip file, already created)

        /abc123     (this is first folder to be created upon unzipping into *base_2*)
            /file_A.txt     (the only file to be zipped to this folder)
            /test_folder_2  (the first folder within /abc123 to be created upon unzipping)
                /file_B.txt     (file to be zipped to this folder)
            /test_folder_3  (the second folder within /abc123 to be created upon unzipping)
                /file_C.txt     (file to be zipped to this folder)
                /file_D.txt     ( " )
                /file_E.txt     ( " )

    /base_2       (parent of first folder to be unzipped - folder not to be created from zip file, already created)

        /abc123     (this is first folder to be created upon unzipping)
            /file_A.txt     (the only file to be zipped to this folder)
            /test_folder_2  (the first folder within /abc123 to be created upon unzipping)
                /file_B.txt     (file to be zipped to this folder)
            /test_folder_3  (the second folder within /abc123 to be created upon unzipping)
                /file_C.txt     (file to be zipped to this folder)
                /file_D.txt     ( " )
                /file_E.txt     ( " )
*/

Open in new window


zipper script:
<?php
$abc123 = "abc123";                             // a path to zip up
echo "abc123 = ".$abc123."<br>";
$filename = "base_1/zipfile.zip";                 // a path and name for the zip file
echo "filename = ".$filename."<br><br>";

class Zipper extends ZipArchive
{

    public function addDir($path)
    {
        print '<br /><b>Adding Folder: [ ' . $path . ' ] to the archive.</b><br />';
        $this->addEmptyDir($path);
        $nodes = glob($path . '/*');
        foreach ($nodes as $node)
        {
            print $node . '<br />';
            if (is_dir($node))
            {
                $this->addDir($node);
            }
            else if (is_file($node))
            {
                $this->addFile($node);
            }
        }
    }

} // class Zipper

function make_archive($abc123, $filename)      // from, to
{
    // this is from extended class
    $zip = new zipper();

    if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE)
    {
        exit("cannot open <$filename>\n");
    }

    $zip->addDir($abc123);
    echo "numfiles: " . $zip->numFiles . "\n";
    $zip->close();
}

make_archive($abc123, $filename);

?>

Open in new window


Output from zipper:
/*
Output from zipper_test_10.php:

abc123 = abc123
filename = base_1/zipfile.zip


Adding Folder: [ abc123 ] to the archive.
numfiles: 1
*/

Open in new window


unzipper script:
<?php
$base_2 = "base_2";
echo "base_2 = ".$base_2."<br>";
$filename = "base_1/zipfile.zip";
echo "filename = ".$filename."<br><br>";

$zip = new ZipArchive;
$res = $zip->open($filename);
if ($res === TRUE)
{
  $zip->extractTo($base_2);
  $zip->close();
  echo 'Successfully extracted';
}
else
{
  echo 'There was a problem';
}
?>

Open in new window


Output from unzipper script:
/*
Output from unzipper_test_10.php:

base_2 = base_2
filename = base_1/zipfile.zip

Successfully extracted
*/

Open in new window

Sorry, this would be a research project for me, and I don't really have time for it this weekend.  But maybe there is a different way of looking at the problem.  Here are some questions that come to mind:

What kinds of files are you needing to zip up?  What is the expected and observed compression ratio?  What is the reason for zipping them instead of keeping them in clear text?  

In my experience, the past few years have given us huge increases in data transfer rates, so if the objective of using zip archives is to shorten data transfer time, you might want to measure the elapsed time and consider whether it's worth a research project, ie: how much payback can you get for the effort?
https://xkcd.com/1205/
Ah yes! July 4th ;)

I need to have zips - not concerned with data transfer time or file sizes.

It seems to be something to do with $nodes = glob($path . '/*'); 'nodes' or 'path'.
I've tried a huge number of cycles to try to discern the problem, and experience tells me it's something simple, or a misunderstanding of mine (probably both).

Maybe someone else can chip in.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Perfect! With a bit of string manipulation that worked exactly, Julian. So now the zipping and unzipping work together. Thank you.
You are welcome.