Alternative Syntax

JA JASWANT Updated 17 Oct 2026
7 min read ·Lesson 4 of 11
In this post

What Is the Alternative Syntax? In simple terms: PHP offers a second way to write control structures — if , foreach , for , while , and switch — that uses a colon ( : ) to open the block and a keyword

What Is the Alternative Syntax?

In simple terms: PHP offers a second way to write control structures — if, foreach, for, while, and switch — that uses a colon (:) to open the block and a keyword such as endif; or endforeach; to close it, instead of curly braces.

Technically: For if, while, for, foreach, and switch, the opening brace { can be replaced with : and the closing brace } with endif;, endwhile;, endfor;, endforeach;, or endswitch;. The behavior is identical; only the syntax differs.

Brace SyntaxAlternative Syntax
if (...) { ... }if (...): ... endif;
elseif (...) { ... }elseif (...): ...
else { ... }else: ...
foreach (...) { ... }foreach (...): ... endforeach;
for (...) { ... }for (...): ... endfor;
while (...) { ... }while (...): ... endwhile;
switch (...) { ... }switch (...): ... endswitch;

Why It Exists

In files that mix PHP and HTML, a closing brace on its own line says nothing about what it closes:

<?php } ?>
<?php } ?>
<?php } ?>

In a long template, matching these braces to their opening statements is difficult. The alternative syntax names each block's end:

<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>

That is why the alternative syntax is the standard for PHP templates, including WordPress themes and the plain-PHP view files of many frameworks.


if, elseif, else

Syntax

<?php if (condition): ?>
    ... HTML ...
<?php elseif (otherCondition): ?>
    ... HTML ...
<?php else: ?>
    ... HTML ...
<?php endif; ?>

Example

<?php $unread = 3; ?>
<?php if ($unread === 0): ?>
<p>No new messages.</p>
<?php elseif ($unread === 1): ?>
<p>You have 1 new message.</p>
<?php else: ?>
<p>You have <?= $unread ?> new messages.</p>
<?php endif; ?>

Output (HTML)

<p>You have 3 new messages.</p>

