PHP跟踪最后的x次迭代

I have four variables: $one_flag, $two_flag, $three_flag, and $four_flag. I'm using them as flags inside a for loop because I want to keep track of the last four iterations.

$one_flag = 1;
$two_flag = 0;
$three_flag = 0;
$four_flag = 0;

$a = array(1, 2, 3, 17, 27, 44, 45, 47, 49);

foreach ($a as $v) {
    if ($one_flag){
        $first_v = $v;
        $one_flag = 0;
        $two_flag = 1;
    }
    if ($two_flag){
        $second_v = $v;
        $two_flag = 0;
        $three_flag = 1;
    }
    if ($three_flag){
        $third_v = $v;
        $three_flag = 0;
        $four_flag = 1;
    }
    if ($four_flag){
        $fourth_v = $v;
        $four_flag = 0;
        $first_flag = 1;
    }
    if ($v == 45){
        # tricky part
        print "The last three v's were: " . $first_v . ", " . $second_v . ", " . $third_v . "
";
    }
}

Right now it prints The last three v's were 1, 1, 1 but it's supposed to print The last three v's were 45, 44, 27. Also, the problem with the code above is I need to know which flag is equal to 1 (what flag we're currently on) so that I can print the correct statement.

For example, when $v == 45, $first_v is suppose to equal to 27; $second_v is suppose to equal to 44; $fourth_v is suppose to equal to 17; and third_v is suppose equal to 45. I'd need to know $three_flag is equal to 1 in order to print out "The last three were $second_flag, $first_flag, $fourth_flag" in that order.

How can I get my loop to work? How do I keep track of the last four iterations?

EDIT: I misspoke. I actually want to print The last three v's were 44, 27, 17

I suppose that this is a minimal example and that the real program is more complex. Otherwise, you could just get the length of the array and retrieve the last 3 elements based on it.

I'd change the approach as follow:

$f1 = -1;  // Last value read
$f2 = -1;  // second to last value
$f3 = -1;


$a = array(1, 2, 3, 17, 27, 44, 45, 47, 49);

foreach ($a as $v) {
    $f3 = $f2;
    $f2 = $f1;
    $f1 = $v;
    if ($v == 45){
        # tricky part
        print "The last three v's were: " . $f1 . ", " . $f2 . ", " . $f3 . "
";
    }
}

I'm using -1 as an indicator that nothing was assigned to the variable. You should adapt this to your context if needed.

It'd help to know the problem you're trying to solve, but off-hand I'd use a circular array to keep track of the last four. (Edited per your revision):

$a = array(1, 2, 3, 17, 27, 44, 45, 47, 49);
$previous = array ();
$pCounter = 0;

foreach ($a as $i => $v) {
    if (45 === $v) {
        print_r(array_reverse($previous));
    }

    // track the last three using a circular array
    $previous[$pCounter] = $v;
    $pCounter = ($pCounter + 1) % 3;
}

Results in:

Array
(
    [0] => 44
    [1] => 27
    [2] => 17
)

Try it online.

The problem lies in your if-statements.

//loop sets $v = 1
//this one is true due to initial parameters, execute
if ($one_flag){
    $first_v = $v; //$first_v = 1
    $one_flag = 0;
    $two_flag = 1; //$two_flag is now TRUE!!!
}
//$two_flag is true, execute immediately!
if ($two_flag){
    $second_v = $v; //$second_v = 1
    $two_flag = 0;
    $three_flag = 1;
}

Although in my reading, that should cause the print to give The last three v's were 45, 45, 45. If you want to keep doing it like this, you will need to use else if.

$a = array(1, 2, 3, 17, 27, 44, 45, 47, 49);

$track = array();

$num = 3;

foreach ($a as $v){

    $track[] = $v;

    if (count($track) > $num){
        $track = array_slice($track, 1);
    }

    if ($v == 45){
        print_r(array_reverse($track));
    }

}

result

Array
(
    [0] => 45
    [1] => 44
    [2] => 27
)

instead of if use elseif, it will serve your purpose, and change the variable name $first_flag to $one_flag.

    $one_flag = 1;
    $two_flag = 0;
    $three_flag = 0;
    $four_flag = 0;
    $probe_counter = 1;
     $first_v=0;
     $second_v=0;
     $third_v=0;$fourth_v=0;

    $a = array(1, 2, 3, 17, 27, 44, 45, 47, 49);

    foreach ($a as $key => $val) {
        if ($one_flag){
            $first_v = $val;
            $one_flag = 0;
            $two_flag = 1;
        }
        elseif ($two_flag){
            $second_v = $val;
            $two_flag = 0;
            $three_flag = 1;
        }
        elseif ($three_flag){
            $third_v = $val;
            $three_flag = 0;
            $four_flag = 1;
        }
        elseif ($four_flag){
            $fourth_v = $val;
            $four_flag = 0;
            $one_flag = 1;
        }

        if ($val == 45){
            # tricky part
            echo "The last three v's were: " . $first_v . ", " . $second_v . ", " . $third_v . "<br>";
        }
    }