Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

finchy70's avatar

Adding files to a zip archive

I have a couple of nested queries that pull valid certs from the database by engineer.

I am trying to get a "Get all valid certs button' to create a zip containing all the valid certs (in date expiry > now() ) for a specific engineer. Certs are stored in /storage /app/certs and the database entries are 'qualification_id, filename, and url'.

I get the certs with a couple of nested loops but cant figure out how to create the zip.

Here is the controller.

public function get_all_valid_certs_by_engineer(Engineer $engineer)
    {
        $file_name = "certs.zip";
        $zip = new ZipArchive;
        $zip->open($file_name, ZipArchive::CREATE);
        $qualifications = Qualification::where('engineer_id', $engineer->id)->get();
        foreach($qualifications as $qualification)
        {
            $certs = $qualification->training_certs()->where('expiry', '>', now())->get();
            if ($certs->count() > 0)
            {
                foreach ($certs as $cert)
                {
                    $zip->addFile('storage/app/'.$cert->url);
                }
            }
        }
        $zip->close();
        return response()->download($file_name);
    }

This gives me the error

The file "certs.zip" does not exist

Any ideas?

0 likes
2 replies
Sergiu17's avatar

I guess $file_name should be something like

$file_name = storage_path('app/certs/certs.zip');
finchy70's avatar
finchy70
OP
Best Answer
Level 12

This worked in the end. I was getting the zip paths and the file paths mixed up.

public function get_all_valid_certs_by_engineer(Engineer $engineer)
    {
        $zip_dir = storage_path().'/app/';
        $public_dir = public_path();
        $file_name = "certs.zip";
        $zip = new ZipArchive;
        $qualifications = Qualification::where('engineer_id', $engineer->id)->get();
        if ($zip->open($public_dir.'/'.$file_name, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE)
        {
            foreach($qualifications as $qualification)
            {
                $certs = $qualification->training_certs()->where('expiry', '>', now())->get();
                if ($certs->count() > 0)
                {
                    foreach ($certs as $cert)
                    {
                        $zip->addFile($zip_dir.$cert->url, $cert->filename);
                    }
                }
            }
            $zip->close();
        }
        return response()->download($public_dir.'/'.$file_name);
    }
1 like

Please or to participate in this conversation.