So I needed to archive data from multiple models into a single zip file. My first attempt was to use the Chumper/Zipper package for Laravel, this however did not work for me as I encountered several problems with it. The results were inconsistent. Maybe I was using it incorrectly or there was something I missed somehow. After several hours of fighting with it, I decided to go the native PHP way.
Here’s an example of how I got it to work. This code is part of a function in the appropriate controller:
<?php
// Convert data to JSON
$data = User::where('account_id', $account_id)->get()->toJson();
$json[] = $this->saveJsonFile($account_id . '_users.json', $data);
$data = Account::where('id', $account_id)->get()->toJson();
$json[] = $this->saveJsonFile($account_id . '_accounts.json', $data);
// Set the storage path and the zip file name
$storage = storage_path() . '/archive/';
$zip_file = $account_id . '_archive_' . time() . '.zip';
// Open a new zip archive for creation
$zip = new ZipArchive;
$open = $zip->open($storage . $zip_file, ZipArchive::CREATE);
// Add each JSON file to the zip archive
if ($open === true) {
foreach ($json as $file) {
$zip->addFile($file);
}
$zip->close();
} else {
throw Exception;
}
// Clean up
File::delete($json);
?>
The code above calls this private function, which exists in the same controller:
<?php
private function saveJsonFile($file_name, $contents)
{
$file = storage_path() . '/archive/' . $file_name;
// Save file
if ( ! File::put($file, $contents)) {
throw Exception;
}
return $file;
}
?>
And that's all there is to it.