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

UweH's avatar
Level 1

ZipArchive::open returns not found

Hey there!

my application is running on Vapor and I am not trying to extract files from a zip archive file uploaded by a user. It contains several csv files and the archive filesize is around 500kb. On my local everything is working (as usual), however not on the vapor test environment.

Here my pretty simple code snippet:

$myFile = 'uploads/archives/test.zip';
$extractTo = 'extracted/';

if(Storage::disk('s3')->exists($myFile)) {
	Log::debug('issue opening archive > code: ' . $myFile);
	
	$zip = new ZipArchive();
	$zipFile = $zip->open(Storage::disk('s3')->path($myFile));

	if ($zipFile === TRUE) {
		$zip->extractTo(Storage::disk('s3')->path($extractTo));
		$zip->close();
	} else {
		Log::debug('issue opening archive > code: ' . $zipFile);
	}
} else {
	Log::debug('archive file not found: ' . $myFile);
}

The confusing aspect is that the archive file is found when testing with Storage::exists() but ZipArchive->open() returns code 9 what means not found. This is driving me crazy and I have not really any further ideas what to test to make that work. Was really testing a lot of path and code variations I found in my researches but nothing worked.

Tried lots of paths but they all did not work for the native file_exists() check and also not the ZipArchive::open() invocation.

Storage::disk('s3')->exists('uploads/archives/test.zip');
// true

file_exists(base_path('storage/app/uploads/archives/test.zip'));
// false > /var/task/storage/app/uploads/archives/test.zip

file_exists(base_path('/storage/app/uploads/archives/test.zip'));
// false > /var/task/storage/app/uploads/archives/test.zip

file_exists(storage_path('/app/uploads/archives/test.zip'));
// false > /tmp/storage/app/uploads/archives/test.zip

file_exists(storage_path('app/uploads/archives/test.zip'));
// false > /tmp/storage/app/uploads/archives/test.zip

file_exists(storage_path('/uploads/archives/test.zip'));
// false > /tmp/storage/uploads/archives/test.zip

file_exists(storage_path('uploads/archives/test.zip'));
// false > /tmp/storage/uploads/archives/test.zip

file_exists(Storage::disk('s3')->path('uploads/archives/test.zip'));
// false

file_exists('uploads/archives/test.zip');
// false

file_exists('/uploads/archives/test.zip');
// false

file_exists('/app/uploads/archives/test.zip');
// false

file_exists('app/uploads/archives/test.zip');
// false

I event tried to avoid s3 as this is just readonly and copy the file to the ephemeral storage first as described here: laracasts.com/discuss/channels/vapor/zipping-file-on-laravel-vapor

Storage::disk('tmp')->put('test.zip', Storage::disk('s3')->get('uploads/archives/test.zip'));
// true

Storage::disk('tmp')->exists('test.zip')
// true

file_exists('tmp/test.zip')
// false

file_exists('test.zip')
// false

Any ideas what else to do? Your help and ideas are highly appreaciated!

Uwe

0 likes
1 reply
UweH's avatar
Level 1

Was able to find a solution for this. If anyone else has the same issue, here what worked for me.

// copy from s3 to local
Storage::disk('local')->put('test.zip', Storage::disk('s3')->get('uploads/archives/test.zip'));

// open the zip
$zipFile = $zip->open(Storage::disk('local')->path('test.zip'));

if ($zipFile === TRUE) {
	// extract the zip
	$zip->extractTo(Storage::disk('local')->path('test'));

	// read list of extracted files
	$extractedFiles = Storage::disk('local')->files('test');
	
	foreach ($extractedFiles as $file) {
		// copy to s3
		Storage::disk('s3')->put($extractTo . basename($file), Storage::disk('local')->get($file));
	}

	// cleanups
	Storage::disk('local')->deleteDirectory('test');
	Storage::disk('local')->delete('test.zip');
}

$zip->close();

Hope it helps ;)

Please or to participate in this conversation.