这可以完美地将压缩文件传递回客户端。但最后取消链接文件的小片段似乎没有用?
我假设fpassthru锁定文件,因此unlink无法做任何事情。
是否有可用的回调选项...在客户收到文件后删除文件?
// we deliver a zip file
header("Content-Type: archive/zip");
// filename for the browser to save the zip file
header("Content-Disposition: attachment; filename=$guideName".".zip");
$filesize = filesize($zip_file);
header("Content-Length: $filesize");
// deliver the zip file
$fp = fopen($zip_file,'r');
echo fpassthru($fp);
// clean up the tmp zip file
unlink($zip_file);
exit();
答案 0 :(得分:1)
文件打开时,它已被锁定且无法删除。
fclose($fp);
unlink($zip_file);
还要确保www-user / fpm脚本所有者(=> chmod)可以写入该文件。
为了调试这个,我建议结合使用错误报告,输出缓冲区和邮件:
ob_start();
error_reporting(E_ALL);
fclose($fp);
unlink($zip_file);
$debug = ob_get_contents();
mail('you@server', 'error in zip upload', var_export($debug, true));
另一个旁注是这里的连接:
("Content-Disposition: attachment; filename=$guideName".".zip")
正确:
("Content-Disposition: attachment; filename=" . $guideName . ".zip")
您也可以使用file_get_contents()
,它与fopen,fpassthru,fclose基本相同:
header("Content-Length: $filesize");
// deliver the zip file
echo file_get_contents($zip_file);
// clean up the tmp zip file
unlink($zip_file);
答案 1 :(得分:1)
首先,您的代码中存在错误,这很可能会损坏您要发送的文件:
返回值
如果发生错误,fpassthru()将返回FALSE。否则,fpassthru() 返回从句柄读取并传递的字符数 到输出。
因此,您的代码应如下所示:
// deliver the zip file
$fp = fopen($zip_file,'r');
fpassthru($fp);
请注意,在fpassthru之前没有回声。
更可靠的解决方案是运行单独的脚本来清理每x分钟/小时/天存储这些文件的文件夹。
如果文件已打开并且您将其删除,则该文件仍处于打开状态,可以从中读取,但不再可以通过文件名访问。当脚本终止并且文件句柄关闭时,文件占用的空间将被释放。
另一种可能的方法是使用会话关闭处理程序。
答案 2 :(得分:0)
您正在创建一个文件句柄,调用fopen,这将锁定文件。您需要确保在取消链接之前调用fclose。例如。
$fp = fopen($zip_file,'r');
echo fpassthru($fp);
fclose($fp);
unlink($zip_file);