You can put an if inside another if. This is called nesting.
<?php
$isLoggedIn = true;
$role = "editor";
if ($isLoggedIn) {
if ($role === "admin") {
echo "Open the admin panel";
} else {
echo "Open your dashboard";
}
} else {
echo "Please log in";
}
Open your dashboard
The inner if runs only when the outer condition is true.
Why too much nesting hurts
Each level of nesting is one more thing a reader must hold in their head. After three levels, code becomes hard to follow.
<?php
$user = ["active" => true, "verified" => true, "balance" => 500];
$price = 300;
if ($user["active"]) {
if ($user["verified"]) {
if ($user["balance"] >= $price) {
echo "Purchase allowed";
}
}
}
Purchase allowed
Fix 1: combine with &&
When the inner conditions have nothing else to do, join them.
<?php
$user = ["active" => true, "verified" => true, "balance" => 500];
$price = 300;
if ($user["active"] && $user["verified"] && $user["balance"] >= $price) {
echo "Purchase allowed";
}
Purchase allowed
Fix 2: guard clauses
In a function, reject bad cases first and return. The “good path” is left with no nesting at all.
<?php
function canPurchase(array $user, int $price): string
{
if (!$user["active"]) {
return "Account is not active";
}
if (!$user["verified"]) {
return "Please verify your email";
}
if ($user["balance"] < $price) {
return "Not enough balance";
}
return "Purchase allowed";
}
echo canPurchase(["active" => true, "verified" => false, "balance" => 500], 300);
Please verify your email
This version also tells the user why it failed. Combining everything into one && cannot do that.
Aim for two levels at most
if, stop and ask whether a function with early returns would be clearer.