我有以下PHP代码,涉及我的网站的下载方法。我试图将下载速度限制为特定的,因为它当前被下载管理器滥用和挤出。
不幸的是,我没有编码经验。
public function download(
$file,
$filename,
$file_size,
$content_type,
$disposition = 'inline',
$android = false
) {
// Gzip enabled may set the wrong file size.
if (function_exists('apache_setenv')) {
@apache_setenv('no-gzip', 1);
}
if (ini_get('zlib.output_compression')) {
@ini_set('zlib.output_compression', 'Off');
}
@set_time_limit(0);
session_write_close();
header("Content-Length: ".$file_size);
if ($android) {
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
} else {
header("Content-Type: $content_type");
header("Content-Disposition: $disposition; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Expires: -1");
}
if (ob_get_level()) {
ob_end_clean();
}
readfile($file);
return true;
}
码:
<?php
public function download(
$file,
$filename,
$file_size,
$content_type,
$disposition = 'inline',
$android = false
) {
// Gzip enabled may set the wrong file size.
if (function_exists('apache_setenv')) {
@apache_setenv('no-gzip', 1);
}
if (ini_get('zlib.output_compression')) {
@ini_set('zlib.output_compression', 'Off');
}
@set_time_limit(0);
session_write_close();
header("Content-Length: ".$file_size);
if ($android) {
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
} else {
header("Content-Type: $content_type");
header("Content-Disposition: $disposition; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Expires: -1");
}
if (ob_get_level()) {
ob_end_clean();
}
$this->readSlow($file, 1);
return true;
}
private function readSlow(string $filename, int $sleepAmount = 0, int $chunkSize = 409600)
{
$handle = fopen($filename, "r");
while (!feof($handle)) {
echo fread($handle, $chunkSize);
ob_flush();
sleep($sleepAmount);
}
fclose($handle);
}
注意:
我假设你发布了课程的一部分。如果你想在课外使用readSlow()
,那么你就这样使用它:
readSlow('pathToFile', $amountOfSleep, $amountOfBytesToReadAtOneRead);
这是可选的,
ob_flush();
我这样做了,所以一旦缓冲区被读取,它会立即发送给请求数据的客户端,但在你的情况下,删除它可能会更好 - 测试它是否更好用于$amountSleep
和$chunkSize
的不同值
sleep()不占用脚本执行总时间,因此如果文件在10秒内没有任何睡眠而下载,并且php脚本的最大执行时间为30秒,那么您可以通过使用sleep轻松地使脚本每次下载运行120秒。
而不是使用sleep()你可以使用usleep(),它可以让你更精确地控制速度限制,因为它需要以微秒为单位的睡眠时间,而不是在第二秒,所以在使用它时要记住这一点,如果你想在读取之间进入睡眠1秒然后当使用$sleepAmount
时,usleep()应该设置为1000000
$chunkSize
是将要读取的字节数,然后您的脚本将进入休眠状态。使用此值播放以获得最佳速度。
我没有测试代码,所以它可能没有用,但至少这是开始的想法。