aggregate1166877
aggregate1166877

Reputation: 3202

PHP `continue` not working as expected

The problem I'm having is that PHP isn't handling my continue correctly. My code is as follows:

$count = -1;
foreach ($lines as $item){
    $count++;

    if ($item == ""){
        continue;  // don't process empty items
    }
    if ($count > 0){
        echo '-not the first line-';
    }

    switch ($item){
        case "item1":
            echo "item 1 found";
        break;
    }
}

The if ($count > 0) part executes regardless of where the continue is placed before it, but the switch executes as expected.

If I remove the if ($count > 0) and place it inside the switch, it executes as expected:

    switch ($item){
        case "item1":
            if ($count > 0){
                echo '-not the first line-';  // executes as expected
            }
            echo "item 1 found";
        break;
    }

Is this normal? Thanks

Upvotes: 0

Views: 4211

Answers (2)

Berry Langerak
Berry Langerak

Reputation: 18859

The if ($count > 0) part executes regardless of where the continue is placed before it, but the switch executes as expected.

Your expectation is that it doesn't execute? You're setting $count to "-1", then increment it with $count++. In my book, $count would then be 0, which is not greater than 0, which means the if condition is true?

EDIT: based on the information I got from the comment, you're not using the contents of the first line, and you're using $count merely to keep track of the number of iterations done? If so; what's wrong with the following:

<?php

$lines = array(
    'first',
    'foo',
    'bar',
    'baz',
    'item1'
);

$first = array_shift( $lines ); // remove it if you don't use it?
$lines = array_filter( $lines ); // remove empty lines.
$count = 0; // set count to 0, although you could just count( $lines ) as well.

foreach ($lines as $item){
    $count ++;
    echo '-not the first line-'."\n";

    if( $item === 'item1' ) {
        echo "item 1 found\n";
    }
}

Upvotes: 2

Basti
Basti

Reputation: 4042

Your 2nd example will work for you even if you don't have the continue-block.

$count = -1;
foreach ($lines as $item){
    $count++;

    switch ($item){
        case "item1":
            if ($count > 0){
                echo '-not the first line-';  // executes as expected
            }
            echo "item 1 found";
        break;
    }
}

if your $item == "" it is obviously $item != "item1" so the only case will not be executed. in your example code that's equivalent to having a continue before. my guess is that your $item is not "" as you expect. try var_dump($item) it.

Edit1: local test

<pre><?php

$lines = array("", "", "John Doe", "", "2011", "", "", "item1");

$count = -1;
foreach ($lines as $item){
    $count++;

    if ($item == ""){
        echo "\t(skipping empty item)\n";
        continue;  // don't process empty items
    }
    if ($count > 0){
        echo "-not the first line-\n";
    }
    else
        echo $item." is the first line\n";

    switch ($item){
        case "item1":
            echo "item 1 found\n";
        break;
    }
}
?>

will output

    (skipping empty item)
    (skipping empty item)
-not the first line-
    (skipping empty item)
-not the first line-
    (skipping empty item)
    (skipping empty item)
-not the first line-
item 1 found

having

$lines = array("foobar", "", "John Doe", "", "2011", "", "", "item1");

will output

foobar is the first line
    (skipping empty item)
-not the first line-
    (skipping empty item)
-not the first line-
    (skipping empty item)
    (skipping empty item)
-not the first line-
item 1 found

move $count++; below the continue-statement, to make it work.

<pre><?php

$lines = array("", "", "John Doe", "", "2011", "", "", "item1");

$count = -1;
foreach ($lines as $item){

    if ($item == ""){
        echo "\t(skipping empty item)\n";
        continue;  // don't process empty items
    }
    $count++;
    if ($count > 0){
        echo "-not the first line-\n";
    }
    else
        echo $item." is the first line\n";

    switch ($item){
        case "item1":
            echo "item 1 found\n";
        break;
    }
}

?>

output

    (skipping empty item)
    (skipping empty item)
John Doe is the first line
    (skipping empty item)
-not the first line-
    (skipping empty item)
    (skipping empty item)
-not the first line-
item 1 found

Upvotes: 3

Related Questions