add zip won't do anything - php

I am trying to zip some folders with this function:
public function generate_zip($directory,$name_of_the_folder){
$rootPath = realpath($directory);
$zip = new ZipArchive();
$zip->open('path/to/my/zip/compressed.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
$zip->addFile($rootPath,$name_of_the_folder);
$zip->close();
}
This does literally nothing. I have already checked the permissions and they seem to be correct.

When using ZipArchive, you cannot add an empty directory using ZipArchive::addFile(). You have to use ZipArchive::addEmptyDir() .
For your case, I think what you want is ZipArchive::addGlob()

According to the documentation, the function 'addFile' wants two filenames: the first is the path to the local file (which you want to add to the zip) and the second (optional) argument is how you want the file to appear inside the zip.
You have a variable '$name_of_the_folder'. Does that contain the right value?
Php.net documentation: http://php.net/manual/en/ziparchive.addfile.php

Related

PHP ZipArchive::addGlob() does not work as expected

I have a bunch of large CSV files which need to zip for later exports. I thought it should be easy with ZipArchive class but it is not. My code looks like:
$zip = new ZipArchive();
$open = $zip->open("$zipDirName/reports.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);
if ($open !== TRUE) throw new \Exception("CampaignsDeviceDays::saveCsvDaysDataZip() error. \$zip->open() failed with error code $open");
$addGlob = $zip->addGlob("$tempDirName/*", GLOB_BRACE, ['add_path' => DIRECTORY_SEPARATOR, 'remove_all_path' => TRUE]);
This code successfuly creates zip file but it is empty.
I want to have all csv files on the top level in zip file. If I use
'add_path' => 'whatever/'
it works. But I want to have it on top level.
The second problem is that I want to owerwrite the files which are in archive but do not remove files which has been in archive before I run the script. I tried constants like
ZipArchive::CREATE | ZipArchive::OVERWRITE but it always rewrite all files in archive. But I dont want to generate all files always. I want previous files saved as they are.
How to achieve this simple solution in PHP? I

Unable to extract zip file which generated using php

I have written the PHP script to generate the zip file. it's working fine when I use rar software to extract it but not getting extract with rar software. I can't ask to users to install rar software to extract downloaded zip file.
I don't know where i am commiting mistakes.
Here i attached error screen shot which i get when try to open zip file.
// Here is code snippet
$obj->create_zip($files_to_zip, $dir . '/download.zip');
// Code for create_zip function
//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) {
$filearr = explode('/', $file);
$zip->addFile($file, end($filearr));
}
$zip->close();
If $valid_files is a glob'd array, use basename() instead of end(), your zip might not actually have added any files causing for it to be an invalid zip (however that would be visible in the size of the zip file).
Also try winrar/winzip/7zip and see what they return, microsoft's internal zip engine might not be up to date enough to open the zips.
I have also encountered this problem, using 7z solved the problem but we need to send the zip to somebody else so 7z is a nono.
I found that, in my case it is that the file path is too long:
When I use this:
$zip->addFile($files_path.'/people.txt');
And it generated a zip folder nested very deep e.g. ["/tmp/something/something1/something2/people.txt"]
So I need to use this instead
$zip->addFile($files_path.'/people.txt', 'people.txt');
Which generate a a zip folder with only 1 layer ["people.txt"], and Windows Zip read perfectly~
Hope this helps somebody that also have this problem!

Problems when extract ZIP file in PHP

I'm trying to extract zip file to some folder in storage_path (I'm using laravel). But I don't know why they comes with .(dot)files when it extracted, also I want to extract them without creating another folder. Here's the code I'm using:
lines inside some public function:
$src = storage_path('application');
$dst = storage_path('tmp/'.time());
$zipfile = $request->file('splashicon');
$zipfile->move($dst, 'splashicon');
$this->splashIcon($dst.'/splashicon', $dst);
splashIcon function:
public function splashIcon($src, $dst)
{
$zip = new ZipArchive();
$x = $zip->open($src); // open the zip file to extract
if ($x === true) {
$zip->extractTo($dst.'/www'); // place in the directory with same name
$zip->close();
unlink($src); //Deleting the Zipped file
}
}
The current result is:
1494618313/www/name.files/thecontentsofzipfile
I have no idea where .(dot) and files came from, please explain what was happened to them.
And by the way, the correct result should be something like this:
1494618313/www/thecontentsofzipfile
Thank you,
This is a laravel convention.
The . means it's a subfolder/subfile within your directory.
I'm not really sure how to get around it.
You might look into Zipper, which is an extraction helper for Laravel. I believe it has an exact match for extraction instead of using the typical Laravel syntax.
https://github.com/Chumper/Zipper

