Statements & Semicolons
A PHP script is a sequence of statements — individual instructions like assigning a variable, calling a function, or looping over an array. PHP needs a way to know where one statement ends and the next begins, and unlike languages that infer this from line breaks, PHP relies on an explicit marker: the semicolon ;. Nearly every parse error a beginner hits traces back to a missing, extra, or misplaced semicolon, so it's worth understanding the rule precisely rather than by trial and error.
Every statement ends with a semicolon
Semicolons terminate statements, not lines
<?php $firstName = 'Kwame'; $lastName = 'Nkrumah'; $fullName = $firstName . ' ' . $lastName; echo $fullName;
Note that this is per statement, not per line — you can put multiple statements on one physical line as long as each ends with its own semicolon, though doing so hurts readability and no real-world style guide recommends it.
Legal but discouraged
<?php $a = 1; $b = 2; $c = $a + $b; echo $c;
Constructs that don't need one after them
The rule isn't "every line needs a semicolon" — it's "every
simple statement needs one." Control structures like if,
foreach, while, and function/class definitions are themselves
block structures, and the block's closing brace } is what ends
them, not a semicolon.
No semicolon after a closing brace
<?php
function isEven(int $n): bool
{
return $n % 2 === 0;
}
if (isEven(4)) {
echo 'Even';
} else {
echo 'Odd';
}
// Note: no ";" after either closing "}" above.The closing ?> tag implies a semicolon
PHP's closing tag, ?>, automatically terminates the statement immediately before it — you're allowed to omit the final semicolon if a closing tag follows right after.
The closing tag makes the last semicolon optional
<?php echo 'Hello' ?> <p>Some HTML follows the PHP block.</p>
This shortcut is convenient in short embedded snippets but easy to misuse the moment you add another statement afterward and forget the semicolon that's now required between two statements rather than before a tag.
This breaks — the omitted semicolon was only safe before ?>
<?php $greeting = 'Hello' $name = 'world' ?> <!-- Parse error: syntax error, unexpected variable "$name" -->
"Unexpected end of file" — the usual causes
This error means the parser reached the end of the script while still expecting something to close — almost always a missing semicolon, brace, parenthesis, or bracket somewhere earlier. Because PHP reports the error at the end of the file rather than at the actual mistake, it's one of the more frustrating messages for newcomers.
A missing semicolon on a statement, which makes the parser fold the next line into the same statement until something breaks.
An unclosed
{for a function, class,if, or loop body — count your braces, or let your editor's bracket-matching do it.A string that was opened with a quote and never closed, silently swallowing the rest of the file as string content.
An unclosed
(in a function call or condition, especially inside a long chained expression.
A missing semicolon cascades into a confusing error
<?php
function calculateTotal(array $prices): float
{
$sum = array_sum($prices) // <-- missing semicolon here
return $sum * 1.08;
}
echo calculateTotal([10, 20, 30]);
// PHP Parse error: syntax error, unexpected token "return"PSR-12: omit the closing tag in pure-PHP files
For any file that contains only PHP code — a class file, a function library, anything without trailing HTML — the PSR-12 coding standard recommends omitting the closing ?> tag entirely. This isn't stylistic pedantry: a file that ends with ?> can have trailing whitespace or a newline after the tag, and if that file is ever included or required, that stray whitespace gets sent straight to the output buffer — which breaks things like sending HTTP headers or cookies after the include, because output has already started.
Idiomatic pure-PHP file (PSR-12 style)
<?php
declare(strict_types=1);
namespace App\Billing;
class InvoiceTotal
{
public function __construct(
private readonly float $subtotal,
private readonly float $taxRate,
) {
}
public function total(): float
{
return $this->subtotal * (1 + $this->taxRate);
}
}
// File simply ends here — no closing ?> tag.Every simple statement (assignment, function call,
return, etc.) must end in;.Block structures (
if, loops, function/class bodies) end with}, not a semicolon.The closing
?>tag implicitly terminates the statement right before it."Unexpected end of file" almost always means an unclosed brace, bracket, string, or a missing semicolon somewhere earlier in the file.
PSR-12 recommends omitting the closing
?>tag in files that contain only PHP.