PHP刷新停止在IIS7.5中冲洗

问题描述:

我们一直在使用php flush在点击时立即“空白”页面,并且还发送页面的导航和主要组件,以便页面几乎立即出现即使有时这些内容可能需要很长时间才能加载。PHP刷新停止在IIS7.5中冲洗

这一直工作得很好。

最近我们从IIS 7.0升级到7.5,现在刷新不起作用。在调查问题时,我们已经关闭了静态和动态文件的压缩。我们也关闭了输出缓存。

我们还关闭了zlib压缩并在php.ini中输出缓冲。

为了测试,我们有以下脚本

@ini_set("output_buffering", "Off"); 
@ini_set('implicit_flush', 1); 
@ini_set('zlib.output_compression', 0); 

ob_start(); 

echo "starting...<br/>\n"; 
for($i = 0; $i < 5; $i++) { 
    print "$i<br/>\n"; 
    ob_end_flush(); 
    ob_flush(); 
    flush(); 
    ob_start(); 
    sleep(2); 
} 
print "DONE!<br/>\n"; 

浏览器只是显示加载状态(无论是在任何浏览器中的问题,在IE浏览器,它看起来像一个Ajax gif动画,在Firefox中标签会显示“Connecting ...”)10秒钟,然后突然显示整个输出。

根据本网站上的类似问题,我们尝试了各种flush和ob_flush和ob_end_flush的组合。他们都没有工作。有没有办法让IIS/PHP刷新数据?

您必须将所需处理的ResponseBufferLimit值设置为一个数字足以实际上平齐低。我建议使用0,因为它可以防止IIS做任何事情,只是传递从PHP脚本发送的内容。 您可以使用下面的命令行设置ResponseBufferLimit为0 PHP的处理程序(只需更改“NAME”到要更新例如PHP53_via_FastCGI处理程序的名称):或者

appcmd.exe set config /section:handlers "/[name='NAME'].ResponseBufferLimit:0" 

,您可以编辑直接在applicationHost.config中添加一个ResponseBufferLimit属性的XML元素。

我要做的是,我使用下面的函数:

function flush_buffers(){ 
    ob_end_flush(); 
    ob_flush(); 
    flush(); 
    ob_start(); 
} 

因此,在你的代码:

ob_start(); 
flush_buffers(); 

echo "starting...<br/>\n"; 
for($i = 0; $i < 5; $i++) { 
    print "$i<br/>\n"; 
    flush_buffers(); 
    sleep(2); 
} 

它应该工作得很好:-)


这里一些工作代码(使用正确的Content-Type设置):
DEMO
CODE

<?php 
header("Content-Type: text/html; charset=utf-8"); 
function flush_buffers(){ 
    ob_end_flush(); 
    ob_flush(); 
    flush(); 
    ob_start(); 
} 

ob_start(); 
flush_buffers(); 
echo "starting...<br/>\n"; 
for($i = 0; $i < 60; $i++) { 
    flush_buffers(); 
    print "$i<br/>\n"; 
    flush_buffers(); 
    sleep(2); 
} 

flush_buffers(); 

print "DONE!<br/>\n"; 
?> 
+0

这工作。把它分开,看看哪个是关键... –

+0

@Jeff,这个演示应该有点帮助:-) – Neal

+1

它看起来像关键是content-type:text/html;字符集= UTF-8。将此添加为标题也可以。特别是它看起来像charset = utf-8是它的工作原理。 –

这取决于它是否决定naggle内容或通过分块编码发送的网络服务器。所以尽管PHP可以要求服务器将数据推送到客户端,但它不能强制服务器使用分块编码。

This article建议您明确地需要为发送数据到服务器设置IIS的传输编码(请参阅关于ISAPI的位) - 您可能会在脚本中尝试相同。

IME,大多数场景中,这是一个问题,可以更好地处理与....

register_shutdown_function('do_slow_stuff'); 
....generate html content.... 
exit; // closes stdin/stdout, but shutdown fn will still be called 

function do_slow_stuff() 
{ 
    .... 
} 

在PowerShell中以管理员身份输入以下命令:

C:\Windows\System32\inetsrv> .\appcmd.exe set config /section:handlers "/[name='PHP_via_FastCGI'].ResponseBufferLimit:0" 

预期输出:

将配置更改应用于“系统”部分。web服务器/处理器” “机器/ WEBROOT/APPHOST” 在配置COMM其路径 “MACHINE/WEBROOT/APPHOST”

欲了解更多的背景,看看:http://www.coastrd.com/cgioniis7

基本上,我们需要。告诉FastCGI的把它ResponseBufferLimit的这无法通过IIS管理控制台做(检查仅7.5)

还有另一种方式来设置使用IIS管理器的响应极限:

  1. 在服务器主页面的“管理”下选择“配置编辑器”;
  2. 在“Section”下输入'system.webServer/handlers';
  3. 在“(Collection)”旁边点击“...”或者标记元素“(Collection)”,在“Actions”和“(Collection)”元素下点击“Edit Items”。
  4. 向下滚动,直到找到“Name”下的PHP版本;
  5. 底部显示的属性可以手动编辑,包括responseBufferLimit,它应该设置为0以使flush()工作。

大的Pro是你可以编辑一切的属性,不仅PHP加上你可以使用PHP的不同版本(甚至安装相同版本)。

HTH

+2

+1优秀!这是我第一次看到通过IIS管理器设置responsebufferlimit的解决方案。 – Rich

+0

这是最好的饮料。谢谢 –

我对聚会有点迟到,但认为我会添加如何使用web.config做到这一点。

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
     <!--- other stuff here ---> 
     <handlers> 
      <remove name="ISAPI-dll" /> 
      <add name="ISAPI-dll" path="*.dll" verb="*" type="" modules="IsapiModule" scriptProcessor="" resourceType="File" requireAccess="Execute" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
     </handlers> 
    </system.webServer> 
</configuration> 

下面是使用web.config(@ Jules的方法不适用于IIS 8.0)的另一种方法。当然,你会想用你的机器上实际的PHP版本和路径替换。

这允许使用服务器发送的事件!

<configuration> 
    <system.webServer> 
     <handlers> 
      <remove name="PHP53_via_FastCGI" /> 
      <remove name="PHP54_via_FastCGI" /> 
      <remove name="PHP55_via_FastCGI" /> 
      <add name="PHP53_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.3\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
      <add name="PHP54_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.4\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
      <add name="PHP55_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.5\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> 
     </handlers> 
    </system.webServer> 
</configuration>