原創|行業資訊|編輯:龔雪|2014-01-06 09:45:56.000|閱讀 615 次
概述:如果你的web應用或服務必須按需在服務器端執行一個可能很巨大的處理過程,本文則正好適合你。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
背景:
當我們的頁面調用服務器動作,基本的php腳本比指定于超時服務器參數需要更多的時間,可以確定接下來的響應將是504(超時)服務器錯誤。如果你有其它選擇得到同樣的方法來改變應用結構或者UI體驗(沒有損壞它),我們建議您讓它在沒有多線程、shell calls或者第三方類的情況下運行。
建議使用paging和multipetition技術,有如下優點:
使用這個模式的缺點:
正如你所見的,這個技術并非所有情況都適用,但對于相當多的問題來說,它是個完美的解決方案。
使用代碼:
首先是考慮如何將我們的任務分成盡可能小的邏輯片段。這些將被視為元素。我們將需要在每個請求中用到所有這些元素,但只有頁面上的元素是需要的,是被處理的。
舉個例子,我們將導入一個csv文件到數據庫。以下是處理頁面的函數腳本:
<?php $path = '/userFiles/import.csv'; /* Local path to file */ $page = $_POST["page"]; /* Page to process (from JavaScript) */ $pageSize = 1000; /* Number of lines to process by page */ $first = $pageSize * $page; /* First line to process. */ $line = 0; /* Current line. */ $processed = 0; /* Number of lines currently processed. */ /* Begins to read the CSV */ $file = fopen($path, "r"); while ($lineStr = stream_get_line($file, 65536, "\n")) { if ($line >= $first) { /* Only if current line is within the requested page */ /* Process this line */ insertLineInDatabaseOrDoAnyHeavyThingWithIt($line, $lineStr); $processed ++; if ($processed = $pageSize) break; /* Page end */ } $line ++; } fclose($file); /* Returns number of processed lines */ echo $processed;
這是服務端,下面則是JavaScript客戶端:
function import() { pageImport(0); // Launch first page } function pageImport(page) { $.post("/import.php", { // Calls our php script asynchronously using jQuery page: page }, function(data) { // Callback if (data > 0) pageImport(page + 1); // Lines were processed so go on with next page else alert("Work finished"); // No more lines processed, so we have finished. }); }
兩種方式都需要:第一種啟動第一頁,第二種遞歸調用自身處理下一個頁面知道沒有更多的記錄。不難想象如何用JSON執行一個進度條以在相同的響應中返回已處理的行和總的頁數。
注意點:
$pageSize越小,出現504錯誤的可能性就越小,但需要更多時間來完成整個進程,因為在每個請求上我們讀取當前頁之前的所有CSV行。$pageSize的最優質的是盡可能大卻又耗費比服務器所定義的超時更少的時間來完成一頁。舉個例子,如果我們的超時定義為60秒,處理一頁應該需要45到50秒或更少。通過瀏覽器上的F12開發者工具,很容易猜到這一點。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:慧都控件網