我有以下情况: 您可以从我们的服务器下载一些文件。如果您是“普通”用户,则您的带宽有限,例如500kbits。如果您是高级用户,则没有带宽限制,可以尽快下载。但我怎么能意识到这一点? 这是如何上传的&合
答案 0 :(得分:6)
注意:您可以使用PHP执行此操作,但我建议您让服务器本身处理限制。如果您想单独使用PHP限制下载速度,那么本答案的第一部分将介绍您的选择,但在您的下方找到几个链接,您可以在其中找到如何使用服务器
有一个PECL扩展使得这个任务变得非常简单,名为 pecl_http ,其中包含函数http_throttle
。文档包含一个如何执行此操作的简单示例。此扩展程序还包含a HttpResponse
class,其中没有详细记录的ATM,但我怀疑使用其setThrottleDelay
和setBufferSize
方法应该产生所需的结果(节流延迟=> 0.001,缓冲区大小20 ==〜20Kb /秒)。从事物的外观来看,这应该有效:
$download = new HttpResponse();
$download->setFile('yourFile.ext');
$download->setBufferSize(20);
$download->setThrottleDelay(.001);
//set headers using either the corresponding methods:
$download->setContentType('application/octet-stream');
//or the setHeader method
$download->setHeader('Content-Length', filesize('yourFile.ext'));
$download->send();
如果你不能安装它,你可以编写一个简单的循环:
$file = array(
'fname' => 'yourFile.ext',
'size' => filesize('yourFile.ext')
);
header('Content-Type: application/octet-stream');
header('Content-Description: file transfer');
header(
sprintf(
'Content-Disposition: attachment; filename="%s"',
$file['fname']
)
);
header('Content-Length: '. $file['size']);
$open = fopen($file['fname'], "rb");
//handle error if (!$fh)
while($chunk = fread($fh, 2048))//read 2Kb
{
echo $chunk;
usleep(100);//wait 1/10th of a second
}
当然,如果你这样做,不要缓冲输出:),最好也添加一个set_time_limit(0);
语句。如果文件很大,很可能你的脚本会在下载过程中被杀死,因为它会达到最大执行时间。
另一种(可能更可取的)方法是通过服务器配置限制下载速度:
我自己从不限制下载率,但是看一下这些链接,我认为nginx到目前为止是最简单的,这是公平的:
location ^~ /downloadable/ {
limit_rate_after 0m;
limit_rate 20k;
}
这会立即启动速率限制,并将其设置为20k。详情可在the nginx wiki找到。
就apache而言,它 更难,但它要求你启用ratelimit模块
LoadModule ratelimit_module modules/mod_ratelimit.so
然后,告诉apache应该限制哪些文件是一件简单的事情:
<IfModule mod_ratelimit.c>
<Location /downloadable>
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 20
</Location>
</IfModule>
答案 1 :(得分:1)
您可以使用http_throttle
PHP扩展程序中的pecl_http
:
<?php
// ~ 20 kbyte/s
# http_throttle(1, 20000);
# http_throttle(0.5, 10000);
if (!$premium_user) {
http_throttle(0.1, 2000);
}
http_send_file('document.pdf');
?>
(以上内容基于http://php.net/manual/en/function.http-throttle.php的示例。)
如果您的服务器API不允许http_throttle
为您的高级和非高级用户创建两个不同的,不可取的网址,请参阅您的HTTP服务器文档,了解如何限制其中一个。有关Nginx的示例,请参阅https://serverfault.com/questions/179646/nginx-throttle-requests-to-prevent-abuse。后者的好处是可以避免由于PHP杀死你的脚本而提前终止下载等问题。
答案 2 :(得分:1)
这个PHP用户土地库bandwidth-throttle/bandwidth-throttle
use bandwidthThrottle\BandwidthThrottle;
$in = fopen(__DIR__ . "/resources/video.mpg", "r");
$out = fopen("php://output", "w");
$throttle = new BandwidthThrottle();
$throttle->setRate(500, BandwidthThrottle::KIBIBYTES); // Set limit to 500KiB/s
$throttle->throttle($out);
stream_copy_to_stream($in, $out);