爲什麼如果客戶端關閉瀏覽器(因此連接到服務器),此虛擬腳本會繼續運行事件?PHP腳本不會在瀏覽器退出時退出
while (true) { sleep(1); file_put_contents('/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND); }
而且帶有非零參數的set_time_limit根本什麼都不做。
我想澄清一下。
爲什麼如果客戶端關閉瀏覽器(因此連接到服務器),此虛擬腳本會繼續運行事件?PHP腳本不會在瀏覽器退出時退出
while (true) { sleep(1); file_put_contents('/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND); }
而且帶有非零參數的set_time_limit根本什麼都不做。
我想澄清一下。
如果您嘗試在該循環中將一些輸出寫入瀏覽器,您應該發現如果連接已終止,腳本將中止。這種行爲是在文檔中暗示了ignore_user_abort
當運行PHP命令行腳本,腳本的TTY去 遠沒有腳本被終止,則該腳本將嘗試寫 下一次死亡任何東西,除非值設置爲TRUE
我嘗試了一些自己的實驗,結果發現,即使你嘗試一些瀏覽器輸出,該腳本將繼續運行,如果輸出緩衝區還沒有滿。如果關閉輸出緩衝,則在嘗試輸出時腳本將中止。這是有道理的 - 當SAPI層嘗試傳輸輸出時,應該注意到請求已被終止。
下面是一個例子...
//ensure we're not ignoring aborts..
ignore_user_abort(false);
//find out how big the output buffer is
$buffersize=max(1, ini_get('output_buffering'));
while (true)
{
sleep(1);
//ensure we fill the output buffer - if the user has aborted, then the script
//will get aborted here
echo str_repeat('*', $buffersize)."\n";
file_put_contents('/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND);
}
演示什麼觸發中止。如果你有一個腳本很容易進入一個沒有輸出的無限循環,你可以使用connection_aborted()來測試連接是否仍然打開。
set_time_limit
只限制花費在php代碼上的時間。大部分時間(我猜測> 99.9%)在您的程序中花費在系統調用中,將數據寫入文件並進行睡眠。
ignore_user_abort
只有當你(而不是在本地文件)寫的東西到客戶端中止 - 有根本沒有辦法可以在TCP區分未使用和終止的連接,否則,除非客戶excplicitely終止連接與RST數據包。
您忽略了用戶中止,而沒有向客戶端做任何輸出。 – hakre