Php 在Zend Framework中呈现页眉后刷新缓冲区

Php 在Zend Framework中呈现页眉后刷新缓冲区,php,zend-framework,flush,output-buffering,Php,Zend Framework,Flush,Output Buffering,我们的应用程序在head标签中有很多CSS和JS,为了提高感知的页面加载速度,我希望页面尽快开始获取外部内容,即使在等待服务器提供其他内容时也是如此。基本上,我的目标是让浏览器在等待主体内容交付时开始获取head标记中的CSS和JS。 因此,在主布局页面中,我尝试在呈现head标记后刷新缓冲区(在php.ini中关闭了输出缓冲): 此处呈现的正文内容。 这基本上没有效果。当我查看Chrome中的网络活动时,我看到head标签和body标签都是在一个响应中交付的,只有在完成加载之后,其他资源才

我们的应用程序在head标签中有很多CSS和JS,为了提高感知的页面加载速度,我希望页面尽快开始获取外部内容,即使在等待服务器提供其他内容时也是如此。基本上,我的目标是让浏览器在等待主体内容交付时开始获取head标记中的CSS和JS。

因此,在主布局页面中,我尝试在呈现head标记后刷新缓冲区(在php.ini中关闭了输出缓冲):


此处呈现的正文内容。
这基本上没有效果。当我查看Chrome中的网络活动时,我看到head标签和body标签都是在一个响应中交付的,只有在完成加载之后,其他资源才开始按顺序加载,而不是像我预期的那样并行加载

我尝试了许多其他的组合,运气不好。我还读到,刷新输出缓冲区之后需要调用flush(),但这给了我奇怪的结果:页面只显示了一堆奇怪的外来字符(可能是试图显示二进制文件还是什么?)

我甚至尝试只在head和body标记之间使用flush()调用,但这引发了一个错误,告诉我我正在尝试在发送头之后修改头,因此这对我也没有任何用处

然后,我试着看看是否有一个特定于Zend框架的解决方案。有人告诉我,我试图做的事情是不可能的,因为ZF将整个页面从内存中的模板呈现出来,因此它不能在渲染过程中被刷新并返回到浏览器,ZF基本上忽略PHP的OutuPuffSimulink配置值。 我想我已经用尽了所有可能的函数组合,所以我想知道是否有其他人也有类似的问题,方法是什么

服务器版本:Apache/2.2.22(Ubuntu)

(作为旁注,是的,我知道应该在页面底部加载JS,但这不是我将其放在head标签中的要求)

更新1

我得到了我想要的,部分是当我尝试以下方法时:

<?php ob_start('ob_gzhandler'); ?>
<head>
<?php
// A bunch of function calls to render tags for external style sheets and JS
?>
</head>
<?php ob_end_flush(); ?>
<body>
Body content rendered here . . .
</body>

此处呈现的正文内容。
我将ob_start的回调添加到ob_gzhandler。执行此操作将返回一个包含head标记的响应,而不包含body。这很好,因为只要head标记出现,资源就开始加载,但是body标记永远不会出现,页面基本上是空白的。这就好像告诉它刷新缓冲区一样,但脚本在完成执行后再也不会刷新


我已经在布局脚本的末尾显式地添加了对ob_flush(和其他变体)的调用,但它们要么什么都不做,要么抱怨没有缓冲区进行刷新(可能是因为我以前调用过ob_end)。

来自未来处理遗留ZF1项目:

这不起作用的原因很简单,因为ZF已经在缓冲布局的输出

$obStartLevel=ob_get_level();
试一试{
$fullContent=$layout->render();
$response->setBody($fullContent);
}捕获(例外$e){
while(ob_get_level()>$obStartLevel){
$fullContent.=ob_get_clean();
}
$request->setParam('layoutFullContent',$fullContent);
$request->setParam('layoutContent',$layout->content);
$response->setBody(空);
扔$e;
}
因此,视图渲染中的任何其他类型的缓冲区操作都只会被刷新到另一个缓冲区。您也不能终止更高级别的缓冲区,因为
setBody将不会捕获输出

没有适当的解决办法。因此,解决办法是:

  • ,
  • 替代以将头部渲染为单独的布局文件
  • 在没有输出缓冲区的情况下立即输出磁头

这是实验性的,我不确定影响是什么



我不知道ZF2的解决方案是什么,但希望这能在将来帮助一些可怜的人。

经过一些测试,很明显这没有任何好处。只有在所有控制器工作完成后(因此,后期调度)才会触发这些命令。因此,下一个可能的解决方案是在完成任何有意义的工作之前,实际使用renderScript()在动作中渲染头部。只需确保只有在发送完所有头之后才能执行此操作。
<?php ob_start('ob_gzhandler'); ?>
<head>
<?php
// A bunch of function calls to render tags for external style sheets and JS
?>
</head>
<?php ob_end_flush(); ?>
<body>
Body content rendered here . . .
</body>