How It Works

  • Each condition line ends with : instead of {.
  • elseif and else also end with :.
  • endif; closes the whole structure.
  • Only the HTML of the matching branch is sent to the browser.

Important: In the alternative syntax, write elseif as one word. else if (...): causes a parse error, because else if is really an else containing a new if, which would need its own endif;.


foreach ... endforeach

<?php
$menu = [
    'Home' => '/',
    'Courses' => '/courses',
    'Contact' => '/contact',
];
$current = '/courses';
?>
<ul class="menu">
<?php foreach ($menu as $label => $url): ?>
    <li><a href="<?= $url ?>"<?= $url === $current ? ' class="active"' : '' ?>><?= $label ?></a></li>
<?php endforeach; ?>
</ul>

Output (HTML)

<ul class="menu">
    <li><a href="/">Home</a></li>
    <li><a href="/courses" class="active">Courses</a></li>
    <li><a href="/contact">Contact</a></li>
</ul>

The loop body is plain HTML with short echo tags. A ternary adds class="active" only to the current page's link.


for ... endfor

<?php $totalSteps = 3; ?>
<?php for ($step = 1; $step <= $totalSteps; $step++): ?>
<span class="step">Step <?= $step ?> of <?= $totalSteps ?></span>
<?php endfor; ?>

Output (HTML)

<span class="step">Step 1 of 3</span>
<span class="step">Step 2 of 3</span>
<span class="step">Step 3 of 3</span>

while ... endwhile

The alternative syntax works in pure PHP code as well, although braces are far more common there:

<?php
$countdown = 3;

while ($countdown > 0):
    echo "$countdown...\n";
    $countdown--;
endwhile;

echo "Go!\n";

Output

3...
2...
1...
Go!

In non-template code, coding standards generally recommend braces. Use the alternative syntax where it improves readability — mainly when switching between PHP and HTML.


switch ... endswitch

<?php $role = 'editor'; ?>
<nav>
<?php switch ($role):
    case 'admin': ?>
    <a href="/admin">Admin panel</a>
<?php break;
    case 'editor': ?>
    <a href="/posts">Manage posts</a>
<?php break;
    default: ?>
    <a href="/profile">My profile</a>
<?php endswitch; ?>
</nav>

Output (HTML)

<nav>
    <a href="/posts">Manage posts</a>
</nav>

The Whitespace Rule for switch

PHP does not allow any output — not even whitespace or a newline — between switch (...): and the first case. Writing them in separate PHP blocks with indentation in between causes a parse error:

<?php switch ($role): ?>
    <?php case 'admin': ?>    <!-- the spaces before this line are output -->

The safe pattern, shown in the example above, keeps switch (...): and the first case inside the same PHP block. Because of this quirk, if/elseif or a match expression that selects a value is often simpler than switch in templates.


Do Not Mix the Two Syntaxes in One Structure

A single control structure must use one syntax throughout:

<?php if ($isLoggedIn): ?>
    <p>Welcome!</p>
<?php else { ?>          <!-- parse error -->
    <p>Please log in.</p>
<?php } ?>

Different structures may use different syntaxes (for example, a braced if in the logic section and an alternative-syntax foreach in the template), but each one must be consistent from start to end.


Whitespace in Templates

PHP removes one newline directly after ?>. This is why lines that contain only a PHP control tag, such as <?php endif; ?>, do not leave blank lines in the output. Two consequences are worth knowing:

  • A line that ends with <?= $value ?> loses its newline, so the next line's content is joined to it. Ending such lines with HTML (for example </span>) keeps the line breaks.
  • Indentation before a <?php tag is output as text. It does not matter for HTML rendering, but it can affect whitespace-sensitive output such as plain-text emails.

HTML rendering ignores most whitespace differences, so this mainly affects how the generated source looks.


Practical Example: Product Listing Template

<?php
$products = [
    ['name' => 'Desk Lamp', 'price' => 1299, 'stock' => 4],
    ['name' => 'Notebook <A5>', 'price' => 60, 'stock' => 0],
];
?>
<?php if ($products === []): ?>
<p>No products found.</p>
<?php else: ?>
<ul class="products">
<?php foreach ($products as $product): ?>
    <li class="<?= $product['stock'] > 0 ? 'in-stock' : 'sold-out' ?>">
        <span class="name"><?= htmlspecialchars($product['name']) ?></span>
        <span class="price">₹<?= number_format($product['price']) ?></span>
<?php if ($product['stock'] === 0): ?>
        <span class="badge">Sold out</span>
<?php elseif ($product['stock'] < 5): ?>
        <span class="badge">Only <?= $product['stock'] ?> left</span>
<?php endif; ?>
    </li>
<?php endforeach; ?>
</ul>
<?php endif; ?>

Output (HTML)

<ul class="products">
    <li class="in-stock">
        <span class="name">Desk Lamp</span>
        <span class="price">₹1,299</span>
        <span class="badge">Only 4 left</span>
    </li>
    <li class="sold-out">
        <span class="name">Notebook <A5></span>
        <span class="price">₹60</span>
        <span class="badge">Sold out</span>
    </li>
</ul>

Step-by-Step Explanation

  1. Data first: the PHP block at the top prepares the data. In a real application, it would come from a database, and the template would contain only presentation.
  2. Empty state: if ($products === []): ... else: shows a message when there is nothing to list. Always handling the empty case avoids rendering an empty <ul>.
  3. Loop: foreach ... endforeach; repeats the <li> block for each product.
  4. Conditional class: a ternary inside <?= ?> chooses in-stock or sold-out for styling.
  5. Escaping: htmlspecialchars() converts <A5> into <A5>, so a product name can never break the HTML or inject a script.
  6. Badges: a nested if ... elseif ... endif; shows "Sold out" or a low-stock warning, and nothing for well-stocked items.
  7. Clean output: each line that contains only a control tag ends with ?>, so its newline is removed and no blank lines appear.

Every closing tag (endif;, endforeach;) tells the reader exactly which structure is ending, even in a much longer template.


Alternative Syntax and Template Engines

Template engines provide even more compact syntax built on the same idea, and they escape output automatically:

Plain PHP (alternative syntax)Blade (Laravel)Twig (Symfony)
<?php if ($x): ?>@if ($x){% if x %}
<?php endif; ?>@endif{% endif %}
<?php foreach ($items as $item): ?>@foreach ($items as $item){% for item in items %}
<?= htmlspecialchars($name) ?>{{ $name }}{{ name }}

Learning the alternative syntax makes these engines easy to understand, because they follow the same structure.


Common Mistakes

Writing else if: Instead of elseif:

Effect: Parse error.

Fix: Use elseif (...):.

Forgetting the Semicolon After endif, endforeach, …

Effect: Usually works when the closing ?> follows immediately (because ?> implies a semicolon), but fails in pure PHP code.

Fix: Always write endif;, endforeach;, and so on.

Mixing Braces and Alternative Syntax in One Structure

Effect: Parse error.

Fix: Use one syntax per structure.

Output Between switch and the First case

Effect: Parse error.

Fix: Put switch (...): and the first case in the same PHP block, or use if/elseif.

Forgetting to Escape Output in Templates

Effect: Broken HTML and XSS vulnerabilities.

Fix: Wrap every external value in htmlspecialchars() (or use a template engine that escapes automatically).


Best Practices

  • Use the alternative syntax in HTML templates; use braces in pure PHP logic.
  • Keep logic (queries, calculations) above or outside the template; keep templates to loops, conditions, and output.
  • Always handle the empty state of lists.
  • Escape every dynamic value with htmlspecialchars().
  • Use elseif as one word and end every structure with its matching end...; keyword.

Official reference: https://www.php.net/manual/en/control-structures.alternative-syntax.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
Ask about this post
AI Ask about this post

Ask questions about Alternative Syntax and get answers drawn from it.

Signed-in readers only.