Edit report at https://bugs.php.net/bug.php?id=75138&edit=1
ID: 75138
Comment by: jcmarchi at gmail dot com
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:
@yohgaki, thank you for providing valuable insight to the (so far) useless discussion!
The parsing issue in the PHP case can be easily observed in the "double semicolon"
example. The question is: why, when adding an extra semicolon before the "else:" or
"elseif:" magically resolves the "nested IF" problem? After all, in PHP, blank
lines should not affect the logic, right? Well, in this case, IT DOES!
It is not exactly ambiguity problem as no more than one correct parse tree actually exist (only in
the eye of the blind ones). If an "IF" statement nested block begins with ":"
and ends when an "else:" or "elseif:" is found, the "nested IFs"
should all work or fail equivalently, but just the last "IF" fails (and it doesn't
have a ":" to create ambiguity).
It is crazy to see people who should be going to the PHP Source Code and look for answers (or
solutions), or even bring something factual to the table, discussing the quality of "code
samples". The only things that matter in those samples are the ";;" and
"};", which fixes the "nested IF" issue, and AFAIK such approach is not even
part of the PHP coding principle.
It is depressing, if not tragic!
Previous Comments:
------------------------------------------------------------------------
[2017-08-30 23:19:01] spam2 at rhsoft dot net
no, i didn't play with the samples on my smartphone BUT DID YOU read the link about
"dangling else"?
------------------------------------------------------------------------
[2017-08-30 23:15:36] jcmarchi at gmail dot com
If you are trying to (childishly) offend me, well... Sorry to disappoint you. Why? Because I agree
with you! Some "freedoms" while coding should be chopped out. However, while language
allows it, it should be (at least) bug-free.
What is unbelievable, however, is people that keep focusing on the "wrong wrongs" simply
to ignore the problem at hand. Those are the ones I DO fire (the ones that go to the extreme of
self-blindness simply to avoid accepting they are wrong).
I bet you didn't even play with the code examples... Or even created your own... Did you?
/me -- All hopes for the technology world are lost, forever!
------------------------------------------------------------------------
[2017-08-30 23:12:11] yohgaki@php.net
Searching "dangling else" would help to understand this issue. It's common issue for
languages/programs.
------------------------------------------------------------------------
[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;
------------------------------------------------------------------------
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