a) estrarre il calcolo del tempo dal foreach. hai un'ora di inizio e vuoi un tempo di esecuzione di 5 secondi, in modo da poter calcolare l'ora di fine prima (startime + 5s). all'interno del foreach, semplicemente confrontare se il tempo è maggiore o uguale al tempo di conclusione, quindi interrompere.
b) D: è possibile avviare il loop da un certo punto? come riprendo dal punto di interruzione nella richiesta successiva?
Due approcci mi vengono in mente.
È possibile memorizzare l'ultimo punto di elaborazione e l'iteratore e riprendere all'ultimo punto + 1. Si salverà l'ultima posizione dell'iterazione e si avanza rapidamente alla successiva richiesta, chiamando iterator-> next() fino a raggiungere il prossimo oggetto da elaborare, che è $ lastPosition + 1. dobbiamo memorizzare l'iteratore e l'ultima posizione e prelevarli entrambi alla successiva richiesta, finché lastPosition è uguale al numero totale di elementi nell'iteratore.
Oppure, è possibile trasformare l'iteratore in una matrice alla prima esecuzione: $array = iterator_to_array($iterator);
e quindi utilizzare un approccio di riduzione dell'array. (Forse qualcun altro sa come ridurre un oggetto iteratore.) Con questo approccio si potrebbe memorizzare solo i dati, che diminuisce richiesta su richiesta fino a 0.
Il codice è testato. È solo una bozza veloce.
$starttime = time();
$endtime = $starttime + (5 * 60); // 5sec
$totalElements = count($array);
for($i = 0; $i <= $totalElements; $i++)
{
if(time() >= $endtime) {
break;
}
doStuffWith($array[$i]);
}
echo 'Processed ' . $i . ' elements in 5 seconds';
// exit condition is "totalElements to process = 0"
// greater 1 means there is more work to do
if(($totalElements - $i) >= 1) {
// chop off all the processed items from the inital array
// and build the array for the next processing request
$reduced_array = array_slice(array, $i);
// save the reduced array to cache, session, disk
store($reduced_array);
} else {
echo 'Done.';
}
// on the next request, load the array and resume the steps above...
Tutto sommato, questo è l'elaborazione in batch e può essere fatto in modo più efficiente da un lavoratore/lavoro-code, come:
fonte
2014-12-18 15:32:00
1. ripristinare il numero di articoli elaborati; se non è impostato, inizializzalo con zero; 2. inserire il ciclo, saltare il numero di articoli elaborati; 3. elaborare un articolo; 4. conta; 5. rompere il ciclo; 6. passare il valore alla richiesta successiva (utilizzando la sessione o la stringa di query). Risciacqua e ripeti. – axiac