所以,我正在寻找比这更有效的东西:
<?php
ob_start();
include 'test.php';
$content = ob_get_contents();
file_put_contents('test.html', $content);
echo $content;
?>
上述问题:
- 在呈现整个页面之前,客户端不会收到任何内容
- 文件可能很大,所以我宁愿不把整个东西都放在内存中
有什么建议么?
所以,我正在寻找比这更有效的东西:
<?php
ob_start();
include 'test.php';
$content = ob_get_contents();
file_put_contents('test.html', $content);
echo $content;
?>
上述问题:
有什么建议么?
有趣的问题;不要以为我以前尝试过解决这个问题。
我认为您需要从您的前端 PHP 脚本向您的服务器发出第二个请求。这可能是对http://localhost/test.php的简单调用。如果您使用 fopen-wrappers,您可以使用 fread() 在渲染时提取 test.php 的输出,并在收到每个块后,将其输出到屏幕并将其附加到您的 test.html 文件中。
以下是它的外观(未经测试!):
<?php
$remote_fp = fopen("http://localhost/test.php", "r");
$local_fp = fopen("test.html", "w");
while ($buf = fread($remote_fp, 1024)) {
echo $buf;
fwrite($local_fp, $buf);
}
fclose($remote_fp);
fclose($local_fp);
?>
更好的方法是使用ob_start
:output_callback
和. 接受的前两个参数chunk_size
。前者指定一个回调来处理缓冲的输出,后者指定要处理的输出块的大小。
这是一个例子:
$output_file = fopen('test.html', 'w');
if ($output_file === false) {
// Handle error
}
$write_ob_to_file = function($buffer) use ($output_file) {
fwrite($output_file, $buffer);
// Output string as-is
return false;
};
ob_start($write_ob_to_file, 4096);
include 'test.php';
ob_end_flush();
fclose($output_file);
在此示例中,每输出 4096 个字节(并在调用结束时再一次),将刷新(发送)输出缓冲区ob_end_flush
。每次刷新缓冲区时,$write_ob_to_file
都会调用回调并传递最新的块。这被写入 test.html。然后回调返回false
,意思是“按原样输出这个块”。如果您只想将输出写入文件而不是 PHP 的输出流,则可以改为返回一个空字符串。
Pix0r 的答案是你想要的,除非你真的需要它“包含”而不是仅仅执行。例如,如果您在 test.php 之前有登录信息,如果您使用 fopen 调用它,它将不会被传递到文件中。
如果您需要真正包含它,那么您所拥有的是最简单的方法,但如果您想要持续输出,您需要实际编写 test.php 以输出和存储信息的方式。据我所知,没有办法既收集缓冲区又随时输出。
在这里你可以使用x-send-file,使用 mod_xsendfile 来高效地发送文件,真的很简单。