1.2 · Conditions: if/else, switch, ternary

Level 1 · Language basics

1.2Conditions: if/else, switch, ternary

Goal: make your code take decisions with if/elseif/else, switch and the ternary (plus ?? and match), by building correct conditions — the foundation of all logic.
Estimated time: 10 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • if/elseif/else = the general case: varied conditions, ranges, logic (&& || !) — the most flexible structure.
  • switch/match = route on ONE variable: several exact values, more readable than a cascade — break mandatory in switch.
  • Ternary and ?? = short and precise: ternary to assign in one line, ?? for default values (null/absence only).

Running mini-case — Riad displays the right rate in Constantine

Riad must display a rate according to the visitor profile on his showcase site: student, professional, or other — with a default page if the parameter is missing. He first writes if ($profil) with a shaky cascade: the "0" profile (a legitimate code) is treated as missing because of falsy values. He fixes it by testing explicitly, uses a switch with break for the three profiles, a ternary for the "adult/minor" label of a legal notice, and ?? for the default page. Each visitor now sees the right rate.

Sequel to case 1.1 — Riad moves from storing data to decisions.

1. if/elseif/else & falsy

Conditions make decisions: if (condition) { … }, extended by else (otherwise) and elseif (else if). The condition evaluates to true/false — usually a comparison ($age >= 18) or a logical combination. Beware of "falsy" values (false, 0, empty string, '0', null, empty array = "false"): they can cause subtle bugs. Build conditions with === and logic (&& || !).

Riad replaces his if ($profil) with an explicit test: the "0" code is no longer confused with an absence — rates apply to the right visitor.

2. switch, ternary, ?? and match

switch compares ONE variable against several values (more readable than a cascade) — do not forget break (otherwise you "fall through" into the next case). The ternary is a short if/else that returns a value ($statut = $age >= 18 ? 'adult' : 'minor';). Modern PHP: ?? (null coalescing, for default values — triggers only on null/absence) and match (PHP 8+, strict switch that returns a value). In templates: alternative syntax if (…): … endif;.

Riad routes his three profiles with a switch (break everywhere), sets the default page with $_GET['page'] ?? 1, and will simplify it tomorrow into a strict match.

Common misinterpretation: "if ($x) is enough to test a value" or "?? and ?: are equivalent". No. if ($x) treats 0, '0', '' and null the same way (falsy): a legitimate "0" value is confused with an absence — test explicitly (isset, !== '', === 0). And ?? triggers only on null/absence, while ?: triggers on any falsy: for a default value that respects an entered 0, ?? is what you need.
Conditional structures Choose according to intent if / elseif / else Variedconditions, ranges, logicswitch / match Route on thevalues of one variableTernary / ?? Shortassignment, default value
Choose according to intent
Text version of the diagram (SEO / screen readers / translation): 1) Decide: Riad writes if/elseif/else for varied conditions (age, country) with strict comparisons. 2) Route: he passes the three profiles to switch (mandatory breaks) or to strict match that returns the rate. 3) Shorten: ternary for the one-line label, ?? for the default page (null/absence). Lesson: the structure that most clearly expresses intent — readability first.

The switch without break (never do this)

"I forgot a break, but that changes nothing, right?"
Verdict: yes it does — execution falls into the next case and the visitor pays the neighbour's rate.
"if ($code) is enough to check the promo code."
Verdict: the "0" code counts as missing — and the customer who was right leaves without a discount.

Moral: a forgotten break costs a rate, a fuzzy test costs a customer.

🔎 Concrete example — 🔎 Concrete example — The right tool for each case

Readability first, like Riad for his rates.

$statut = $age >= 18 ? 'adult' : 'minor'; // ternary
$page = $_GET['page'] ?? 1; // ??: default if missing
$prix = match($taille) { // match (PHP 8)
    'S' => 10,
    'M' => 15,
    'L' => 20,
    default => 0
};

Reading: each structure clearly expresses its intent: assign, default, routing that returns.

Lesson: ?? triggers only on null/absence (not on 0 or '') — precise for defaults.

Section vocabulary

if / elseif / else
Runs a block IF a condition is true; else (otherwise), elseif (else if, several conditions in cascade). The condition evaluates to true/false.

Simple example: The note-based mention written by Riad (if/elseif/else).

What it is not: a cascade of nested unreadable ternaries.

Reflex: varied conditions = if/elseif, one branch per case.

"falsy" values
Values considered "false" by PHP in a condition: false, 0, empty string, '0', null, empty array; the rest is "true".

Simple example: Riad's "0" profile code, wrongly treated as missing.

What it is not: believing any non-empty string is true (except '0').

Reflex: test explicitly: isset, !== '', === 0.

switch
Compares ONE variable against several values (case), more readable than an elseif cascade; break exits the switch (forgetting it falls through into the next case); default for other cases.

Simple example: The three rate profiles routed by Riad.

What it is not: a switch without break running two rates at once.

Reflex: one case = one break, always a default.

