安利两种 php 的下载函数
1.readfile, 获取文件的句柄 (注意: 这里是句柄而不是文件, 所以只占用很小的内存) 并将句柄输出到缓冲区
- function readfile_download($url, $filename,$opt = null)
- {
- // 设置 http 下载消息报文
- header("Content-Disposition: attachment; filename=" . $filename);
- header("Pragma: no-cache");
- header("Expires: 0");
- // 有些下载需要附带 cookie 和 useragent
- $cookie = $opt['cookie'] ? $opt['cookie'] : '';
- $useragent = $opt['useragent'] ? $opt['useragent'] : '';
- $opts = array(
- 'http' => array(
- 'method' => 'GET',
- 'header' =>
- "UserAgent:$useragent\r\n" .
- "Cookie:$cookie \r\n",
- )
- );
- $context = stream_context_create($opts);
- readfile($url,false,$context);
- }
但是缓冲区同样有限制大小, 默认的缓冲区只有 4k, 一旦缓冲区溢出, 同样也会占用内存, 所以如果要进行多人大文件下载, 缓冲区也要被限制
2. 使用 fopen 获取远程文件的句柄, 然后使用 fread 分段获取并输出, 这样不仅占用的内存少, 而且占据的缓冲区也少, 可以用于多人大文件下载场景
- function0 fopen_download($url, $filename,$opt = null,$limit = 1024)
- {
- // 设置 http 下载消息报文
- header("Content-Disposition: attachment; filename=" . $filename);
- header("Pragma: no-cache");
- header("Expires: 0");
- // 有些下载需要附带 cookie 和 useragent
- $cookie = $opt['cookie'] ? $opt['cookie'] : '';
- $useragent = $opt['useragent'] ? $opt['useragent'] : '';
- $opts = array(
- 'http' => array(
- 'method' => 'GET',
- 'header' =>
- "UserAgent:$useragent\r\n" .
- "Cookie:$cookie \r\n",
- )
- );
- $context = stream_context_create($opts);
- $handle = fopen($url, "r", false, $context);
- // 输出
- while (!feof($handle)) {
- $content = fread($handle, intval($limit));
- echo $content;
- ob_flush();
- }
- }
来源: http://www.jianshu.com/p/0d33afab8e09