2011-08-24 36 views
6

我們一直在使用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刷新數據?

回答

7

您必須將所需處理的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元素。

3

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

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是它的工作原理。 –

1

這取決於它是否決定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() 
{ 
    .... 
} 
4

在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)

23

還有另一種方式來設置使用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

這是最好的飲料。謝謝 –

2

我對聚會有點遲到,但認爲我會添加如何使用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> 
0

下面是使用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>