这种用于缓存动态内容的简单方法使用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);
});
}
答案 0 :(得分: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
会将数据发送回浏览器,然后继续执行之后编写的任何代码。
答案 1 :(得分:1)
首先, 如果以这种方式缓存动态内容,那么你做错了。当然它可以这样使用,它可以工作,但它完全瘫痪的方法本身。
如果你想有效地缓存和处理内容,可以创建一个类并将所有缓存函数包装成。
是的,您可以像fast_cgi_finish_request()
一样使用register_shutdown()
。唯一的区别是,fast_cgi_finish_request()
将发送输出(如果有)并且将不会终止脚本,而在脚本终止时将调用register_shutdown()
的回调。 / p>
答案 2 :(得分:0)
这是一个老问题,但我不认为任何答案都能正确回答问题。
据我了解,问题是在关闭函数期间发生的ob_get_flush()调用之前,没有任何输出被发送到客户端。
要解决该问题,您需要将函数和块大小传递给ob_start(),以便以块的形式处理输出。
你的其他条款有这样的事情:
$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);