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

查看:25
本文介绍了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)?

更长的背景故事:

我有一个网站,里面有很多大型 mp3 文件(当地教会的布道).并非所有音频档案中的文件都允许下载,因此/sermon/{filename}.mp3 路径被重写为真正执行/sermon.php?filename={filename} 并且如果允许下载文件,则内容类型设置为audio/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天全站免登陆