4

这种缓存动态内容的简单方法用于register_shutdown_function()在退出脚本后将输出缓冲区推送到磁盘上的文件。但是,我使用的是PHP-FPM,这不起作用;添加到函数中的 5 秒睡眠确实会导致从浏览器执行脚本时延迟 5 秒。PHP 文档中的评论者指出,PHP-FPM 用户有一个特殊功能,即fastcgi_finish_request(). 但是,没有太多关于这个特定功能的文档。

的重点fastcgi_finish_request()似乎是刷新所有数据并继续执行其他任务,但我想要实现的,通常会使用register_shutdown_function(),基本上是将输出缓冲区的内容放入文件中,而无需用户等待完成。

有没有办法在 PHP-FPM 下使用fastcgi_finish_request()或其他功能来实现这一点?

$timeout = 3600; // cache time-out
$file = '/home/example.com/public_html/cache/' . md5($_SERVER['REQUEST_URI']); // unique id for this page
if (file_exists($file) && (filemtime($file) + $timeout) > time()) {
  readfile($file);
  exit();
} else {
  ob_start();
  register_shutdown_function(function () use ($file) {
    // sleep(5);
    $content = ob_get_flush();
    file_put_contents($file, $content);
  });
}
4

3 回答 3

3

是的,可以使用fastcgi_finish_request它。您可以保存此文件并查看它是否有效:

<?php

$timeout = 3600; // cache time-out
$file = '/home/galymzhan/www/ps/' . md5($_SERVER['REQUEST_URI']); // unique id for this page
if (file_exists($file) && (filemtime($file) + $timeout) > time()) {
  echo "Got this from cache<br>";
  readfile($file);
  exit();
} else {
  ob_start();
  echo "Content to be cached<br>";

  $content = ob_get_flush();
  fastcgi_finish_request();
  // sleep(5);

  file_put_contents($file, $content);
}

即使您取消注释该行sleep(5),您仍会看到该页面仍会立即打开,因为fastcgi_finish_request将数据发送回浏览器,然后继续执行其后编写的任何代码。

于 2013-02-23T10:33:07.070 回答
1

首先,如果你用这种方式缓存动态内容,你就错了。当然,它可以以这种方式使用并且能够工作,但它完全被这种方法本身所瘫痪。

如果您想有效地缓存和处理内容,请创建一个类并将所有缓存功能包装到其中。

是的,您可以fast_cgi_finish_request()register_shutdown(). 唯一的区别是,fast_cgi_finish_request()将发送输出(如果有)并且不会终止register_shutdown()脚本,而在脚本终止时将调用回调。

于 2013-03-01T23:08:31.187 回答
0

这是一个老问题,但我认为任何答案都不能正确回答这个问题。

据我了解,问题是在关闭函数期间发生 ob_get_flush() 调用之前,没有任何输出被发送到客户端。

要解决该问题,您需要将函数和块大小传递给 ob_start() 以便以块的形式处理输出。

你的 else 子句是这样的:

$content = '';

$write_buffer_func = function($buffer, $phase) use ($file, &$content) {
  $content .= $buffer;
  if ($phase & PHP_OUTPUT_HANDLER_FINAL) {
    file_put_contents($file, $content);
  }
  return $buffer;
};

ob_start($write_buffer_func, 1024);
于 2015-08-12T14:01:59.617 回答