2012-03-02 78 views
3

PHP腳本需要25秒才能完成(對於1人),並且可能需要更長時間才能完成高通信量。我不希望瀏覽器超時(PHP不會 - 我set_time_limit(0);)。如何防止瀏覽器超時(長PHP腳本)

有人可以提供示例代碼關於如何確保瀏覽器不超時(或者詳細解釋怎麼做)?什麼是最好的方法?阿賈克斯?

謝謝。

編輯:

布賴恩·格雷厄姆說,「一旦JavaScript的開始一個Ajax請求,它運行直到它完成,退出或錯誤,據我所知,如果用戶離開它甚至應該做到這一點。頁。」

所以,我可以簡單地通過Ajax調用長PHP腳本,然後它將運行不管超時是否需要(即使腳本沒有返回任何內容)?

+1

^同意。你會發現很多人在棧上更有幫助,當他們看到你確實接受,並給他們的聲譽,當他們把自己的時間來幫助你與你的問題;) – Brian 2012-03-02 20:46:18

+0

你需要的是分析,這樣你就可以找出哪些部分是什麼你頁面需要很長時間才能完成然後你可以加速這些部分。 – Arjan 2012-03-02 20:50:56

+0

這是事情 - 大約3/4的時間涉及到聯繫遠程服務器。無論我的網站有多少流量,此服務器的速度都不會改變。您是否認爲即使我通過URL直接運行腳本,瀏覽器仍然有機會以高流量超時運行? – Hope4You 2012-03-02 20:55:13

回答

6

這確實取決於你的腳本是做什麼它發回,但如果你可以使用AJAX,這將是該方式去。它不僅會讓你長時間運行請求,而且不會阻塞瀏覽器,讓用戶自由地繼續使用當前頁面,直到請求完成。

實現類似此類功能的最佳方式是設置ignore_user_abort並關閉時間限制。這樣你可以讓腳本在後臺運行。這樣腳本可以在用戶瀏覽您的網站時繼續運行。他們甚至不必呆在同一頁面上。所以你通過AJAX發起請求來啓動它。在該腳本中有一個循環,用於更新用戶會話的進度。

ini_set('session.use_cookies', 0); //don't spam the user with cookies for each session_start() 
while(...) { 
    session_start(); 
    //update status to the user's session 
    session_write_close(); 
    //sleep or whatever 
} 

很明顯,這不一定是一個循環。您可以在開始處理信息之前關閉會話,然後打開它,設置狀態並再次關閉。一次只有一個腳本可以訪問用戶的會話,因此您需要確保此過程不會影響用戶的會話。

然後,所有你需要做的就是讓您網站上,讓用戶知道什麼時候不管它是你正在做的是完成和/或爲他們提供文件/輸出/等的網頁運行的腳本。

這樣就減少了用戶繼續瀏覽您的網站的腳本運行時,不會強迫他們坐在一個頁面在加載指示燈59。。

+0

這看起來像是我最好的解決方案。通過Ajax啓動進程,然後使用Ajax檢查會話的值,一旦進程結束,顯示結果。這應該會阻止瀏覽器超時,因爲即使瀏覽器中止了瀏覽器,該進程仍將繼續運行。 – Hope4You 2012-03-02 20:53:03

+0

這是正確的:)只要你不需要直接從該腳本返回任何結果到瀏覽器,這是有效的。如果您需要將任何輸出寫入瀏覽器,則需要編寫自己的通信通道,使用Comet-like輪詢系統從會話中檢索更新。祝你好運;) – Brian 2012-03-02 20:56:11

2

您需要使用AJAX請求啓動主進程,然後不斷輪詢服務器以檢查進度。沒有辦法告訴瀏覽器不要超時。 (可以理解的是,如果我的瀏覽器掛了5分鐘,我會很困惑)

我建議爲腳本的每次運行分配一個唯一的ID,然後在AJAX請求中傳回。然後,在未來的狀態輪詢中,只需傳遞該ID,輪詢腳本就可以返回狀態。你如何處理狀態將取決於究竟發生了什麼。

+0

我真的不知道如何處理狀態。這個簡單的解決方案也能工作嗎? - 通過Ajax啓動進程,然後每隔幾秒使用Ajax從服務器請求一個像素gif(任何可以保持連接的活動)。這將保持腳本連接? (我將使用onreadystatechange來知道進程何時完成)。 – Hope4You 2012-03-02 20:43:09

+0

一旦javascript開始一個ajax請求,它會運行,直到它完成,退出或錯誤。據我所知,如果用戶離開頁面,甚至應該這樣做。 – 2012-03-02 20:45:04

+0

保持活動狀態的連接將掛起大請求。在轉移到下一個請求之前,持續連接完成請求。最簡單的(儘管也許不是最好的)方式做處理事情(雖然你應該考慮的一些喬納森希巴德的建議,試圖找出爲什麼腳本需要很長時間),是創建一個名爲無論狀態ID是在開始腳本,然後在腳本結尾刪除文件。您的狀態檢查將只是:如果文件存在,仍在運行,否則,完成。 – Corbin 2012-03-02 20:46:08

1

如果你不想讓瀏覽器超時,那麼這裏是我可能爲你考慮的唯一解決方案....只要知道這一點:我設置PHP 10秒後超時。如果花費比這更長的時間處理 - 那麼腳本不適合訪問我的網站的用戶。

1)優化你的代碼 - 找出你的代碼中哪些部分花費的時間過長,並確定你可以做些什麼來使其更快。

2)使用推/拉解決方案。將請求推送到服務器並告訴它執行一個應用程序。應用程序被放入要運行的隊列中,並且服務器返回進程ID。服務器上的守護進程檢查隊列並執行腳本cli而不是瀏覽器。

3)創建單獨的例程,需要單獨的ajax風格的方法調用。調用例程1啓動一段腳本。調用例程2發出另一個ajax請求,並在第一個返回完成後啓動第二個。等等

4)老實說 - 我只是找到另一種解決方案。很明顯,如果你的腳本採取這一長期執行,事情是可怕 ...

+1

大部分時間(大概3/4)都是聯繫遠程服務器 - 我無法控制的速度。 – Hope4You 2012-03-02 20:45:55

+0

再次,這是你想分離出來的東西。創建一個由守護進程/ cron腳本處理的隊列或者你想做的任何事情就是如何「控制」它。 在一天結束的時候,你要問自己這樣一個問題:是用戶要等到我得到迴應,或者是他們將要離開我的網頁之前,我甚至可以給他們一個答覆。 – 2012-03-02 20:56:03

+0

希望他們等待 - 腳本實際上用於處理訂單!這就是爲什麼我要確保瀏覽器不超時。謝謝您的幫助。 – Hope4You 2012-03-02 21:00:29