PHP readfile()和大文件 [英] PHP readfile() and large files

查看:227
本文介绍了PHP readfile()和大文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用readfile()时-在Apache上使用PHP-是文件立即读入Apache的输出缓冲区并完成了PHP脚本执行,还是执行了PHP脚本,直到客户端完成文件(或服务器)的下载超时,以先发生者为准)?

When using readfile() -- using PHP on Apache -- is the file immediately read into Apache's output buffer and the PHP script execution completed, or does the PHP script execution wait until the client finishes downloading the file (or the server times out, whichever happens first)?

更长的背景故事:

我有一个网站,里面有很多大型mp​​3文件(当地教堂的讲道).并非所有音频档案中的文件都允许下载,因此/sermon/{filename}.mp3路径被重写为真正执行/sermon.php?filename={filename},如果允许下载该文件,则内容类型设置为音频/mpeg",并使用readfile()将文件流式传输出去.我一直在抱怨(几乎完全来自通过3G传输下载内容的iPhone用户)这些文件没有完全下载,或者它们在大约10或15分钟后就中断了.当我从使用readfile()进行流式传输文件切换到简单地重定向到文件时,标题是:header("Location:$ file_url"); -所有的抱怨都消失了(我什至与一些可以可靠地按需重现该问题的用户进行了核对).

I have a website with lots of large mp3 files (sermons for a local church). Not all files in the audio archive are allowed to be downloaded, so the /sermon/{filename}.mp3 path is rewritten to really execute /sermon.php?filename={filename} and if the file is allowed to be downloaded then the content type is set to "audio/mpeg" and the file streamed out using readfile(). I've been getting complaints (almost exclusively from iPhone users who are streaming the downloads over 3G) that the files don't fully download, or that they cut off after about 10 or 15 minutes. When I switched from streaming out the file with a readfile() to simply redirecting to the file -- header("Location: $file_url"); -- all of the complaints went away (I even checked with a few users who could reliably reproduce the problem on demand previously).

这使我怀疑在使用readfile()时,PHP脚本引擎一直在使用,直到文件完全下载为止,但是我找不到任何证实或否认这一理论的参考.我承认我在ASP.NET世界中会更在家,而等效于readfile()的dotNet会将整个文件立即推送到IIS输出缓冲区,因此ASP.NET执行管道可以独立于文件的交付而完成到最终客户端... PHP + Apache的行为等同于此行为吗?

This leads me to suspect that when using readfile() the PHP script engine is in use until the file is fully downloaded but I cannot find any references which confirm or deny this theory. I'll admit I'm more at home in the ASP.NET world and the dotNet equivalent of readfile() pushes the whole file to the IIS output buffer immediately so the ASP.NET execution pipeline can complete independently of the delivery of the file to the end client... is there an equivalent to this behavior with PHP+Apache?

推荐答案

您可以做的几件事(我没有报告您需要发送的所有标头,它们可能与脚本中当前的标头相同) :

a few things you can do (I am not reporting all the headers that you need to send that are probably the same ones that you currently have in your script):

set_time_limit(0);  //as already mention
readfile($filename);
exit(0);

passthru('/bin/cat '.$filename);
exit(0);

//When you enable mod_xsendfile in Apache
header("X-Sendfile: $filename");

//mainly to use for remove files
$handle = fopen($filename, "rb");
echo stream_get_contents($handle);
fclose($handle);

$handle = fopen($filename, "rb");
while (!feof($handle)){
    //I would suggest to do some checking
    //to see if the user is still downloading or if they closed the connection
    echo fread($handle, 8192);
}
fclose($handle);

这篇关于PHP readfile()和大文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