Making decisions: if, else, switch and match

Run different code depending on conditions, and choose the right tool for each case.

  • Beginner
  • 4 min read
  • Updated 17 Oct 2026

What you will learn

  • Write if, elseif and else blocks
  • Predict which values PHP treats as false
  • Use early returns to avoid deep nesting
  • Map values with match and know how it differs from switch

Programs become useful when they react to data: show a discount to members, an error for invalid input, or a different greeting in the morning. Conditionals make that possible.

if, elseif and else

PHP
<?php

$hour = (int) date('G'); // 0 to 23

if ($hour < 12) {
    echo 'Good morning';
} elseif ($hour < 18) {
    echo 'Good afternoon';
} else {
    echo 'Good evening';
}

PHP checks each condition in order and runs the first block whose condition is true. The else block runs if none matched. Both elseif and else are optional.

Always use curly braces, even for one-line blocks. Code without braces is easy to break when someone adds a second line later.

Truthy and falsy values

A condition does not have to be a boolean. PHP converts the value, and these all count as false:

ValueType
falsebool
0 and -0int
0.0float
'' (empty string) and '0'string
[] (empty array)array
nullnull

Everything else is true, including 'false', ' ' (a space) and '0.0'.

PHP
<?php

$items = [];

if ($items) {
    echo 'You have items';
} else {
    echo 'Your basket is empty';
}

The string '0' is falsy. If a user can legitimately enter 0, such as a quantity or a score, check explicitly: if ($quantity !== '') rather than if ($quantity).

Combining conditions

PHP
<?php

$age = 16;
$hasConsent = true;

if ($age >= 18 || ($age >= 13 && $hasConsent)) {
    echo 'Account can be created';
}

Brackets make mixed && and || conditions readable, even where precedence would give the same result.

Avoid deep nesting with early returns

Nested if blocks quickly become hard to follow. Inside a function you can check failure cases first and return early:

PHP
<?php

function shippingCost(float $total, string $country): float
{
    if ($total <= 0) {
        return 0.0;
    }

    if ($country !== 'GB') {
        return 15.0;
    }

    return $total >= 50 ? 0.0 : 4.99;
}

echo shippingCost(60, 'GB'); // 0
echo shippingCost(20, 'GB'); // 4.99

Each rule is visible at a glance. You will learn functions properly in a later lesson.

switch

switch compares one value against several cases:

PHP
<?php

$day = 'sat';

switch ($day) {
    case 'sat':
    case 'sun':
        echo 'Weekend';
        break;
    case 'fri':
        echo 'Almost there';
        break;
    default:
        echo 'Weekday';
}

Without break, execution "falls through" into the next case. That is useful for grouping cases (sat and sun above) and a classic source of bugs when forgotten. switch also uses loose == comparison.

match: the modern alternative

PHP 8 added match, an expression that returns a value:

PHP
<?php

$status = 404;

$message = match ($status) {
    200, 201 => 'Success',
    301, 302 => 'Redirect',
    404 => 'Not found',
    500 => 'Server error',
    default => 'Unknown status',
};

echo $message; // Not found

Why match is usually better than switch:

  • It returns a value, so you assign the result directly.
  • It uses strict === comparison.
  • There is no fall-through and no break to forget.
  • If no arm matches and there is no default, it throws an UnhandledMatchError instead of silently doing nothing.

match (true) lets you match on conditions:

PHP
<?php

$score = 82;

$grade = match (true) {
    $score >= 90 => 'A',
    $score >= 75 => 'B',
    $score >= 60 => 'C',
    default => 'Needs work',
};

echo $grade; // B

Summary

  • if, elseif and else run the first matching block.
  • 0, '0', '', [], null and false are falsy; check explicitly when 0 is valid input.
  • Early returns keep logic flat and readable.
  • switch falls through without break and compares loosely.
  • Prefer match for mapping values: it is strict, returns a value and fails loudly.

Further reading