note 121575 deleted from control-structures.alternative-syntax by salathe
| From: | salathe@php.net | Date: | Mon, 21 Sep 2020 14:36:22 +0000 |
| Subject: | note 121575 deleted from control-structures.alternative-syntax by salathe | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-215218@lists.php.net to get a copy of this message | ||
Note Submitter: Julio Marchi
----
Consider the following hypothetical PHP example:
<?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;
?>
Disconsider the dumb logic and focus on the elseif line. If you try it yourself you will get a PHP
EXCEPTION error saying: syntax error, unexpected ':' .
Now, you may think the fix is to have the sub-if enclosed in between { } instead of being a single
line statement, like this:
<?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;
?>
Wrong! The error remains. Exactly the same EXCEPTION as before...
Well, here is what I found: if you put a semicolon (;) AFTER the curly bracket (}) which resides
immediately before the elseif statement, then the error is gone! Try it:
<?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;
?>
Weird enough, if you go back to the first example and DOUBLE the semicolon immediately before the
elseif statement, it will also work:
<?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;
?>
But, it doesn't end there. You can also do this:
<?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;
?>
However, in this last example, the logic gets totally scrambled! The elseif will now belong to the
sub-if instead of the first if, and the rest of the logic will all behave as a "one single
statement" in response to the first if only. Very confusing and error prone (be careful).
The differences are very subtle and can deceive the eyes (especially while debugging). For this
reason, I strongly suggest the first example from this answer: when using IF-ELSEIF blocks (AKA
"Alternative Syntax"), if another IF is required inside it, enclose it in between {} and
don't forget to add a semicolon after the last }. Example:
<?php
if (isset($bar)):
if (isset($foo)) {
echo "Both are set.";
};
elseif (...):
?>
Maybe the truth is that someone screwed up in the language parsing process for those PHP Block
Alternative Statements or failed to document this very important detail!