【问题标题】:Apache / PHP output cachingApache / PHP 输出缓存
【发布时间】:2010-08-13 09:51:10
【问题描述】:

我正在编写一个 PHP 脚本,该脚本会在不预先知道长度的情况下即时生成大型(多 MB)输出。我正在通过fwrite() 直接写信给php://output,并尝试了标准输出和使用Transfer-Encoding: chunked(根据需要对块进行编码),但无论我尝试什么,浏览器都会等到所有数据都写入后才会显示下载对话框.我也试过flush()ing 在标题之后和每个块之后,但这也没有区别。

我猜 Apache 正在缓存输出,因为浏览器在从服务器接收到几 kB 后通常会显示。

有没有人知道如何停止这种缓存并将数据在生成时刷新到浏览器?

谢谢, J

【问题讨论】:

  • 我建议使用wireshark 或类似工具查看正在向浏览器发送哪些数据,而不是猜测apache 在生成整个内容之前不会刷新。如果您需要放慢速度,请插入一些 sleep(1) 调用。 (我怀疑 Apache 在刷新其缓冲区之前会在单个套接字上维护几兆字节。)
  • 我的猜测是,您在 php.ini 和/或 apache 配置中启用了 GZIP 压缩。在这种情况下,apache 总是缓存。还没有找到避免这种情况的方法(除了禁用压缩),所以让我们看看其他人对此有何了解。可能是 serverfault.com 的问题,不过...
  • @sarnold - 当我说我猜这是一个有根据的猜测,因为我一直在通过 Fiddler 跟踪请求并且在下载对话框出现之前看不到任何响应,所以我很有信心它在服务器端缓存。 @BlaM-您说启用了GZIP是绝对正确的,我不认为这是可能的原因,因为它是流压缩算法,但这可能是问题所在。我会尝试禁用这个特定的脚本,看看会发生什么。谢谢。
  • @user290796,啊哈,那不是真的“猜测”! :) 如果@BlaM 是正确的,也许您可​​以编写自己的 Apache 输出过滤器来发送定期 FLUSH 存储桶,以保持 gzip 的好处。 (对于保存大文件似乎真的很有用。)
  • 是的,虽然我不能 100% 确定 Fiddler 在显示之前没有等待完整的输出,所以它有点猜测;)。无论如何,要输出的文件实际上是一个 ZIP 文件,因此它已经被压缩,因此保留 GZIP 可能没有太大的好处,但输出过滤器可能是一个选项。我现在不在服务器附近尝试禁用 GZIP,但我会在今天晚些时候尝试一下。

标签: php apache http caching


【解决方案1】:

首先,就像 BlaM 在他的评论中提到的那样,如果在 PHP 配置中启用了 OutputBuffering,它将无法工作,因此了解您的 phpinfo() 会很有用。

接下来,尝试它是否适用于存储在您的网络服务器上的大文件,使用 inf readfile 输出它。并且,与此一起,检查您是否发送了正确的标题。关于如何读取文件()和发送正确标题的提示:StackOverflow: How to force a file download in PHP

当您使用它时,请在脚本顶部调用ob_end_flush()ob_end_clean()

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 2016-10-19
    • 2013-02-08
    • 1970-01-01
    • 2010-09-26
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    相关资源
    最近更新 更多