我通过PHP脚本从URL下载到我的用户。使用readfile()
时,我获得了连接可以支持的最大下载速度(大约2.5MB / s)但是当我使用fopen, fread, fclose
路由时,下载速度非常非常慢(大约1-2KB / s) )。
这是我的代码:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $filesize);
ob_clean();
flush();
$file = fopen($url, 'rb');
while(!feof($file)) {
echo fread($file, 2014);
}
,readfile代码只是readfile($link);
。
我不能只使用readfile()
函数,原因有两个,一个是我想限制用户下载速度(我只能通过读取这么多数据来使用fread
)和我还想跟踪用户下载的数量(我可以使用readfile()
执行此操作,但不会计算部分下载次数。)
有谁知道为什么会发生这种情况或我如何解决这个问题?据我所知readfile()
只是fopen, fread and fclose
的包装,所以我不知道出了什么问题。
编辑:结束了cURL。
$curl = curl_init();
$options = array(
CURLOPT_URL => $rdLink,
CURLOPT_FAILONERROR => true,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_WRITEFUNCTION => 'readResponse'
);
curl_setopt_array($curl, $options);
if(!curl_exec($curl)) {
header('Location: http://whatever.com');
exit;
}
curl_close($curl);
function readResponse($ch, $data) {
$length = mb_strlen($data, '8bit');
echo $data;
return $length;
}
答案 0 :(得分:2)
使用stream_context_create()和stream_get_contents()
$context = stream_context_create();
$file = fopen($url, 'rb', FALSE, $context);
while(!feof($file))
{
//usleep(1000000);
echo stream_get_contents($file, 2014);
}
您还可以尝试使文件读取长度更大并放入usleep()以减慢执行速度。 无论如何,对于最新版本的PHP,似乎建议使用流函数而不是fread。 您可能还希望在fread()或stream_get_contents()前面添加@来抑制任何错误,至少在生产中是这样。没有它,有点不幸,你的文件已经损坏了。
答案 1 :(得分:0)
它可能在PHP或Apache中的某处缓冲(或者甚至可能是速率限制)。尝试更改:
while(!feof($file)) {
echo fread($file, 2014);
}
要:
while(!feof($file)) {
$s=fread($file, 2014);
if($s===false)break; //Crude
echo $s;
@ob_flush();@flush();
}
(@
前缀是因为他们可能会抱怨空缓冲区。)
正如弗雷什沃特先生所说,你应该对你的fread
电话进行错误检查,所以我在上面添加了一些基本内容。
答案 2 :(得分:0)
原因是2014年。操作系统获得4096字节数据部分的速度比其他部分快。但是如果你写2014,那么OS会尝试从文件读取数据一个字节来计算它。这就是为什么需要这么长时间。将2014年更改为4096