I have a script which allows users to upload a ZIP folder. Some users select individual files, and ZIP them up so when uncompressed there are multiple files, however some ZIP entire folders, so when they're uncompressed you just get one folder.
What I want to do, is check if the only contents of an unzipped folder is another folder, and if it is, move all the files from that folder down into the previous one, and delete the original folder.
What would the best way of doing this be?
In other words, you want to flatten the directory structure of a zip archive. There are lots of ways to do this.
Unzip, then flatten folder structure
One would be to unzip the zip archive and then use a DirectoryIterator to walk files and folders.
If a folder is detected, move/copy it's file content to the extraction dir and delete the folder afterwards. That would flatten the dir structure with every iteration on a folder.
https://stackoverflow.com/a/17087268/1163786
ZipArchive - unzip without folder
Another approach would be to unzip the zip archive, without taking care about the paths stored in it, like so:
$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();
}
unzip -j or 7z -e
Finally, it's tagged as PHP question, but:
If you use unzip on the CLI, then use the -j option.
Ìt stands for "junk paths", meaning that the archive's directory structure is not recreated, when unzipping and all files are stored in the extraction directory (by default, the current one).
It's e (to ignore paths), instead of x (with full paths) on 7z. http://sevenzip.sourceforge.jp/chm/cmdline/commands/extract.htm
Related
How to compress or zip a directory and then extract alongside with its files and and sub directories using php script.
i have a directory which is needed to be compressed,then transferred to another server and then extracted into a new directory with new name given to it.
PATH.'/'.$TO.'/'.$DIR_WITH_DIR_NAME
First of all if you want to perform zipping and unzipping operations using php it is must to install php zip extension,as i am using Ubuntu as my OS and php7.0 on my server i installed it using this command.
sudo apt-get install php7.0-zip
For zipping parent directory and other sub directories along side with its files you can use this method given in approved answer.i have used it myself and its best to do so.
Transfer file using php cURL to other server.Now to unzip a folder in a new folder whichever you are trying to extract files in,first create that directory using this php code.
#mkdir(PATH.'/'.$TO.$NEW.'/'.$DIR_WITH_DIR_NAME,0777,true);
This will create the directory and give it all read/write permissions
now use this code to extract a directory
$zip = new ZipArchive;
if ($zip->open(PATH.'/'.$TO.$COMPRESSED.'/'.$FILE.'.zip') === TRUE) {
if(is_dir(PATH.'/'.$TO.$NEW.'/'.$DIR_WITH_DIR_NAME)){
$zip->extractTo(PATH.'/'.$TO.$NEW.'/'.$DIR_WITH_DIR_NAME);
}
$zip->close();
echo 'extracted';
} else {
echo 'error in file extracting';
}
That's it all of the files will be extracted into newly created directory enjoy happy coding.
My file structure in zip is
lib
css
js
app1
app2
index.php
All the above files and folders are in test.zip
i want to extract this test.zip using php
$zip = new ZipArchive;
$res = $zip->open("test.zip");
if ($res === TRUE)
{
$zip->extractTo('path');
$zip->close();
}
if lib folder is already exist in the directory where we are unzipping then except lib(folder) all other files and folders should get override.
how to solve this.
http://php.net/manual/en/ziparchive.open.php , on open, pass in the over write flag.
I am creating a zip archive in php and want to add some pdf files available in my pdfs_lib folder.I have successfully created the archive but there is a problem that inside the created zip archive, files get added into pdfs_lib folder, which is not what i want.
I want to add pdf files present in pdfs_lib folder directly into the archive instead of adding those files inside pdfs_lib folder in my created zip archive.
What i have tried is:
// Create Zip File
$zip = new ZipArchive;
$res = $zip->open("pdfs_lib/my_zip_archive.zip", ZipArchive::CREATE);
if ($res === TRUE)
{
// Add pdf file to zip archive
$zip->addFile("pdfs_lib/pdf_file_1.pdf");
$zip->addFile("pdfs_lib/pdf_file_2.pdf");
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
This code creates the zip archive successfully but whwen i unzip the archive it creates a pdfs_lib folder and unzip all files inside this newly created folder.
Any suggestion on how to create a zip archive without add pdf_lib folder in it.
Change the addFile calls to:
$zip->addFile("pdfs_lib/pdf_file_1.pdf", "pdf_file_1.pdf");
The second parameter is the 'localname', the name used in the zipfile itself. If you leave out the folderpath there, it will be added to the root in the zipfile.
A side not as an into: usually it is considered good practice if an archive (be it zip or any other archive format) unpacks into a clean folder instead of littering the contained files all over the place.
However if you really want to implement this without such folder, then you must rework your code. You have two alternatives:
you can change the working directory your php script is executed in into that folder where you keep the files in. In that case you do not need any path to add files to the zip archive, thus no folder is constructed inside the archive.
the addFile() method of phps zip extension allows to specify a second (optional) argument which allows to pass the target name of a passed file.
I am using the ZipArchive to unzip a zip file:
This file is a zipped up folder and i want to:
Make sure that the content consists of just a folder (obviously with files in side)
Get the name of the unzipped folder so i can then rename it if needs be?
But having trouble getting the folders name after the unzip? I know i could get the name of the zip file as most of the time when zipped it the same name but some people also change the zipped file name.
If you know for sure there's only one dir in the zip you can just do this:
$dir = trim($zip->getNameIndex(0), '/');
Otherwise, you'll have to loop over all the files and somehow figure out which one of them is the one you want:
for ($i = 0; $i < $zip->numFiles; $i++) {
$entry = $zip->getNameIndex($i);
}
Im moving un-zipped files to a server directory /zip/file.unzipped.png
now i need to take that file and zip it.
Is it possible to do that or a need the zip archive as codeigniter guide says?
How can i do that?
Is what you're looking for just a straight download, and not saving the archive on disk before download?
If this is the case you can do what #zer02 suggested, but remove the archive step.
$name = 'mydata1.txt';
$data = 'A Data String!';
$this->zip->add_data($name, $data);
// Write the zip file to a folder on your server. Name it "my_backup.zip"
$this->zip->archive('/path/to/directory/my_backup.zip');
// Download the file to your desktop. Name it "my_backup.zip"
$this->zip->download('my_backup.zip');
The zip library should gather up all the data you've added to the zip cache in memory, and create a file to download dynamically.
Please read the user manual: http://codeigniter.com/user_guide/libraries/zip.html
There are two functions that jump out me for your use case:
$this->zip->read_file()
Permits you to compress a file that already exists somewhere on your
server. Supply a file path and the zip class will read it and add it
to the archive:
$this->zip->read_dir()
Permits you to compress a folder (and its contents) that already
exists somewhere on your server. Supply a file path to the directory
and the zip class will recursively read it and recreate it as a Zip
archive. All files contained within the supplied path will be encoded,
as will any sub-folders contained within it.
$name = 'mydata1.txt';
$data = 'A Data String!';
$this->zip->add_data($name, $data);
// Write the zip file to a folder on your server. Name it "my_backup.zip"
$this->zip->archive('/path/to/directory/my_backup.zip');
// Download the file to your desktop. Name it "my_backup.zip"
$this->zip->download('my_backup.zip');
Zip Lib CI