Bug #75138 [Nab]: Nested "IF" triggers Exception when it is before "else:" or "elseif:".

From: Date: Wed, 30 Aug 2017 23:12:11 +0000
Subject: Bug #75138 [Nab]: Nested "IF" triggers Exception when it is before "else:" or "elseif:".
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-210888@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=75138&edit=1 ID: 75138 Updated by: yohgaki@php.net Reported by: jcmarchi at gmail dot com Summary: Nested "IF" triggers Exception when it is before "else:" or "elseif:". Status: Not a bug Type: Bug Package: *Programming Data Structures Operating System: All PHP Version: Irrelevant Block user comment: N Private report: N New Comment: Searching "dangling else" would help to understand this issue. It's common issue for languages/programs. Previous Comments: ------------------------------------------------------------------------ [2017-08-30 22:58:40] spam2 at rhsoft dot net frankly, i consider to propose a RFC to disallow such coding styles at all and would fire anybody writing such code immediately the same for if($× === $y) do_something; without {} ------------------------------------------------------------------------ [2017-08-30 22:38:06] jcmarchi at gmail dot com OMG... Let me draw a picture!!!! [ IF (CONDITION): [ ANYTHING IN HERE SHOULD BE A NESTED BLOCK FOR THE "IF" CONDITION WHEN IT IS TRUE ] ELSEIF (ANOTHER CONDITION): [ ANYTHING IN HERE SHOULD BE A NESTED BLOCK FOR THE "ELSEIF:" CONDITION WHEN IT IS TRUE ] ELSE: [ ANYTHING IN HERE SHOULD BE A NESTED BLOCK FOR THE "ELSE:" CONDITION WHEN IT IS TRUE ] ] Now, based on the nested blocks above, it should NOT fail when you NEST "whatever" statement inside! Each nested block is initiated by the ":" and end when it reaches an "ELSEIF" or an "ELSE" (each one of those having its own nested blocks again after their own ":"), or an "ENDIF" (when the first "IF" ends). It said such code should NOT fail: [ IF (CONDITION): [ ANYTHING IN HERE SHOULD BE A NESTED BLOCK FOR THE "IF" CONDITION WHEN IT IS TRUE IF (ANOTHER CONDITION) [ DO THIS; ] <--- THIS SHOULD BE NESTED INTO THE SAME LINE "IF" ] ELSEIF (ANOTHER CONDITION): [ ANYTHING IN HERE SHOULD BE A NESTED BLOCK FOR THE "ELSEIF:" CONDITION WHEN IT IS TRUE ] ELSE: [ ANYTHING IN HERE SHOULD BE A NESTED BLOCK FOR THE "ELSE:" CONDITION WHEN IT IS TRUE ] ] Or, based on your comment, this following logic should run, but provide a wrong result (and it actually works as expected): $bar = 'bar'; $foo = 'foo'; if (isset($bar)): if (isset($foo)) echo "Both are set."; echo " It actually works."; elseif (isset($foo)): echo "Only 'foo' is set."; else: echo "Only 'bar' is set."; endif; The above code will return: "Both are set. It actually works.", while based on your "thinking" it should return blank. Also, just for thinking purposes, try this (it works): $bar = 'bar'; $foo = 'foo'; if (isset($bar)): echo "It actually works. "; { if (isset($foo)) echo "Both are set."; } elseif (isset($foo)): echo "Only 'foo' is set."; else: echo "Only 'bar' is set."; endif; Does not matter how you look at it, if a nested IF statement (any coding style) precedes an "else:" or an "elseif:" statement, a DOUBLE semicolon is required to make it work (or sub-enclosure it under curly brackets). I can't believe you cannot see it. More (simplified) examples: // FAIL: $bar = 'bar'; if (true): if ($bar == 'bar') echo "Got 'bar'."; else: echo "Didn't get 'bar'."; endif; // WORKS: $bar = 'bar'; if (true): if ($bar == 'bar') echo "Got 'bar'.";; else: echo "Didn't get 'bar'."; endif; // WORKS: $bar = 'bar'; if (true): { if ($bar == 'bar') echo "Got 'bar'."; } else: echo "Didn't get 'bar'."; endif; // FAIL: $bar = 'bar'; if (true): if ($bar == 'bar') { echo "Got 'bar'."; } else: echo "Didn't get 'bar'."; endif; // WORKS: $bar = 'bar'; if (true): if ($bar == 'bar') { echo "Got 'bar'."; }; else: echo "Didn't get 'bar'."; endif; ------------------------------------------------------------------------ [2017-08-30 22:02:56] spam2 at rhsoft dot net just take your code, remove any whitespace and look again at it ------------------------------------------------------------------------ [2017-08-30 21:25:00] jcmarchi at gmail dot com Sorry, but you are also missing the point... Try this: <?php $bar = 'bar'; $foo = 'foo'; if (isset($bar)): if (isset($foo)) echo "Both are set."; echo "Working now"; elseif (isset($foo)): echo "Only 'foo' is set."; else: echo "Only 'bar' is set."; endif; ?> Now, try this (also works): <?php $bar = 'bar'; $foo = 'foo'; if (isset($bar)): if (isset($foo)) echo "Both are set."; ; elseif (isset($foo)): echo "Only 'foo' is set."; else: echo "Only 'bar' is set."; endif; ?> Question is: WHY the semicolon after the last nested IF statement is needed ONLY when the last IF is immediately BEFORE an "else:" or "elseif:" statement? Or, better said: why it only fails when the immediate last command BEFORE an "else:" or "elseif:" is an IF statement without an extra (unnecessary, wrongly required) semicolon (;)? Answer: IT IS A BUG in the interpreter/parser! It is not related to "code style", or "indentation", or "coding rules", or "standards", or "language nuances", or "Solar eclipse", etc... It is related to a tested in uncountable scenarios (and real codes) where in all cases it fails exactly the same way (code example is just it: a code example). ------------------------------------------------------------------------ [2017-08-30 20:59:17] nikic@php.net The assessment of peehaa is correct. PHP is not a whitespace-sensitive language, so the way your code is actually interpreted is as follows: if (isset($bar)): if (isset($foo)) echo "Both are set."; elseif (isset($foo)): echo "Only 'foo' is set."; else: echo "Only 'bar' is set."; endif; This mixes both styles on the same if/elseif/else structure and is, as already noted, not permitted. Please see https://en.wikipedia.org/wiki/Dangling_else for more information about this ambiguity. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=75138 -- Edit this bug report at https://bugs.php.net/bug.php?id=75138&edit=1

« previous php.bugs (#210888) next »