A question about if else is easy to confuse

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$a = true;
if ($a) {
echo "true";
} else label: {
echo "false";
}
$a = true; if ($a) { echo "true"; } else label: { echo "false"; }
$a = true;
if ($a) {
  echo "true";
} else label: {
  echo "false";
}

First of all, the above code outputs true and false. If you know the reason, then you don’t need to read it further. If you don’t know, then the cause of this confusion may be because we will intuitively think:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
label : {
statement;
}
label : { statement; }
label : {
  statement;
}

It should be a whole, just like:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if ($a) {
} else switch($a) {
}
if ($a) { } else switch($a) { }
if ($a) {
} else switch($a) {
}

or:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if ($a) {
} else do {
} while (!$a);
if ($a) { } else do { } while (!$a);
if ($a) {
} else do {
} while (!$a);

Because in the syntax design of PHP, if else is essentially:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if_stmt:
if_stmt_without_else T_ELSE statement
if_stmt: if_stmt_without_else T_ELSE statement
if_stmt:
 if_stmt_without_else T_ELSE statement

In other words, all statements can be followed by else. If the condition is not established, the execution flow will jump to the statement after else, and while and switch can be reduced to statement. But the label is a bit special (it can be said to be a design counter-intuitive “flaw”), in zend_language_parser.y:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
statement:
...
| T_DO statement T_WHILE '(' expr ')' ';' {...}
| T_SWITCH '(' expr ')' switch_case_list {...}
| T_STRING ‘:’ { $$ = zend_ast_create(ZEND_AST_LABEL, $1); }
statement: ... | T_DO statement T_WHILE '(' expr ')' ';' {...} | T_SWITCH '(' expr ')' switch_case_list {...} | T_STRING ‘:’ { $$ = zend_ast_create(ZEND_AST_LABEL, $1); }
statement:
  ...
  | T_DO statement T_WHILE '(' expr ')' ';' {...}
  | T_SWITCH '(' expr ')' switch_case_list {...}
  | T_STRING ‘:’ { $$ = zend_ast_create(ZEND_AST_LABEL, $1); }

As you can see, do while and switch will combine their body to reduce to a statement, but the label is a bit different. “label:” itself reduces to a statement, which makes this look rather confusing. The emergence of the problem, he essentially becomes:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$a = true;
if ($a) {
echo "true";
} else {
label: ;
}
echo "false";
$a = true; if ($a) { echo "true"; } else { label: ; } echo "false";
$a = true;
if ($a) {
 echo "true";
} else {
 label: ;
}
echo "false";

One more thing at the end, I forgot what I saw there before, saying that there is no elseif in this world, and some are just else (if statements), which are essentially the same as this. That is, a statement can be followed by else.Make good use of this combination of switch, for, do while, etc., sometimes can make our code more streamlined.For example, if we want to traverse an array, when the length of the array is zero, we need to do something else. Many people might write:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (count($array)) {
for ($i = 0; $i < count($array); $i++) {
}
} else {
// Logic for empty array
}
if (count($array)) { for ($i = 0; $i < count($array); $i++) { } } else { // Logic for empty array }
if (count($array)) {
  for ($i = 0; $i < count($array); $i++) {
  }
} else {
  // Logic for empty array
}

But you can also write:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (count($array) == 0) {
// Logic for empty array
} else for ($i = 0; $i < count($array); $i++) {
}
if (count($array) == 0) { // Logic for empty array } else for ($i = 0; $i < count($array); $i++) { }
if (count($array) == 0) {
   // Logic for empty array
} else for ($i = 0; $i < count($array); $i++) {
}