Skip to content
Theory · Conditions · lesson 6 of 8

switch

A condition often compares one variable with a long list of values: if the day is 6, it's "Saturday"; if it's 7, "Sunday"; otherwise, "workday". An elseif chain can handle that, but every condition would repeat $day ===. For this kind of choice, PHP has switch.

Picture a long corridor with doors. Each door has a number on it, and a doorman stands at the entrance. He looks at your ticket, finds the first door with a matching number and lets you in. He checks the number loosely: a ticket with a handwritten 7 is the same to him as a printed number 7.

Let's see switch in action:

PHP
<?php

$day = 3;
switch ($day) {
    case 6:
        echo 'Saturday', "\n";
        break;
    case 7:
        echo 'Sunday', "\n";
        break;
    default:
        echo 'workday', "\n"; // workday
}

Let's take it apart:

  • switch ($day) is the value that gets compared;
  • case 6: is a label, that is, an instruction "if the value equals 6, start here";
  • break; is the exit from switch, and the code after the closing brace runs next;
  • default: is the label for all other values, and it is optional.

In our example $day is 3. Neither case 6 nor case 7 matched, so PHP runs the lines after default and prints workday.

Loose comparison

switch compares the value with each label using ==, not ===. So a numeric string, say from a form, lands in a case with a number:

PHP
$input = '7';
switch ($input) {
    case 7:
        echo 'Sunday', "\n"; // Sunday
        break;
    default:
        echo 'unknown', "\n";
}

The string '7' matched the number 7 because '7' == 7 is true: == compares a numeric string as a number. A non-numeric string, however, will not match a number: in PHP 8 'abc' == 0 is false, and switch ('abc') does not land in case 0.

Falling through without break

The most surprising part of switch starts after a match. Once it finds a matching label, PHP runs every line in a row until the nearest break or the end of the switch. It does not check the following labels on the way and walks right through them. This behavior is called fall-through.

In our corridor it looks like this: once you walk through your door, you are in a room with a passage to the next one. You walk through the rooms one after another until someone says "stop"—break. Press "Next step" and watch $kind in the {main} frame: after case 6 PHP does not stop and appends weekend to the string as well.

Liveswitch without breakstep 1 of 9 · frames: 1

$day holds 6, the value that switch will compare with the labels.

Watch how $kind grows

This is where the corridor analogy stops working. In a real corridor, every door would check your ticket again. switch checks the labels only until the first match, and after that it walks right through, ignoring the numbers.

The rule is this: switch chooses which label to start from, and it stops only at a break or at the closing brace. Interviewers like to show a switch without break and ask what it prints. Walk through such a program the way the widget does: from the matching label, line by line, to the first break.

Several values in one case

Sometimes fall-through is what you want. When several values lead to the same result, their labels go one after another, with no lines between them:

PHP
$day = 7;
switch ($day) {
    case 6:
    case 7:
        echo 'weekend', "\n"; // weekend
        break;
    default:
        echo 'workday', "\n";
}

$day is 7, so PHP starts at the label case 7 and prints weekend. With 6 it would start at the empty label case 6, fall through into case 7 and reach the same line.

Common mistake

A branch is missing its break:

PHP
$role = 'admin';
switch ($role) {
    case 'admin':
        echo 'full access', "\n"; // ✗
    case 'guest':
        echo 'read only', "\n";
        break;
}

The program prints both full access and read only: there is no break after the first branch, so PHP falls through into case 'guest'. There is no error message, because to PHP this is valid code. The fix is a break; at the end of every branch except the ones that fall through on purpose.

Key points

  • switch compares the value with each case label using ==, so the string '7' lands in case 7.
  • After the matching label, PHP runs every line in a row until break, without checking the following labels.
  • default runs when no label matched.
  • A forgotten break causes no error: the program silently runs extra lines.