我有一個循環,說:如何設置循環的時間限制?
$lines = file('file.txt');
foreach ($lines as $line) {
// some function
}
有些時候,這需要更多的時間來完成一個循環,如果數據不可用。那麼,如何爲每個循環設置一個時間限制,如果有任何信息不可用,它將移動到下一個?
我有一個循環,說:如何設置循環的時間限制?
$lines = file('file.txt');
foreach ($lines as $line) {
// some function
}
有些時候,這需要更多的時間來完成一個循環,如果數據不可用。那麼,如何爲每個循環設置一個時間限制,如果有任何信息不可用,它將移動到下一個?
用循環前的time()存儲當前時間,並將循環開始時的當前時間與當前時間進行比較,並且如果設定時間已過,則中斷。
正如tharkun所說,雖然,你應該首先檢查數據是否可用。如果文件外部更改,則會想到filemtime()。
您應該測試以查看數據是否可用而不是創建計時器。
$lines = file('file.txt');
if (!empty($lines)) {
foreach ($lines as $line) {
// some function
}
}
您只需檢查$ lines數組中是否有任何數據,然後嘗試使用foreach對它進行迭代。例如:
<?php
$lines = file('file.txt');
if (!empty($lines)) {
foreach ($lines as $currentLine) {
...
}
}
?>
這就是說,對於大文件(其中通過使用文件可能不適合在內存中產生的陣列),你應該同時使用while循環讀取一行直到文件的末尾( EOF)標記被找到。
例如:
<?php
$fileHandle = fopen("test.txt");
if(is_resource($fileHandle)) {
while (!feof($fileHandle)) {
$currentLine = fread($fileHandle);
}
fclose($handle);
}
?>
根據這個代碼,如果數據不可用,循環不開始了! 所以,問題需要更具體。
你怎麼去取決於循環內部的內容。
如果它是一個嵌套的循環和持續時間長,以迭代的內部循環數的出現是由於,那麼你就可以在你的代碼如檢測到這一點:
foreach ($lines as $line) {
$iters=strtok($line, ',');
$start_iter=time();
for ($x=0; $x<$iters; $x++) {
... do something here
if (time()-$start_iter>600) {
print "abandoning $line after $x iterations\n";
break;
}
}
}
OTOH,如果函數本質上是原子,例如
foreach ($lines as $line) {
mysql_query($line);
}
然後,控件將永遠不會返回到您的代碼,直到操作完成。但是,這並不意味着它不可能中斷處理並繼續到下一行 - 有兩種方法可以做到這一點:
1)使用pcntl_alarm觸發信號處理程序 - 請注意,它本身並不能解決在上述情況下的問題 - 因爲在信號處理程序完成時,被調用的函數將會重新開始 - 在某些情況下,強制終止函數可能會過早終止。
2)在單獨的進程中運行循環的內部部分,並在進程溢出時終止進程。
查看pcntl函數以獲取更多細節 - 注意這些函數僅適用於Linux/Unix/POSIX環境。
您需要顯示更多的代碼,因爲此時您的問題無法回答。 「有些時候,如果數據不可用,則需要更多時間才能完成一個循環」對於您當前的發佈代碼沒有意義。 – thirtydot 2011-01-13 10:09:34
對不起,但我不明白這個問題。你能否詳細說明一下? – davogotland 2011-01-13 10:10:25