Conditional Statements
Conditional statements let your code make decisions: run a block when a condition is true, choose between multiple branches, and map values to results. We’ll cover if/elseif/else, switch, and modern match in depth.
Truthiness Refresher
| Value | As boolean | Notes |
|---|---|---|
false | False | — |
0, 0.0 | False | Number zero |
"" (empty string), "0" | False | Be careful: "0" is falsey! |
[] (empty array) | False | — |
NULL | False | — |
| everything else | True | Non-empty strings, non-zero numbers, non-empty arrays, objects |
1) if / elseif / else
<?php
$score = 78;
if ($score >= 90) {
echo "Grade A";
} elseif ($score >= 75) {
echo "Grade B";
} else {
echo "Keep improving!";
}
?>
Guard Clauses (early returns)
Instead of deep nesting, exit early when a condition fails.
<?php
function divide($a, $b) {
if ($b === 0) {
return "Cannot divide by zero";
}
return $a / $b;
}
?>
Short-circuit patterns
<?php
// Execute only if condition is true
$isAdmin = true;
$isAdmin && print("Welcome, admin\n");
// Provide default if empty (Elvis), or if null (??)
$username = "";
$label = $username ?: "Guest";
$safe = $_GET['name'] ?? "Guest";
?>
Alternative syntax (great for templates)
Use colon blocks in views (no braces). Close with endif;, endforeach;, etc.
<?php $loggedIn = true; ?>
<ul>
<?php if ($loggedIn): ?>
<li>Dashboard</li>
<?php else: ?>
<li>Login</li>
<?php endif; ?>
</ul>
2) switch
switch compares loosely by default (like ==), and falls through unless you use break.
<?php
$role = "editor";
switch ($role) {
case "admin":
echo "Full access";
break;
case "editor":
case "author":
echo "Can edit content";
break;
default:
echo "Read-only";
}
?>
Multiple values: Stack
case lines (as above) to handle several inputs the same way.switch pitfalls
- Loose comparison can surprise:
switch("0")may matchcase 0. - For strictly-typed checks, prefer
match(PHP 8+). - Don’t forget
break(unless you want fallthrough intentionally).
3) match (PHP 8+)
match evaluates to a value, uses strict comparison (like ===), no fallthrough, and requires handling all possibilities (or a default). Excellent for mapping.
<?php
$status = 200;
$message = match ($status) {
200 => "OK",
404 => "Not Found",
500 => "Server Error",
default => "Unknown",
};
echo $message;
?>
match with conditions (boolean arms)
You can pre-compute a category and match that, or match on true and use boolean expressions in arms:
<?php
$score = 88;
$grade = match (true) {
$score >= 90 => "A",
$score >= 75 => "B",
$score >= 60 => "C",
default => "D",
};
echo $grade;
?>
Returning values & throwing in match
<?php
$ext = "jpg";
$mime = match ($ext) {
"jpg", "jpeg" => "image/jpeg",
"png" => "image/png",
default => throw new InvalidArgumentException("Unsupported ext"),
};
?>
Common Gotchas
| Gotcha | Explanation | Fix |
|---|---|---|
= vs == |
Assignment inside condition is usually a bug | Use === for comparison; enable warnings/static analysis |
| Loose comparison | "0" == false is true |
Prefer === / !== for safety |
| Empty string truthiness | "" and "0" are falsey |
Differentiate ?: vs ?? based on need |
| switch fallthrough | Missing break executes next case |
Add break or switch to match |
Real-World Examples
Role-based UI
<?php
$role = $_GET['role'] ?? 'guest';
$menu = match ($role) {
'admin' => ['Dashboard','Users','Settings'],
'editor' => ['Dashboard','Posts'],
default => ['Home','Login'],
};
foreach ($menu as $item) {
echo "$item\n";
}
?>
Validation flow (guard + detailed reasons)
<?php
function validateAge($age) {
if (!is_numeric($age)) {
return "Age must be numeric";
}
if ($age < 0) {
return "Age cannot be negative";
}
return "OK";
}
?>
Practice Tasks
- Read
$_GET['lang']and usematchto print a greeting foren,hi,es, withdefaultfallback. - Write a function
grade($score)usingmatch(true)that returnsA/B/C/D. - Refactor a nested
ifthat checks multiple invalid states into clear guard-clauses. - Demonstrate a
switchwith intentional fallthrough for related categories. - Show the difference between
$x = true or falseand$x = true || false(precedence!).
Next: Continue with Loops (for, while, do-while, foreach, break/continue, and practical patterns).