Bug #75138 [Com]: Nested "IF" triggers Exception when it is before "else:" or "elseif:".
| From: | spam2 at rhsoft dot net | Date: | Wed, 30 Aug 2017 22:58:41 +0000 |
| Subject: | Bug #75138 [Com]: 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-210887@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
Comment by: spam2 at rhsoft dot 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:
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 {}
Previous Comments:
------------------------------------------------------------------------
[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.
------------------------------------------------------------------------
[2017-08-30 20:47:27] jcmarchi at gmail dot com
@peehaa. Did you actually READ the bug report????? I don't think so...
IT IS A BUG! In the interpreter...
The "mixed syntax" is merely an example to display the wrong requirement of the last
";" (and it WORKS). The reported bug fails regardless of the "mixed syntax".
Check code examples before saying anything!
BTW, it is outrageous the lack of understanding some people has when RTFM! The statement
"Mixing syntaxes in the same control block is not supported" refers to the SAME LEVEL
BLOCK, not to NESTED BLOCKS (the reason why IT WORKS).
-- /me losing faith in the Technology world... :'(
------------------------------------------------------------------------
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