使用 PHP 脚本流式传输大文件
使用 http://php.net/manual/en/ 的注释中找到的类似脚本function.fread.php,我设计了这个函数:
function readfile_chunked_remote($filename, $seek = 0, $retbytes = true, $timeout = 3) {
set_time_limit(0);
$defaultchunksize = 1024*1024;
$chunksize = $defaultchunksize;
$buffer = '';
$cnt = 0;
$remotereadfile = false;
if (preg_match('/[a-zA-Z]+:\/\//', $filename))
$remotereadfile = true;
$handle = @fopen($filename, 'rb');
if ($handle === false) {
return false;
}
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
header("Cache-Control: no-cache, must-revalidate");
header("Content-Length: " . filesize($filename));
header("Content-Disposition: attachment; filename=\"" . basename($filename) . "\"");
stream_set_timeout($handle, $timeout);
if ($seek != 0 && !$remotereadfile)
fseek($handle, $seek);
while (!feof($handle)) {
if ($remotereadfile && $seek != 0 && $cnt+$chunksize > $seek)
$chunksize = $seek-$cnt;
else
$chunksize = $defaultchunksize;
$buffer = @fread($handle, $chunksize);
if ($retbytes || ($remotereadfile && $seek != 0)) {
$cnt += strlen($buffer);
}
if (!$remotereadfile || ($remotereadfile && $cnt > $seek))
echo $buffer;
ob_flush();
flush();
}
$info = stream_get_meta_data($handle);
$status = fclose($handle);
if ($info['timed_out'])
return false;
if ($retbytes && $status) {
return $cnt;
}
return $status;
}
但是,对于超过 100mb 左右的文件,它似乎仍然会超时......我可能哪里出错了?
Using a similar script found in the comments of http://php.net/manual/en/function.fread.php, I've devised this function:
function readfile_chunked_remote($filename, $seek = 0, $retbytes = true, $timeout = 3) {
set_time_limit(0);
$defaultchunksize = 1024*1024;
$chunksize = $defaultchunksize;
$buffer = '';
$cnt = 0;
$remotereadfile = false;
if (preg_match('/[a-zA-Z]+:\/\//', $filename))
$remotereadfile = true;
$handle = @fopen($filename, 'rb');
if ($handle === false) {
return false;
}
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
header("Cache-Control: no-cache, must-revalidate");
header("Content-Length: " . filesize($filename));
header("Content-Disposition: attachment; filename=\"" . basename($filename) . "\"");
stream_set_timeout($handle, $timeout);
if ($seek != 0 && !$remotereadfile)
fseek($handle, $seek);
while (!feof($handle)) {
if ($remotereadfile && $seek != 0 && $cnt+$chunksize > $seek)
$chunksize = $seek-$cnt;
else
$chunksize = $defaultchunksize;
$buffer = @fread($handle, $chunksize);
if ($retbytes || ($remotereadfile && $seek != 0)) {
$cnt += strlen($buffer);
}
if (!$remotereadfile || ($remotereadfile && $cnt > $seek))
echo $buffer;
ob_flush();
flush();
}
$info = stream_get_meta_data($handle);
$status = fclose($handle);
if ($info['timed_out'])
return false;
if ($retbytes && $status) {
return $cnt;
}
return $status;
}
However, it seems to still time out for files over 100mb or so... where might I be going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试xmoovstream。它会为你做的。也是开源的。
Try xmoovstream. It will do it for you. Opensource as well.
根据手册,使用
readfile()
http://php.net/readfile
According to the manual, use
readfile()
http://php.net/readfile