Control Flow
By the end of this lesson you'll make your PHP make decisions — branching with if , choosing between many options with switch and the safer PHP 8 match , and writing tidy one-liners with the ternary and template if: ... endif; syntax.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ if / elseif / else
An if statement runs a block of code only when its condition is true. A condition is any expression that's true or false — usually a comparison like $score >= 70 . Add elseif branches to test more conditions, and a final else as the catch-all. PHP checks them top to bottom and runs only the first block that's true, then skips the rest — so order matters. You can join conditions with && (both must be true) and || (either is enough).
Note that PHP spells it elseif as one word ( else if as two words also works). Because only the first true branch runs, the score 78 prints "Grade: C" and never even checks the lower branches.
2️⃣ switch / case / break / default
When you're comparing one value against a list of fixed options, a long if/elseif chain gets noisy. A switch reads better: you name the value once, then list each possible case . The crucial part is break — it tells PHP to stop once a case has run. Leave it out and PHP "falls through" into the next case and keeps going. default is the catch-all (like else ), and you can stack cases to share one block.
3️⃣ The PHP 8 match Expression
match (added in PHP 8) is a sharper switch. Three things make it nicer: it returns a value you can assign straight to a variable; it needs no break because it never falls through; and it compares with strict === , so the integer 200 won't accidentally match the string "200" . Each arm is value => result , arms are separated by commas, and one arm can list several values. Prefer match over switch for simple value-to-value mapping in PHP 8+.
4️⃣ Ternary ? : and Null-Coalescing ??
When a choice is small, a full if/else is overkill. The ternary operator packs it into one line that produces a value: condition ? ifTrue : ifFalse . Closely related is null coalescing ?? , which says "use the left value, or this fallback if the left is null or unset" — perfect for safe defaults like a guest name when no one is logged in. Keep ternaries to genuinely simple choices; nesting them quickly becomes unreadable.
5️⃣ Alternative if: ... endif; Syntax
PHP offers a second way to write control structures: drop the curly braces, put a colon after the condition, and close with an endif; keyword (there's also endswitch; , endwhile; , and so on). It behaves exactly like the brace version. Its purpose is readability in templates — when you weave PHP through chunks of HTML, a matching endif; is far easier to spot than a lonely '} buried in markup.
Because $loggedIn is true, only the first block's HTML is sent; the else markup is skipped entirely.
6️⃣ Your Turn — Fill in the Blanks
Time to practise. Each script below is almost complete — replace every ___ using the 👉 hint, then run it and check it against the Output panel.
Now a match . Fill in the missing result and the catch-all keyword so it returns the right label.
📋 Quick Reference — Control Flow
No code is filled in this time — just a brief and an outline. Write it yourself, run it on onecompiler.com/php or your own machine, then check your result against the expected output in the comments. This is exactly the decide-run-check loop you'll use on every real script.
Practice quiz
In an if / elseif / else chain, how many blocks run?
- Every block whose condition is true
- Always the else block
- Only the FIRST block whose condition is true
- All of them in order
Answer: Only the FIRST block whose condition is true. PHP runs only the first block whose condition is true, then skips the rest.
What keyword stops a switch from 'falling through' into the next case?
- break
- stop
- exit
- end
Answer: break. break ends a case; without it PHP keeps running into the following case.
Which comparison does the PHP 8 match expression use?
- Loose ==
- <=> spaceship
- It depends on the value
- Strict ===
Answer: Strict ===. match always compares with strict ===, so 200 never matches the string "200".
What happens if match has no matching arm and no default?
- It returns null
- It throws an UnhandledMatchError
- It returns false
- It runs the first arm
Answer: It throws an UnhandledMatchError. match throws an UnhandledMatchError rather than silently doing nothing.
Which is a key advantage of match over switch?
- It returns a value you can assign
- It needs more break statements
- It uses loose comparison
- It only works with strings
Answer: It returns a value you can assign. match returns a value, needs no break, and compares strictly.
What does the ternary ($age >= 18) ? "Adult" : "Minor" produce when $age is 20?
- "Minor"
- true
- "Adult"
- 20
Answer: "Adult". 20 >= 18 is true, so the ternary returns the value before the colon: "Adult".
What does $display = $username ?? "Guest" give when $username is null?
- null
- "Guest"
- An error
- false
Answer: "Guest". ?? falls back to "Guest" because $username is null.
How does PHP spell the keyword for an additional condition?
- else if only
- elif
- otherwise
- elseif (one word; else if also works)
Answer: elseif (one word; else if also works). PHP spells it elseif as one word, though 'else if' as two words also works.
What is the alternative if: ... endif; syntax mainly for?
- Faster execution
- Readability inside HTML templates
- Avoiding semicolons
- Defining functions
Answer: Readability inside HTML templates. It replaces braces with a colon and endif; making PHP-in-HTML templates easier to read.
Why can you stack cases like 'case 6: case 7:' in a switch?
- To run different code for each
- It is a syntax error
- So 6 OR 7 run the same shared block
- To compare strictly
Answer: So 6 OR 7 run the same shared block. Stacked cases share one block, so both values trigger the same code.