如何在输出 10 MB 数据时停止执行 PHP 脚本


How to stop executing PHP script when 10 MB of data has been output

我有一个Apache服务器,出站传输限制为6 GB。在PHP脚本中,我不小心运行了一个循环,该循环输出了大量数据,并几乎使用了我分配的所有带宽。

有没有办法将每个请求限制为仅输出 10 MB 的数据,然后杀死进程或让它运行但不输出任何其他内容,以避免将来出现此类问题?

以下是日志中有问题的请求的样子:

xxx.xxx.xxx.204 - - [16/Jan/2015:16:10:01 +0100] "GET /ebok/ebok.php HTTP/1.1" 200 5368709120 "-" "Wget/1.13.4 (linux-gnu)"

我试过ini_set

<?php
ini_set('memory_limit', '1M');
$a = array();
for($x=1; $x<1000; $x++) {
    array_push($a, array('imie'=>'Pablo'.$x, 'nazwisko'=>'picasso'.$x,     'adres'=>'nowowiejska'.$x));
}
print_r($a);
exit;
?>

我收到消息:

Fatal error:  Allowed memory size of 1048576 bytes exhausted (tried to allocate 72 bytes) in /home/public_html/bench.php on line 5

但在 Apache 日志中,它只需要 10KB

xxx.xxx.xxx.134 - - [16/Jan/2015:23:25:50 +0100] "GET /bench.php HTTP/1.1" 200 11146 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"

我做错了什么?

你基本上有几个不同的东西来源使用你的带宽。文本,如javascript和php输出,可能只占带宽的一小部分。图像将占用更多空间,而电子书等文件将占用每个请求最多的空间。

您可以对 apache 的 httpd.conf 文件应用一个设置,以限制每个请求的最大大小。我在谷歌搜索几分钟后找不到它,但你可能有一些运气(或者也许这里有人知道实际的命令!

您还可以在脚本顶部设置 ob_start(),并在脚本末尾结束 () 之前查看输出缓冲区大小。如果它太大,您可以截断它。

您可以尝试缓冲输出并将其修剪为所需的大小 (10 MB),然后再实际将其发送到客户端。

这是一种解决方法,但我认为它可以工作:

<?php
//start buffering output
ob_start();
echo 'Hello'; //echo something, string is buffered now, nothing is sent
var_dump(strlen(ob_get_contents()); // this should print int(5), as 5 bytes are in the string echoed
//get the buffered output, flush output buffer and stop buffering
$output = ob_get_flush();
//echo first 10 milion bytes (10 MB) = send it to the client
echo substr($output, 0, 1e7);

有关输出缓冲的更多信息,请参阅 PHP 文档中的 ob_start() 和 ob_get_flush()。