tags:

views:

189

answers:

6

I'm refactoring some PHP code and discovered that certain nested combinations of

if () :

and

if () {

generate syntax errors. Not that I would normally mix the two, but I like to do frequent syntax checks as I'm writing code and I kept getting a syntax error because of this.

Example - generates syntax error:

if ( $test == 1 ) :
  if ( $test2 == 'a' ) {
    if ( $test3 == 'A' ) {
    } else {
    }
  }
else :
  echo 'test2';
endif;

Example - does NOT generate syntax error:

if ( $test == 1 ) :
  if ( $test2 == 'a' ) :
    if ( $test3 == 'A' ) :
    else :
    endif;
  endif;
else :
  echo 'test2';
endif;

Could someone please explain to me why the first block of code is generating an error?

+2  A: 

This is a wild guess since I am not familiar with the grammar of PHP. But here goes:

The problem is the second else. The parser can't see if this else is belonging to the first or the second if (counting from the beginning). In your second example there is an endif making the second if-block be terminated so there it can do the parse. Perhaps this is the famous 'dangling-else' problem in disguise?

jlouis
This sounds like the general problem, it looks like the interpreter is just confused by the else, though it really shouldn't be as it is still short 1 }
Unkwntech
+2  A: 

i don't know the exact reason why. here's a related PHP bug post in which a dev basically says, "just don't do it" :). i haven't poured through the PHP source code lately, but if i had to hazard a guess, it's due to not checking for alternative syntax while recursively going through if statements.

Owen
A: 

The only thing I can say here is that the code is completely unreadable. Avoid : like plague. Use familiar, C-style curly brace syntax.

The quality of the code is very much driven by its readability, so do make an effort to clean this up, you'll save yourself a bunch of surprising bugs.

Alex
The code above is just an example. And yep, I agree - readable code makes life much easier. However, regarding using curly braces I have to disagree - IMHO, code is much more readable when control structures end with descriptive statements lik endif, endfor and so on which necessitates the use of :
Bill
Yep, familiar is always a matter of opinion. Although I prefer brackets too :)
m0rb
+1  A: 

It works fine if you put a semicolon after the last curly-brace:

if ( $test == 1 ) :
  if ( $test2 == 'a' ) {
    if ( $test3 == 'A' ) {
    } else {
    }
  };
else :
  echo 'test2';
endif;
dmazzoni
+1  A: 

Indentation be damned, it's interpreting the first example as being an if using braces matched up with an else using the alternate syntax.

Consistency is the rule of thumb here and the interpretation is ambiguous to any reader anyway, so either put in the semicolon as suggested in the other answers, or better yet... clean up the code. That's horrible!

Allain Lalonde
A: 

Thanks for the answers everyone. As for those of you who pointed out that the code I supplied in my question was horrible, yes it is - it's an example! As I stated in the original question, I only ran across this issue while changing my control structures from using {} to more descriptive : and else/endif statements. I wasn't planning on trying to use mixed syntax like this - I just wanted to know why I was receiving syntax errors from code that looked like it should be valid.

Bill