php 用户下载后删除文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2641667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 07:11:27  来源:igfitidea点击:

deleting a file after user download it

php

提问by Utku Dalmaz

I am using this for sending file to user

我正在使用它向用户发送文件

header('Content-type:  application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="file.zip"');
readfile($file);

I want to delete this file after user downloads it, how can i do this?

我想在用户下载后删除这个文件,我该怎么做?

EDIT: My scenario is like that, when user hits download button, my script will create a temporary zip file and user download it then that temp zip file will be deleted.

编辑:我的场景是这样的,当用户点击下载按钮时,我的脚本将创建一个临时 zip 文件,用户下载它然后该临时 zip 文件将被删除。

EDIT2: OK best way seems running a cron job that will be cleaning temp files once an hour.

EDIT2:好的,最好的方法似乎是运行一个 cron 作业,该作业将每小时清理一次临时文件。

EDIT3: I tested my script with unlink, it works unless user cancel the download. If user cancel the download, zip file stays on the server. So that is enough for now. :)

EDIT3:我用 测试了我的脚本unlink,除非用户取消下载,否则它可以工作。如果用户取消下载,zip 文件将保留在服务器上。所以现在就足够了。:)

EDIT4: WOW! connection_aborted()made the trick !

EDIT4:哇!connection_aborted()成功了!

ignore_user_abort(true);
if (connection_aborted()) {
    unlink($f);
}

This one will delete the file even if user cancel the download.

即使用户取消下载,这也会删除文件。

采纳答案by inkedmn

unlink($filename);

This will delete the file.

这将删除文件。

It needs to be combined with ignore_user_abort()Docsso that the unlinkis still executed even the user canceled the download.

它需要与ignore_user_abort()Docs结合,以便unlink即使用户取消下载仍然执行。

ignore_user_abort(true);

...

unlink($f);

回答by Lars van den Bosch

I always use the following solution:

我总是使用以下解决方案:

register_shutdown_function('unlink', $file);

回答by zerkms

There is no any correct way to detect whether file was completely downloaded by user or not.
So the best way will be to delete file after some period of inactivity.

没有任何正确的方法来检测文件是否完全被用户下载。
所以最好的方法是在一段时间不活动后删除文件。

回答by vkGunasekaran

I too have very similar functionality in one of my website. It will be like deleting randomly created folder & zip file after/cancelling download. I try to explain it here, may be someone find it useful.

我的一个网站中也有非常相似的功能。这就像在/取消下载后删除随机创建的文件夹和 zip 文件一样。我试着在这里解释一下,可能有人觉得它有用。

skin.php:
This page contains download link such as "http://mysite.com/downoload/bluetheme"

skin.php:
此页面包含下载链接,例如“http://mysite.com/downoload/bluetheme”

.htaccess:
I have following rule in htaccess file to redirect the download request to a php file. [download.php].

.htaccess:
我在 htaccess 文件中有以下规则将下载请求重定向到 php 文件。[下载.php]。

RewriteRule ^download/([A-Za-z0-9]+)$ download.php?file= [L]

download.php:

下载.php:

include "class.snippets.php";
$sn=new snippets();
$theme=$_GET['file'];
$file=$sn->create_zip($theme);
$path="skins/tmp/$file/$file.zip";
$config_file="skins/tmp/$file/xconfig.php";
$dir="skins/tmp/$file";

$file.=".zip";
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=$file");
header("Pragma: no-cache");
header("Expires: 0");
readfile($path);

//remove file after download  
unlink($path);
unlink($config_file);
rmdir($dir);

so on request download.php will create directory with a random name using snippets class. Inside the directory it will create a zip file. after the download/cancelling the request all the files and the directory will be deleted.

所以根据请求,download.php 将使用snippets 类创建一个随机名称的目录。在目录中,它将创建一个 zip 文件。下载/取消请求后,所有文件和目录将被删除。

回答by Bren1818

I couldn't find something which worked for me, so I came up with this, which seems to work well for me:

我找不到对我有用的东西,所以我想出了这个,这对我来说似乎很有效:

header('Content-type: application/zip'); //this could be a different header 
header('Content-Disposition: attachment; filename="'.$zipName.'"');

ignore_user_abort(true);

$context = stream_context_create();
$file = fopen($zipName, 'rb', FALSE, $context);
while(!feof($file))
{
    echo stream_get_contents($file, 2014);
}
fclose($file);
flush();
if (file_exists($zipName)) {
    unlink( $zipName );
}

I hope that helps someone

我希望能帮助某人

回答by Sina aria

connection_aborted()never worked for me. Although ob_clean()works exactly as it should. Hope this help others aswell

connection_aborted()从来没有为我工作过。虽然ob_clean()完全按照它应该的方式工作。希望这对其他人也有帮助

header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $file . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
ob_clean();
flush();
if (readfile($file))
{
  unlink($file);
}

回答by timdev

The safest way I can think of would be to use some client-side flash movie that can observe the transfer from the client side, and then make an XmlHttpRequest call to the server once the download finishes.

我能想到的最安全的方法是使用一些可以观察从客户端传输的客户端 Flash 电影,然后在下载完成后对服务器进行 XmlHttpRequest 调用。

AFAIK, there's no way to do that reliably without using Flash (or a similar browser plugin)

AFAIK,如果不使用 Flash(或类似的浏览器插件),就无法可靠地做到这一点