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:02:57 +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-210885@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:
just take your code, remove any whitespace and look again at it
Previous Comments:
------------------------------------------------------------------------
[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... :'(
------------------------------------------------------------------------
[2017-08-30 15:57:34] peehaa@php.net
From the docs (http://php.net/manual/en/control-structures.alternative-syntax.php):
> Mixing syntaxes in the same control block is not supported.
------------------------------------------------------------------------
[2017-08-30 15:31:47] jcmarchi at gmail dot com
Description:
------------
When using Block Alternative Syntax for IF statement (if: elseif: else: endif;) a nested
"IF" will trigger a PHP EXCEPTION error saying: syntax error, unexpected ':' if
it exists immediately BEFORE the "else:" or "elseif".
Test script:
---------------
Example 1:
<?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;
?>
Example 2:
<?php
$foo = 'foo';
$bar = 'bar';
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;
?>
Both examples fail with the same error.
Expected result:
----------------
Test Scripts fail. So, this is not a result but a "workaround" for the interpreter to stop
failing.
It fixes the parsing error to add an extra semicolon AFTER the last semicolon (before the
"elseif:" or "else:") as shown below:
<?php
$foo = 'foo';
$bar = 'bar';
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;
?>
Or, for the Example 2 (nested traditional "if" with brackets), to add a semicolon AFTER
the last closing bracket:
<?php
$foo = 'foo';
$bar = 'bar';
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;
?>
Ultimately, an empty line with a semicolon in it also do the trick, but none are "PHP
standard" and create a huge trouble when debugging. Some people may even get mistaken with the
statements and do something foolish like this broken logic (which is validated by the PHP
interpreter, of course):
<?php
$foo = 'foo';
$bar = 'bar';
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;
?>
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75138&edit=1