简体   繁体   中英

double semicolon in dangling else in php

i have started learning php and i saw a piece of code in php documentations that was bug reported but in the report page said that was not a bug. the code is :

$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;

if we put the nested if code in curly braces again that error is happening.

if (isset($bar)) :
    if (isset($foo)) {  
           echo "Both are set.";
    }
elseif (isset($foo)) :
       echo "Only 'foo' is set.";
else :
       echo "No one is set.";
endif;

the above code raise an error unexpected ":" and the reason of report page said this it is not a bug it was the mixed structure used in above code and php does not allowed and i accepted that but what makes this code go wrong. but why if we add another semicolon at the end of nested if statement it works perfectly. or why if we add else statement at the end of nested if statement error will gone. something like this :

if (isset($bar)) :
    if (isset($foo)) {  
           echo "Both are set.";
    } else {
            echo "this is else";
    }
elseif (isset($foo)) :
       echo "Only 'foo' is set.";
else :
       echo "No one is set.";
endif;

i will appreciate if anyone help i know this mixed structure is really bad but understanding the problem will help to prevent another mistakes. thanks a lot;

The problem is that this:

if (cond):
    if (cond) stuff();
elseif (cond):
    stuff();
else:
    stuff();
endif;

is really an instance of the dangling-else problem - does the elseif belong to the "inner" or the "outer" if in an whitespace-insensitive language?

PHP chooses to parse it as this: 1

if (cond):
    if (cond)
        stuff();
    elseif (cond):
        stuff();
    else:
        stuff();
    endif;

which mixes the two syntaxes, which is " not supported ".

So one might be inclined to say that this is a bug (which is not the conclusion of the related bug report ) - the spec states:

An else clause is associated with the lexically nearest preceding if or elseif that is permitted by the syntax.

Assuming that this also applies to elseif clauses, then one might say that the parser should associate our elseif with our outer if , as nothing else is permitted.


The problem is mitigated by anything which causes the above parse not to be possible. To take the simplest example from that bug report:

if (cond):
    if (cond) stuff();
    ;                   // <<<<
elseif (cond):
    stuff();
else:
    stuff();
endif;

The extra semicolon means that the elseif can't be interpreted as part of the inner if / elseif / if chain.


1. In this particular code snippet, I'm pretending that whitespace is important.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM