我試圖找出爲什麼這個循環沒有任何返回到瀏覽器:PHP無盡while循環混亂
while(1) {
echo "hello";
flush();
sleep(1);
}
我期待它返回「你好」到瀏覽器每一秒。 .. 我錯了嗎?現在這個頁面似乎掛起了。
我試圖找出爲什麼這個循環沒有任何返回到瀏覽器:PHP無盡while循環混亂
while(1) {
echo "hello";
flush();
sleep(1);
}
我期待它返回「你好」到瀏覽器每一秒。 .. 我錯了嗎?現在這個頁面似乎掛起了。
在收到整個頁面之前,瀏覽器不會顯示任何東西。 PHP不能完成你想要完成的任務。
在Javascript中,這很簡單。
<script>
window.setInterval(function(){document.innerHTML += "<br> Hello"}, 1000)
</script>
PHP只在執行完成後輸出。所以你所做的每一毫秒都會產生一個新的hello,並且由於你永遠不會退出循環,所以你永遠不會看到輸出。
是什麼flush()是爲了什麼? – mootymoots 2013-03-08 20:38:07
閱讀刷新文檔:http://php.net/manual/en/function.flush.php刷新「排序」的作品,但更多的時候,不是, – bizzehdee 2013-03-08 20:39:17
不正確,你可以真正輸出一行,但你有到'flush()'並且確保'output_buffering'被禁用,或者調用'ob_flush()'作爲valentin所說的 – 2013-03-27 11:29:06
您應該認識到PHP是一種腳本語言,因爲它僅在完成腳本後才返回輸出。編輯:或者輸出緩衝區填充後,謝謝@Marc B. 無論我會說這是更聰明的使用JS或如果你真的需要你的服務器,使用AJAX請求。
也許你應該考慮使用Javascript?這將允許你每秒添加內容(請記住JS在客戶端運行,所以你可能不想讓你的操作全部擴展)。
或者你可以考慮使用AJAX請求例如JQuery的,但可能是這個問題的範圍...
不完全正確。 PHP可以/會根據需要將輸出發送給客戶端。但只有當腳本完成和/或輸出緩衝區填滿時。很可能有一個php腳本發送無限數據,並且會很快顯示在客戶端。 – 2013-03-08 20:44:52
你說得很對,謝謝我解決了我的答案,以反映這個評論:) – MrHug 2013-03-08 20:48:42
添加到所有其他的答案,
要做到異步服務器推到客戶端,您需要使用WebSockets。這是一個很大的課題,並沒有完全標準化,但是確實有這樣做的方法。如果您有興趣搜索PHP Websockets。
也許是未爲晚矣回答,但如果你想在這裏刷新每一秒,我給你一個例子:
<?php
echo "Flushing every second ...\n";
flush();
$seconds = array (0,1,2,3,4,5,6,7,8,9);
foreach ($seconds as $second):
echo $second . "\n";
sleep(1);
@ob_flush(); flush();
endforeach;
echo 'I flashed 10 second :P';
要糾正我的答案,讓你更好地理解,併爲AJAX愛好者。 .. 你需要和額外的沖洗有..在 'ob_' 之一:
<?php
while(1):
echo "hello";
ob_flush(); flush();
sleep(1);
endwhile;
這是大家誰需要知道的 '特技';)
這不是一個好的答案,因爲它不能可靠地工作(如果有的話),如文檔[這裏](http://stackoverflow.com/問題/ 5770917)和[ob_flush()的評論](http://www.php.net/manual/en/function.ob-flush.php#allnotes)。 AJAX是實現在所有瀏覽器中可靠且一致地提出問題的唯一方法。而無需修改服務器設置。 – mastaBlasta 2013-03-22 15:17:33
Valentin給了你正確的答案(upvote他/接受他的答案!),但沒有解釋爲什麼。這裏的解釋:
PHP不輸出馬上瀏覽器,等待有一些內容量發送到瀏覽器(可能是它發出的1024,2048或4096字節的塊),或執行結束時。調用flush()
會使PHP發送數據,但有多個緩衝層。一個是內部緩衝(我剛剛評論過),但是你可以添加更多的緩衝層。假設此代碼:
<?php
echo "hi";
setcookie('mycookie', 'somevalue');
?>
的setcookie()
函數發送一個HTTP報頭到瀏覽器,但它不能這樣做,因爲在HTTP的服務器(或客戶端,這是相同的兩種方式),必須首先發送所有標題,空白行,然後是內容。正如你所看到的,你正在輸出一些內容(hi)在標題之前,所以它失敗(因爲內部緩衝遵循相同的執行順序)。
您可以使用php函數ob_*()
添加另一層輸出緩衝。用ob
緩衝它只緩衝內容輸出,而不是HTTP頭。您可以使用它們來獲取直接輸出到瀏覽器的功能的輸出,如var_dump()
。此外,您還可以巢層ob
:
<?php
// start first level of output buffering
ob_start();
echo "nesting at level ", ob_get_level(), "<br />\n"; // prints level 1
echo "hi<br />";
ob_start();
echo "nesting at level ", ob_get_level(), "<br />\n"; // prints level 2
var_dump($_POST);
$post_dump = ob_get_clean();
// this will print level 1, because ob_get_clean has finished one level.
echo "nesting at level ", ob_get_level(), "<br />\n";
echo "The output of var_dump(\$_POST) is $post_dump<br />\n";
// in spite of being inside a layer of output_buffering, this will work
setcookie('mycookie', 'somevalue');
// flush the current buffer and delete it (will be done automatically at the
// end of the script if not called explicitly)
ob_end_flush();
也許你的PHP服務器output_buffering默認情況下啓用。默認情況下,請參閱configuration variables將其關閉/打開。
好吧,卡洛斯批評我,因爲我沒有解釋我的答案,但他的答案是含糊不清......用餅乾,圖層...... POST,ob_levels ...:OO到很多信息,沒有真正的關於真正的用戶問題,但我會告訴你爲什麼你的代碼不工作。因爲你在php.ini設置的輸出緩衝是這樣的:
output_buffering = On
或
output_buffering = 4096 (default setting on most distributions)
這就是爲什麼你需要額外的「使用ob_flush()」,擺脫任何垃圾輸出。 。
所以......爲了讓你的代碼工作,你有兩個選擇:
1). set output_buffering = 0 or Off (if you have access to the php.ini)
2). ob_flush many times as layers of buffering you have
如果你不知道如何MA紐約層你有,你可以這樣做:
while (@ob_end_clean());
和清潔每垃圾,你可以有,然後你的代碼會工作得很好.. 完成snipp:
<?php
while (@ob_end_clean());
while(1) {
echo "hello";
flush();
sleep(1);
}
氰..
你的HTTP服務器正在緩衝輸出 – galchen 2013-03-08 20:36:32
不是什麼flush()的用途? – mootymoots 2013-03-08 20:38:28
排序,閱讀http://php.net/manual/en/function.flush.php – galchen 2013-03-08 20:40:05