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

fichby's avatar

Zipping file on laravel Vapor

I am trying to create a zip file and add files to it and then download it.

s3 does not allow the manipulation of the files, and vapor does not allow you to save the save locally.

Does anyone have an idea on how i can get around this.

this is the zip code

 $zip = new \ZipArchive;

        if ($zip->open($zipname, \ZipArchive::CREATE) === true) {
            $files = $CustomerOrder->files;
            foreach ($files as $value) {
                $file_content = Storage::disk($source_disk)->get($value->filepath);
                $file_name = $value->filename;
                $zip->addFromString($file_name, $file_content);
            }

            $zip->close();

        }


and this is the error

ZipArchive::close(): Failure to create temporary file: Read-only file system
(1/1) ErrorException
ZipArchive::close(): Failure to create temporary file: Read-only file system

any help would be great, thanks

0 likes
7 replies
JhumanJ's avatar

You don't have access to local file storage on lambda as it's serverless. However, I think you could be able to zip a file in memory and put the ouput stream in a file that you upload to s3... Otherwise, I think you have access to /tmp in lambda functions, if you set this folder as your app storage, you might be able to achieve what you are trying.

1 like
fichby's avatar

So how would i access the lamba temp folder

$zipname = 'tmp/archive-' . $date . '.zip';
        $zip = new \ZipArchive;

        if ($zip->open($zipname, \ZipArchive::CREATE)
...

like this?

kurucu's avatar
kurucu
Best Answer
Level 8

Set up a local disk that points to /tmp, and use this for local processing.

The instructions are here.

I have the following in my filesystems.php config file:

'disks' => [

        'tmp' => [
            'driver' => 'local',
            'root' => env('USE_LAMBDA_STORAGE', true) ? "/tmp" : storage_path('app/temp'),
        ],
],

Which I then access with Storage::disk('tmp')->...().

The env variable lets me use USE_LAMBDA_STORAGE=false on the local .env so that the app uses the normal local space.

5 likes
KevinKirchner's avatar

Here's what finally worked for me:

config/filesystems.php (I had to add url to @kurucu's "tmp" driver)

	'tmp' => [
            'driver' => 'local',
            'root' => env('USE_LAMBDA_STORAGE', true) ? "/tmp" : storage_path('app/temp'),
            'url' => env('USE_LAMBDA_STORAGE', true) ? "/tmp" : storage_path('app/temp'),
        ],

In my controller:

$filename = 'myfile.zip';
$zipfile = Storage::disk('tmp')->url($filename);
$zip = new \ZipArchive();
$zip->open($zipfile, \ZipArchive::CREATE);

// Loop through photos, pull them from S3, and add them to the zip file
foreach ($myModel->photos as $photo) {
    $imageNameParts = explode('/', $photo->url);
    $imageName = array_pop($imageNameParts);
    $zip->addFromString(Str::slug($imageName), Storage::disk('s3')->get($photo->url));
}

$zip->close();

Storage::disk('s3')->put("my-directory/$filename", file_get_contents($zipfile));

// Redirect to the S3 file directly
return redirect(Storage::disk('s3')->temporaryUrl(
    "my-directory/$filename",
    now()->addHour(),
    ['ResponseContentDisposition' => 'attachment']
));

3 likes

Please or to participate in this conversation.