Ternary
Short if/else returning a value: condition ? valueIfTrue : valueIfFalse. Handy for short conditional assignments.

Simple example: Riad's $statut adult/minor in one line.

What it is not: three nested ternaries for the rates.

Reflex: simple and short = ternary; complex = if/else.

Null coalescing ?? / match
?? returns the left side if it exists and is not null, otherwise the right side (default values). match (PHP 8+) = modern switch, strict, that returns a value.

Simple example: Riad's $_GET['page'] ?? 1 and the sizes match.

What it is not: ?: for a default that wipes out the entered 0.

Reflex: default on absence = ??; routing that returns = match.

In practice — In practice — Making code take decisions

  1. Write an if/elseif/else condition (e.g. determine a mention from a grade); build the condition with comparisons (===, >=…) and logic (&&, ||).
  2. Use a switch to compare one variable against several values (do not forget `break`!) with a `default` case.
  3. Write a ternary for a short conditional assignment (`$statut = $age >= 18 ? 'adult' : 'minor';`).
  4. Test the `??` operator for a default value (e.g. fetch a missing parameter), and spot the alternative `if (...): ... endif;` syntax for templates.
You make your code take decisions with if/elseif/else, switch and the ternary (plus ?? and match), by building correct conditions — the foundation of all logic.

Ready-to-say script — explaining the structure choice (30 s)

"For these three profiles, I suggest a switch: we route a single variable on exact values, which is more readable than an elseif cascade. And for the default page, ?? is enough — it only triggers if the parameter is missing, without wiping out a legitimate 0."

Say in code review; show the if/switch/ternary/match/?? grid.

Copy-paste template — rates by profile (switch + ?? + ternary)

= 18) ? 'adult' : 'minor';
echo 'Rate: ' . $tarif . ' — ' . $mention;

Rates in Constantine

Like Riad: one switch per profile with break and default — adding a profile means adding a case, without touching the others.

Missing parameter

$_GET['page'] ?? 1 gives the default page only when missing — the explicit 0 of a pagination stays respected.

One-line label

A ternary for adult/minor: a simple assignment that fits on one readable line, with no if/else block.

Upgrading to match

In PHP 8+, convert the switch to match: strict comparison, returned value, no break to forget.

✓ Best practices

  • if/elseif for varied conditions; switch/match to route on one variable.
  • Ternary for a SIMPLE assignment; never nested (unreadable).
  • Use ?? for default values (precise on null/absence).

✗ Common pitfalls

  • Forgetting a break in a switch ("fall-through" into the next case).
  • Relying on if ($x) and hitting falsy values (0, '0', '').
  • Stacking nested ternaries (prefer a clear if/else).

Key takeaways

  • CONDITIONS make decisions: `if (condition) { ... }`, extended by `else` (otherwise) and `elseif` (else if). The condition evaluates to true/false (often a comparison).
  • Beware of "FALSY" values (false, 0, empty string, '0', null, empty array = "false"); build conditions with `===` and logic (&& || !).
  • SWITCH compares one variable against several values (more readable than a cascade) — do NOT FORGET `break` (otherwise you "fall through" into the next case). TERNARY = short if/else returning a value.
  • Modern PHP: `??` (null coalescing, for default values), `match` (PHP 8+, strict switch that returns a value). Alternative `if (...): ... endif;` syntax for HTML templates.

48h challenge — apply tomorrow

Take the template above: add a 4th profile (one case + break), replace an elseif cascade with a switch, and convert a simple assignment into a ternary. Check each profile locally. 20 minutes is enough.

Section exit checklist
  • I choose if/elseif, switch, ternary, match or ?? according to intent.
  • I never forget breaks and I explicitly test falsy values.
  • I wrote ?? for a default and a ternary for a short assignment.
Self-assessment 1-5: do my conditions distinguish absence from falsy value?does each structure clearly express its intent?

Frequently asked questions

When to use if/elseif, switch, ternary or match — how to pick the right structure?

if/elseif/else: the general case, for VARIED conditions (complex comparisons, logical combinations, ranges). switch: to compare ONE variable against several EXACT values — more readable than a cascade; note it compares with `==` (loose) and needs `break`. Ternary: for a SIMPLE if/else that RETURNS a value — never nested. match (PHP 8+): modern switch that RETURNS a value, compares STRICTLY, with no `break`. `??`: for DEFAULT VALUES. The guiding principle: pick the structure that most clearly expresses intent — readability first.

What are "falsy" values in PHP, and why can they cause bugs?

In a boolean context, PHP evaluates the "truth" of values. FALSY: `false`, `0` and `0.0`, `''`, `'0'` (the trap!), `null`, `[]`. The `'0'` trap: checking a field with `if ($_POST['champ'])` fails if the user entered "0". Be EXPLICIT: `isset($x)`, `$x !== ''`, `$x === 0` — and `??` for defaults, which triggers only on null/absence.

Check your understanding

Which value does PHP consider "falsy" (false) in a tricky way?

Additional resources (optional, to go further)

Level 1 examFresh, harder questions to test what you've learned