Reputation: 2277
I need to download images from other websites to my server. Create a ZIP file with those images. automatically start download of created ZIP file. once download is complete the ZIP file and images should be deleted from my server.
Instead of automatic download, a download link is also fine. but other logic remains same.
Upvotes: 20
Views: 53287
Reputation: 358
This code sample and short explanation shows how to delete the zip file after the user has downloaded or cancelled the download.
I am not taking full credit for this answer. Here is a link to the article I copied most of the code from.
Handling zip file download completion and cancellation event
$zip = new ZipArchive();
$zip_file_name = 'your-file.zip';
$zip->open($zip_file_name, ZipArchive::CREATE|ZipArchive::EXCL);
// you can add your file using $zip->addFromString(basename($file_path), file_get_contents($file_path));
// as well as other the $zip->addFile() method.
// when you are done adding your files, simply close the zip.
$zip->close();
// these are the headers we will send to download.
// notice that the Expires header's value is set to true and that of Pragma is set to "no-cache".
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zip_file_name);
header('Content-Length: ' . filesize($zip_file_name));
header('Pragma: no-cache');
header('Expires: 0');
readfile($zip_file_name);
ob_clean();
ob_flush();
readfile($zip_file_name);
ignore_user_abort(true);
unlink($zip_file_name);
exit();
Upvotes: 0
Reputation: 89
I went there looking for a similar solution, and after reading the comments found this turnover : before creating your zip file in a dedicated folder (here called 'zip_files', delete all zip you estimate being older than a reasonable time (I took 24h) :
$dossier_zip='zip_files';
if(is_dir($dossier_zip))
{
$t_zip=$dossier_zip.'/*.zip'; #this allow you to let index.php, .htaccess and other stuffs...
foreach(glob($t_zip) as $old_zip)
{
if(is_file($old_zip) and filemtime($old_zip)<time()-86400)
{
unlink($old_zip);
}
}
$zipname=$dossier_zip.'/whatever_you_want_but_dedicated_to_your_user.zip';
if(is_file($zipname))
{
unlink($zipname); #to avoid mixing 2 archives
}
$zip=new ZipArchive;
#then do your zip job
By doing so, after 24h you only have the last zips created, user by user. Nothing prevents you for doing a clean by cron task sometimes, but the problem with the cron task is if someone is using the zip archive when the cron is executed it will lead to an error. Here the only possible error is if someone waits 24h to DL the archive.
Upvotes: 1
Reputation: 557
Other solution: Delete past files before creation new zip file:
// Delete past zip files script
$files = glob('*.zip'); //get all file names in array
$currentTime = time(); // get current time
foreach($files as $file){ // get file from array
$lastModifiedTime = filemtime($file); // get file creation time
// get how old is file in hours:
$timeDiff = abs($currentTime - $lastModifiedTime)/(60*60);
//check if file was modified before 1 hour:
if(is_file($file) && $timeDiff > 1)
unlink($file); //delete file
}
Upvotes: 2
Reputation: 169
<?php
Zip('some_directory/','test.zip');
if(file_exists('test.zip')){
//Set Headers:
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime('test.zip')) . ' GMT');
header('Content-Type: application/force-download');
header('Content-Disposition: inline; filename="test.zip"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize('test.zip'));
header('Connection: close');
readfile('test.zip');
exit();
}
if(file_exists('test.zip')){
unlink('test.zip');
}
function Zip($source, $destination)
{
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', realpath($file));
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
?>
Upvotes: 15
Reputation: 1964
Enable your php_curl extension; (php.ini),Then use the below code to create the zip. create a folder class and use the code given below:
<?php
include("class/create_zip.php");
$create_zip = new create_zip();
//$url_path,$url_path2 you can use your directory path
$urls = array(
'$url_path/file1.pdf',
'$url_path2/files/files2.pdf'
); // file paths
$file_name = "vin.zip"; // zip file default name
$file_folder = rand(1,1000000000); // folder with random name
$create_zip->create_zip($urls,$file_folder,$file_name);
$create_zip->delete_directory($file_folder); //delete random folder
if(file_exists($file_name)){
$temp = file_get_contents($file_name);
unlink($file_name);
}
echo $temp;
?>
create a folder class and use the code given below:
<?php
class create_zip{
function create_zip($urls,$file_folder,$file_name){
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file_name);
header('Content-Transfer-Encoding: binary');
$mkdir = mkdir($file_folder);
$zip = new ZipArchive;
$zip->open($file_name, ZipArchive::CREATE);
foreach ($urls as $url)
{
$path=pathinfo($url);
$path = $file_folder.'/'.$path['basename'];
$zip->addFile($path);
$fileopen = fopen($path, 'w');
$init = curl_init($url);
curl_setopt($init, CURLOPT_FILE, $fileopen);
$data = curl_exec($init);
curl_close($init);
fclose($fileopen);
}
$zip->close();
}
function delete_directory($dirname)
{
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle))
{
if ($file != "." && $file != "..")
{
if (!is_dir($dirname."/".$file))
unlink($dirname."/".$file);
else
delete_directory($dirname.'/'.$file);
}
}
closedir($dir_handle);
rmdir($dirname);
return true;
}
}
?>
Upvotes: 1
Reputation: 1416
Firstly, you download images from webiste
then, with the files you have downloaded you creatae zipfile (great tute)
finally you sent this zip file to browser using readfile and headers (see Example 1)
Upvotes: -1
Reputation: 10752
Here's how I've been able to do it in the past. This code assumes you've written the files to a path specified by the $path
variable. You might have to deal with some permissions issues on your server configuration with using php's exec
// write the files you want to zip up
file_put_contents($path . "/file", $output);
// zip up the contents
chdir($path);
exec("zip -r {$name} ./");
$filename = "{$name}.zip";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.urlencode($filename));
header('Content-Transfer-Encoding: binary');
readfile($filename);
Upvotes: 2
Reputation: 104050
Any idea how many zip file downloads get interrupted and need to be continued?
If continued downloads are a small percentage of your downloads, you can delete the zip file immediately; as long as your server is still sending the file to the client, it'll remain on disk.
Once the server closes the file descriptor, the file's reference count will drop to zero, and finally its blocks on disk will be released.
But, you might spent a fair amount of time re-creating zip files if many downloads get interrupted though. Nice cheap optimization if you can get away with it.
Upvotes: 3
Reputation: 401002
Well, you'll have to first create the zipfile, using the ZipArchive
class.
Then, send :
header()
-- there is an example on that manual's page that should helpreadfile()
And, finally, delete the zip file from your server, using unlink()
.
This just in case your normal PHP script is, sometimes, interrupted, and doesn't delete the temporary file.
Upvotes: 25