skip to content

In a PHP template such as a restaurant menu, how does the colon-style alternative syntax (if: ... endif;) work, and what are its traps?

level: middleimportance: should knowfreq 32%

answer

  1. colon opens, endX; closes
  2. if, while, for, foreach, switch, declare
  3. elseif must be one word
  4. no mixing braces in one block
  5. nothing between switch: and first case

basics

~20 s

The opening brace becomes a colon and the closing brace an end keyword such as endif; or endforeach;, which keeps templates readable. Traps: write elseif, never mix braces and colons, and output nothing between switch: and its first case.

solid answer

~40 s

PHP offers an alternative syntax for `if`, `while`, `for`, `foreach`, `switch` and `declare`: the opening brace becomes a **colon** and the closing brace becomes `endif;`, `endwhile;`, `endfor;`, `endforeach;`, `endswitch;` or `enddeclare;`. In templates this pairs each end marker with its structure, so `<?php foreach ($dishes as $dish): ?> ... <?php endforeach; ?>` reads better than a lone `<?php } ?>`. HTML between the tags is output only when the branch runs. The traps: `else if` in two words is a **parse error** with colons (write `elseif`); **mixing** braces and colons in one block is not supported; any output, even whitespace, between `switch (...):` and the first `case` is a **parse error**; and each `?>` swallows one newline, which affects whitespace in the rendered page. `match` has no alternative form.

code

php · 9 lines
php
<?php $course = 'main'; ?>
<?php switch ($course):
case 'starter': ?>
    <h2>Starters</h2>
<?php break; ?>
<?php case 'main': ?>
    <h2>Mains</h2>
<?php break; ?>
<?php endswitch; ?>

go deeper

for a junior

Recall the colon form and the end keywords for if and foreach, and write a small loop in a template with them.

for a middle

Explain the traps: elseif as one word, no mixing with braces, nothing between switch: and the first case, and the swallowed newline after ?>.

for a senior

Keep templates to presentation: alternative syntax and <?= in views, logic in PHP classes, escaping on every printed value.

for a principal

Decide whether plain-PHP templates are enough or a template engine with auto-escaping is warranted, weighing escaping safety against another dependency.

## The syntax For six control structures PHP accepts a second form in which the braces are replaced by a colon and an end keyword: | Structure | Opening | Closing | |---|---|---| | `if` / `elseif` / `else` | `if (...):`, `elseif (...):`, `else:` | `endif;` | | `foreach` | `foreach (... as ...):` | `endforeach;` | | `for` | `for (...; ...; ...):` | `endfor;` | | `while` | `while (...):` | `endwhile;` | | `switch` | `switch (...):` | `endswitch;` | | `declare` | `declare(...):` | `enddeclare;` | `do-while` has no alternative form, and `match` is an expression, not a block, so it has none either. ## Why templates use it In a template, PHP blocks are small islands in HTML. With braces, the closing side is a bare `<?php } ?>`, and after three nested loops nobody knows which brace closes what. With the alternative syntax every closing tag names its structure. A restaurant menu: ```php <?php if ($dishes === []): ?> <p>The menu is being updated.</p> <?php else: ?> <ul class="menu"> <?php foreach ($dishes as $dish): ?> <li> <?= htmlspecialchars($dish['name']) ?> <?php if ($dish['vegetarian']): ?><span class="tag">V</span><?php endif; ?> <?= number_format($dish['price'], 2) ?> </li> <?php endforeach; ?> </ul> <?php endif; ?> ``` The HTML inside a branch is not echoed by PHP code; it is inline output that the engine **skips** when the condition is false and repeats on every loop iteration. ## The traps 1. **`else if` versus `elseif`.** With braces, `else if` and `elseif` behave the same. With colons, only `elseif` works; `else if (...):` is a parse error. 2. **No mixing.** The manual states that mixing syntaxes in the same control block is not supported. An `if (...):` closed by `}` fails to parse. 3. **Whitespace before the first `case`.** Any output, including whitespace, between `switch (...):` and the first `case` is a syntax error. An indented `<?php case 1: ?>` on the next line puts spaces there and fails; the fix is to put `switch` and the first `case` in one PHP block, or start the `case` line at column zero so only the swallowed newline sits between them. 4. **Swallowed newlines.** Each `?>` swallows the newline right after it. In HTML this rarely matters; in plain-text output, such as an email body built from a template, lines can join. 5. **Semicolons after end keywords.** `endif;` is a statement; inside a `<?php endif ?>` block the closing tag supplies the semicolon, so both `endif;` and `endif` before `?>` work. ## Keeping templates small The alternative syntax stays readable only if the template does little work: - Prepare data before rendering: group dishes by course, format prices and decide flags in PHP code, then pass plain arrays or objects to the template. - Nest at most two or three levels; a nested `foreach` over courses and then dishes is fine, but business rules inside the template are not. - Put one control structure per PHP block, so every `endforeach;` and `endif;` line is easy to match with its opener. - Indent the HTML, not the PHP tags, if whitespace in the output matters. ## Where it belongs - **Templates**: the alternative syntax plus `<?=` is the idiomatic way to write plain-PHP views. - **Class and library code**: braces. Coding standards such as PSR-12 describe control structures with braces, and mixing styles in logic code hurts readability. - **Escaping**: the syntax only controls flow. Every value printed into HTML still needs escaping, a separate security topic. An interview answer that shows a small template, names the end keywords and mentions the `elseif` and `switch` traps covers what is asked.

  • Why does `else if ($x):` fail in a template while `elseif ($x):` works?
    With braces, `else if` is parsed as `else` followed by a nested `if` statement, which behaves like `elseif`. With the colon syntax the nested `if` would need its own `endif;`, and the parser expects `elseif`, `else` or `endif` at that point, so the two-word form is a parse error. The manual says the one-word `elseif` becomes necessary with colons.
  • Why is an indented `<?php case 1: ?>` right after `<?php switch ($x): ?>` a parse error?
    The newline after `?>` is swallowed, but the indentation before `<?php case` is inline HTML, which is output. PHP forbids any output between `switch (...):` and the first `case`, so the parser reports unexpected inline HTML. Put the first `case` in the same PHP block as `switch`, or start that line at column zero.

saying these in an interview costs you the question

  • else if and elseif are interchangeable in the colon syntax too.
  • You can open with if (...): and close with a brace.
  • match also has an endmatch; alternative form.
  • HTML inside a false if: block is still sent, just hidden.
  • Whitespace between switch: and the first case is ignored.