在我的Laravel脚本中,我将文本写入使用tmpfile()
创建的文件,然后尝试返回文件下载响应,以便用户可以下载该文件。
$file = tmpfile();
fwrite($file, 'Write some text to the file.');
return Response::download(stream_get_meta_data($file)['uri'], 'myFile.txt');
结果是AccessDeniedException
说:
The file /tmp/phpJfvGtH could not be accessed
如果我强制不使用Laravel Response
类的文件下载响应,它可以正常工作:
header('Content-disposition: attachment; filename=myFile.txt');
header('Content-type: text/plain');
readfile(stream_get_meta_data($file)['uri']);
为什么这样做,但使用Response::download()
方法却没有?
我正在使用Laravel Framework version 4.2.16
答案 0 :(得分:0)
发生这种情况是因为丢失了对文件资源的所有引用。根据{{3}}文档:
关闭后(例如,通过调用fclose()或tmpfile()返回的文件句柄没有剩余引用)或脚本结束时,文件将自动删除。
在您的情况下,当您将文件路径传递给$file
函数而不是处理程序本身时,对文件处理程序download()
的唯一引用保留在当前作用域中。
return Response::download(stream_get_meta_data($file)['uri'], 'myFile.txt');
那解决方案呢?
Response::stream()
或确保以某种方式不会丢失对文件句柄的引用。我通过将文件处理程序传递给标头选项进行了一些虚拟检查,并且它起作用。 (不知道将来是否会破坏任何内容,因为标头选项并非针对此类情况设计的)
$file = tmpfile();
fwrite($file, 'Write some text to the file.');
return Response::download(stream_get_meta_data($file)['uri'], 'myFile.txt', [
$file,
]);
或者在存储文件夹中创建文件,而不是创建临时文件。考虑一下临时文件的清理机制