Restart foreach loop if condition is satisfied on last iteration

109 views Asked by At

How do I restart a foreach loop when I reach the last index and some other condition?

The loop needs to run again, instead, it just stops.

foreach ($getUsers as $index => $user) {
    $userID = saveToDB($user, rand(1,1000));
    if($index == count($getUsers) && alreadyUsed($userID)) {
         reset($getUser);
         reset($index);
    }
}

This doesn't work.

3

There are 3 answers

0
MorganFreeFarm On BEST ANSWER

The reset() function in PHP is used to reset the internal pointer of an array to its first element, but it doesn't impact the control flow of a foreach loop, you could achieve desired behaviour, like this:

$continueLoop = true;

while ($continueLoop) {
    foreach ($getUsers as $index => $user) {
        $userID = saveToDB($user, rand(1,1000));

        if ($index == count($getUsers) - 1 && alreadyUsed($userID)) {
            // If you reach the last user and the userID is already used,
            // continue the outer while loop
            continue 2;
        }
    }

    // If the end of the foreach loop is reached without restarting,
    // break out of the while loop
    $continueLoop = false;
}
1
sinyorridak On
foreach ($getUsers as $index => $user) {
    $userID = saveToDB($user, rand(1,1000));
    if ($index == count($getUsers) - 1 && alreadyUsed($userID)) {
        continue;
    }
    // Code...
}

When the condition is met, the loop will skip the rest of the current iteration and start from the next iteration, thus restarting the loop.

Sorry google translate :)

0
mickmackusa On

I don't understand at all what saveToDB() and alreadyUsed() do, but you can re-visit the foreach() loop (which isn't affected by array pointers, so no resetting is needed) by using a post-test while loop.

do {
    foreach ($getUsers as $user) {
        $userID = saveToDB($user, rand(1, 1000));
    }
} while (isset($userID) && alreadyUsed($userID));

This way you don't need to use any clunky variables or any conditional controls in the loop body.

Because you only want to perform the check after the last iteration of the foreach() has had its chance to execute saveToDB(), you can verify that the foreach() loop has been entered (and therefore declared $userID) and then check if alreadyUsed() has returned a truthy result.

In other words, isset($userID) needs to be written in case $getUsers is empty.

I've even removed the $index variable because it is no longer needed.