get a unknown file name in different dir, php

Here is my directory structure,
C:\xampp\htdocs\..
C:\download\20150923abc.xls //abc is a random value
how can I attach the file 20150923abc.xls in php?
Also, how to change the filename after I got it?
Thanks.
Use the glob ability to find references all files of type .xls and then you can use the file name references as you wish. This sidesteps the issue of you not knowing the specific file name.
$files = glob("c:/download/*.xls");
This will produce an array of all .xls files with their full filepath. If you wish to rename or attach these files then you can do this using the glob reference:
rename($files[0], "c:/download/somenewname.xls");
etc. Read more at:
PHP Glob Function
EDIT:
From Comment below:
foreach (glob( $old_folder."*.xls") as $filename)
{
$names = explode('/', $filename);
$just_file_name = end($names);
echo $just_file_name . "----\n";
$new_folder = dirname(FILE)."\\prm\\att\\";
//rename_win($old_folder, $new_folder);
rename($filename, $new_folder.$just_file_name); <== this line changed.
}
unset($filename);
To fix the above code in your comment, you need to change the incorrect variables referenced (there was no array $files[0]) to the ones used in the foreach loop.

Zipping up a folder without extra folders in the zipped file

So, I understand it's pretty easy to zip a folder and its contents given that php.net and stackoverflow are full of sample codes. I am trying to zip up a folder as well. This is my code:
$zip = new ZipArchive;
$zip->open('myzip.zip', ZipArchive::CREATE);
foreach (glob("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder/*") as $file) {
$zip->addFile($file);
}
$zip->close();
My script is running in a folder, say on Desktop, and I want to zip thisFolder and its contents. The above code WORKS. But, the problem is that when I unzip the myzip.zip created, I get a structure like
Volumes>Data>Users>username>Desktop>Archive>some>thisFolder
and then I find the contents inside the 8th folder (thisFolder) in this case. How can I change this code so that when I unzip myzip.zip,I would straightaway see the folder thisFolder with the contents inside it instead of having to navigate through folders 7 times before getting my content?
I tried to change the path and silly things like that. But, it doesn't work.
Thanks
If you want everything in the file to be a name relative to your starting folder, use chdir() to start from there:
chdir("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder");
foreach (glob("*") as $file) {
$zip->addFile($file);
}
Actually, I don't think this will work when $file is a subdirectory -- addFile doesn't recurse automatically. There's a comment in the documentation that shows how to write a recursive zip function:
http://www.php.net/manual/en/ziparchive.addemptydir.php
bool ZipArchive::addFile ( string $filename [, string $localname ] )
filename
The path to the file to add.
localname
local name inside ZIP archive.
You can use the pathinfo function to each $file in your loop, in order to retrieve the filename without the path, and then, use it as second parameter to the addFile method.
pathinfo doc here
Here is an example that could solve your problem:
// Create your zip archive
$zip = new ZipArchive;
// open it in creation mode
$zip->open('myzip.zip', ZipArchive::CREATE);
// Loop on all your file
$mask = "/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder";
$allAvailableFiles = glob($mask . "/*")
foreach ($allAvailableFiles as $file)
{
// Retrieve pathinfo
$info = pathinfo($file);
// Generate the internal directory
$internalDir = str_replace($mask, "", $info['dirname']);
// Add the file with internal directory
$zip->addFile($file, $internalDir . "/" . $info['basename']);
}
$zip->close();

Categories