[英]How to create a ZIP file using PHP and delete it after user downloads it?
我需要从其他网站下载图像到我的服务器。 使用这些图像创建ZIP文件。 自动开始下载创建的ZIP文件。 下载完成后,应从我的服务器中删除ZIP文件和图像。
而不是自动下载,下载链接也没关系。 但其他逻辑仍然相同。
好吧,你必须首先使用ZipArchive
类创建ZipArchive
。
然后,发送:
header()
- 该手册的页面上有一个例子应该有帮助 readfile()
最后,使用unlink()
从服务器中删除zip文件。
注意:作为安全预防措施,最好让PHP脚本自动运行(通常由crontab运行) ,这将删除临时目录中的旧zip文件。
这是为了防止您的普通PHP脚本被中断,并且不会删除临时文件。
<?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();
}
?>
其他解决方案:在创建新zip文件之前删除过去的文件:
// 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
}
知道有多少zip文件下载被中断并需要继续吗?
如果继续下载只占您下载的一小部分,您可以立即删除zip文件; 只要您的服务器仍在将文件发送到客户端,它就会保留在磁盘上。
一旦服务器关闭文件描述符,文件的引用计数将降至零,最后将释放其磁盘上的块。
但是,如果许多下载中断,您可能会花费相当多的时间重新创建zip文件。 很好的便宜优化, 如果你可以逃脱它。
以下是我过去的表现。 此代码假定您已将文件写入$path
变量指定的$path
。 您可能必须使用php的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);
启用php_curl扩展名; (php.ini),然后使用下面的代码创建zip。 创建一个文件夹类并使用下面给出的代码:
<?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;
?>
创建一个文件夹类并使用下面给出的代码:
<?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;
}
}
?>
我去那里寻找类似的解决方案,并在阅读评论后发现这个营业额:在专用文件夹中创建你的zip文件之前(这里称为'zip_files',删除你估计比合理时间早的所有邮政编码(我花了24小时) :
$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
通过这样做,在24小时后,您只能按用户创建最后一个拉链。 没有什么能阻止你有时通过cron任务进行清理,但是cron任务的问题是如果有人在执行cron时使用zip存档会导致错误。 这里唯一可能的错误是如果有人等待24小时到存档的DL。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.