9

Why it won't work? Appears Parse error: syntax error, unexpected ':' ... on line 7

$a = 0; $b = 1; $c = 3; $d = 4;
if ($a == $b):
   if ($b == $c) {
       // something
   }
else:
   $c = $a;
endif;

But if i change it to (just added else statement):

$a = 0; $b = 1; $c = 3; $d = 4;
if ($a == $b):
   if ($b == $c) {
       // something
   } else {
       // something
   }
else:
   $c = $a;
endif;

It works fine.

Why is that? isn't it a PHP bug? Or there is a rule about if...else i should know?

Anyway, i'm using PHP 5.3.3 version.

user1301744
  • 113
  • 4
  • http://stackoverflow.com/questions/564130/difference-between-if-and-if-endif – Pheonix Mar 29 '12 at 20:15
  • 4
    Interesting - and a good illustration of why you probably shouldn't mix the templating style flow control statements with the regular braced ones. (or use the templating style _at all_ unless you're coding an HTML view... but that's opinion) – Michael Berkowski Mar 29 '12 at 20:15
  • Hmm that's interesting. Looks like the alternative else is being connected to the inner if. I wonder if you could wrap the inner if in parenthesis or something. – Gohn67 Mar 29 '12 at 20:16
  • @NullUserException Dangling else doesnt seem to be the case here. Even though the op mixed the syntax, each of the if else are grouped correctly, it will never be the case [if (if else else)] or [(if if else) else], it has to be [if (if else) else] – Churk Mar 29 '12 at 20:24
  • 2
    @itachi the issue might not have been voluntary, though, you should not be so eager to criticize... – Damien Pirsy Mar 29 '12 at 20:25
  • @Churk As I understand it, In the first example, the `else:` is being attached to the inner `if` and throwing an error because it uses the alternative syntax instead of the expected `{` – Mike B Mar 29 '12 at 20:26
  • @MikeB I miss read the question, I though the top works while the bottom one does not. So Dangling else is the issue. – Churk Mar 29 '12 at 20:29
  • @damien: i am not criticising. Its just a matter of opinion. Some people find it interesting, i feel it knit picking issues, like, solving a problem which doesn't exist. – itachi Mar 29 '12 at 20:30

4 Answers4

16

I am not sure if I would call this is a bug, but I believe you're having this issue because of a dangling else, in conjunction with your mixed if-else syntax:

if ($a == $b):            // 1
    if ($b == $c) {       // 2 
        // something      // 3
    }                     // 4
else:                     // 5 - this else
    $c = $a;              // 6
endif;                    // 7

Note how the else on line 5 is ambiguous: it could "belong" either to the first or second if statements.

You can easily remove that ambiguity and fix your syntax error by adding a semicolon after your nested if:

if ($a == $b):            // 1
    if ($b == $c) {       // 2 
        // something      // 3
    };                    // 4 - here
else:                     // 5 
    $c = $a;              // 6
endif;                    // 7

On another note, please don't use this syntax unless you want your fellow programmers to bludgeon you to death in your sleep.

NullUserException
  • 83,810
  • 28
  • 209
  • 234
1

As mentioned in comments on the PHP manual's control structure page the parser appears to not always assume that an if from one style should not be matched with an else using the other.

Troubadour
  • 13,334
  • 2
  • 38
  • 57
0

By PSD standards, always use brackets.

$a = 0;
$b = 1;
$c = 3;
$d = 4;
if ($a == $b) {
    if ($b == $c) {
        // something
    } else {
        $c = $a;
    }
}

Its more readable, safer and clear.

step
  • 2,254
  • 2
  • 23
  • 45
  • You appear to be making dozens of edits to question after running their codeblocks through an automated formatting tool. Please stop doing this, there is no objectively "right" way to format PHP, and people are free to post using whatever format they like. – user229044 Jun 15 '18 at 13:23
0

The colon form of the if/else can be ambiguous when dealing with nested ifs. In your example the else is being attached the the second if (as it should.) In order to avoid this you must explicitly let the interpreter know that that else is paired with the first if, either by adding an else to the second if (as you show in your second code block), or using {} to explicitly define the control flow.

In other words, you can use multiple forms of if statements. For example:

if (foo):
  //statements
else {
  //statements
}

Is perfectly valid. Although I would advise against mixing forms since it takes away from the readability.

John Sparwasser
  • 1,015
  • 13
  • 26