How to zip current folder without .zip file containing full server path

Hi
I have a php script to recursively zip all files and sub folders in a folder. That part works great. The problem is the zipped file contains the full server path when I extract the zip file. I just want it to act like a normal zip when I click extract here and extract the files to that location.

The relevant code to set the source or folder to zip is-

$from=__DIR__ . '/info';

but when I extract I get multiple empty folders created -

xampp\htdocs\MyProjects\wplocal/info

the info folder contains the sub folders and files I want. How do I zip just the files/folders in /info so I can place the zip file where I want and extract there without all the server folders
thanks

https://www.php.net/manual/en/ziparchive.extractto.php

First contributed comment…

$path = 'zipfile.zip'

$zip = new ZipArchive();
if ($zip->open($path) === true) {
    for($i = 0; $i < $zip->numFiles; $i++) {
        $filename = $zip->getNameIndex($i);
        $fileinfo = pathinfo($filename);
        copy("zip://".$path."#".$filename, "/your/new/destination/".$fileinfo['basename']);
    }                  
    $zip->close();                  
}

Try changing to the directory, zipping the files then change back to the original directory when finished zipping:

$oldDir = chdir(__DIR__.'/info');
$zips= PKZIP('*.*');
chdir($oldDir);

Hi
Thanks for feedback guys. @igor_g - Thanks for replying but I can’t actually get this script to work. Also line 1 should read $path = 'zipfile.zip'; plus I don’t think this would do a recursive zip. But thanks for replying and trying to help.

@John_Betong - Nice idea - I will remember that thanks

For the possible benefit of others the problem was not in my code to set folder $from=__DIR__ . '/info';
the problem was further down in my script - $source = realpath($source); which actually sets the path as the absolute path to the location

Thanks again guys

1 Like

@John_Betong and @igor_g
Well guys, finally got a recursive zip script created that suits me perfectly - so I thought I would share for others -

<?php
// For demonstration purposes this script should be in one folder 
// and the from and to folders should already exist 
// For this example example -  if this folder is called 'test' 
// the two other folders should be /info and /zips
// you can change the source (from) location and the destination 
// or(from) location by changing $to and $from under 'Set folders'

// Optional parameters for overriding php.ini for large files or 
// slow connection or optimising performance and resources
ini_set('max_execution_time', 300);
ini_set('memory_limit','512M');

//Set folders
$from='info';
$to='zips/backup.zip';

//Start timer
$start = microtime(true);

//Call the function to start zipping
echo 'Starting recursive zip process.<br>'; 
echo 'Zipping files and sub folders in '.$from.' to '.$to.'<br>';

zipData($from, $to);

//Notify end of zipping on exit of function
$execution_time = microtime(true) - $start;
echo 'Process completed in '.round($execution_time,4).' seconds<br>';
echo 'Final zip file location is '.$to;

// Main recursive zip function
function zipData($source, $destination) {
	//Set file and folder counters
	$count_folders=0;
	$count_files=0;	
        if (extension_loaded('zip')) {
            if (file_exists($source)) {
                $zip = new ZipArchive();
                if ($zip->open($destination, ZIPARCHIVE::CREATE)) {
					//if line below is uncommented then the zip file will reflect and extract to the full server path
                    //$source = realpath($source);					
                    if (is_dir($source)) {						
                        $iterator = new RecursiveDirectoryIterator($source);
                        // ignore dot files 
                        $iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
                        $files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);						
                        foreach ($files as $file) {
							//if line below is uncommented then the zip file will reflect and extract to the full server path
                            //$file = realpath($file);
                            if (is_dir($file)) {
								$count_folders++;
                                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
                            } else if (is_file($file)) {
								$count_files++;
                                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
                            }	
                        }						
                    } else if (is_file($source)) {
                        $zip->addFromString(basename($source), file_get_contents($source));
                    }
                }
				echo 'Finished zipping - '.$count_files.' files in '.$count_folders.' folders<br>';				
                return $zip->close();				
            }			
        }		
        return false;		
    }	
?>

Just place it in a folder, make sure you have an immediate sub folder called ‘info’ with the files/folders you want to compress inside and an immediate sub folder called ‘zips’ - open the php file in your browser and wait… /info contents will be zipped and backup.zip will be in /zips

You can amend the source and destination folders

I have commented the script to try and make easier for others - happy zipping

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.