Summer Sale! All accounts are 50% off this week.

boldstar's avatar

How To Use ZipArchive For Multiple Files

So I am trying to use ZipArchive to create a zip file. But for whatever reason It will not create the file. Ive tried different formats and I have also tried just doing a single file but no luck.

Here is what the code currently looks like

     public function getClientFiles($id)
    {
        $record = Mail::find($id);
        // Zip File Name
        $zipFileName = 'files.zip';
        // Create ZipArchive Obj
        $zip = new ZipArchive();
        $zip->open(public_path().$zipFileName, ZipArchive::CREATE);
        $files = Storage::files($record->path);
        foreach ($files as $path) {
            $zip->addFile($path, basename($path));
        }
        $zip->close();
        
        return response('done');
    }

so once I run the function, there is no zip file in the public directory but it also does not throw an alarm.

0 likes
10 replies
kropcik's avatar

Start debugging. First of all, check if $zip->open returns TRUE, then dump your $files, to see if you have any. I would say there could be permissions issue on accessing filesystem/creating zip archive.

Does your log shows nothing ?

boldstar's avatar

$zip->open does return true.

When I call $files = Storage::files($record->path); It returns an array of paths to each file in the folder.

I pass in the path to each file with the file name using the foreach loop. But when I call $zip->close() it doesn't create the .zip file and when I check the logs its not giving me anything to work with..

Sinnbeck's avatar

I dont think public_path() ends with a /

public_path().'/'.$zipFileName

Or change the filename

$zipFileName = '/files.zip';
boldstar's avatar

Thanks for the reply, it works with just public_path().$zipFileName. It would return false if it couldn't open the file. But I tried your suggestion with still no luck.

The only time I can get an alarm is if $zip->open() doesn't work and it will throw alarm saying Invalid or uninitialized object when I try passing the file into $zip->addFile()

Sinnbeck's avatar

Yes /yourpath/to/your/website/publicfiles.zip would also be a valid path I suppose

What does $zip->close(); return ? Should also be true on success

boldstar's avatar

@sinnbeck $zip->close() also returns true. However $zip->addFile() is returning false which is weird because I thought $zip->close() should return false if the $zip is empty..

Sinnbeck's avatar

That is indeed stange.

What if you check file_exists() and is_readable() on each file before adding?

Sinnbeck's avatar

Out of curiosity. What happens if you do this?

 public function getClientFiles($id)
    {
        $record = Mail::find($id);
        // Zip File Name
        $zipFileName = public_path() . '/files.zip';
        // Create ZipArchive Obj
        $zip = new ZipArchive();
        $zip->open($zipFileName, ZipArchive::CREATE);
        $files = Storage::files($record->path);
        foreach ($files as $path) {
            $zip->addFile($path, basename($path));
        }
        $zip->close();

    dd(file_exists($zipFileName), $zipFileName);
        
        return response('done');
    }
boldstar's avatar

Well I am calling this function using ajax so I can't dd the result but I am finding out that when I use this path as storage

$zipFileName = public_path() . '/files.zip'

It is placing the file in the wrong public folder. Instead of using 'storage/app/public' it is placing at the root level public folder

Also maybe due to my configuration, I have to do $zip->addFile('../storage/app/'.$path, basename($path)) in order for it to find the file. So I am having issues with the location of the file as well. But I am atleast creating the .zip file now its just not going to the right location. Does that make sense?

Sinnbeck's avatar

If your storage is symlinked you can do

$zipFileName = public_path() . '/storage/files.zip';

Or

$zipFileName = Storage::disk('public')->path('files.zip');

Please or to participate in this conversation.