Web Analytics

PHP Switch Statements

Beginner~30 min read

When you need to compare a single value against many possible matches, the switch statement provides a cleaner alternative to multiple if-elseif chains. PHP 8 also introduces the powerful match expression for even more concise code.

Basic Switch Statement

The switch statement evaluates an expression once and compares it against multiple cases:

<?php
switch (expression) {
    case value1:
        // Code for value1
        break;
    case value2:
        // Code for value2
        break;
    default:
        // Code if no match
}
?>
Keyword Purpose
switch Starts the switch block with expression to evaluate
case Defines a value to compare against
break Exits the switch block (prevents fall-through)
default Executes when no case matches (optional)
Output
Click Run to execute your code

Switch vs If-Elseif

Compare the same logic written both ways:

<?php
$color = "red";

// Using if-elseif (verbose)
if ($color === "red") {
    echo "Stop!";
} elseif ($color === "yellow") {
    echo "Caution!";
} elseif ($color === "green") {
    echo "Go!";
} else {
    echo "Unknown color";
}

// Using switch (cleaner for many cases)
switch ($color) {
    case "red":
        echo "Stop!";
        break;
    case "yellow":
        echo "Caution!";
        break;
    case "green":
        echo "Go!";
        break;
    default:
        echo "Unknown color";
}
?>
When to use switch: Use switch when comparing one variable against 3 or more specific values. Use if-elseif for complex conditions, ranges, or when comparing different variables.

Fall-Through Behavior

Without break, execution "falls through" to the next case. This can be intentional:

<?php
$month = 2;

switch ($month) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        $days = 31;
        break;
    case 4:
    case 6:
    case 9:
    case 11:
        $days = 30;
        break;
    case 2:
        $days = 28;  // Simplified, ignoring leap years
        break;
    default:
        $days = 0;
}

echo "Month $month has $days days.";
?>
Caution: Forgetting break is a common bug! Always add break unless you intentionally want fall-through behavior. Add a comment when fall-through is intentional.

Switch with Strings

Switch works with any scalar type, including strings:

<?php
$action = strtolower($_GET['action'] ?? 'view');

switch ($action) {
    case 'create':
        echo "Creating new record...";
        break;
    case 'read':
    case 'view':
        echo "Displaying record...";
        break;
    case 'update':
    case 'edit':
        echo "Editing record...";
        break;
    case 'delete':
        echo "Deleting record...";
        break;
    default:
        echo "Unknown action: $action";
}
?>
Note: Switch uses loose comparison (==), not strict comparison. This means "0" will match 0. Use match (PHP 8+) for strict comparison.

Alternative Syntax

Like if statements, switch has an alternative syntax for templates:

<?php $page = "about"; ?>

<?php switch ($page): ?>
    <?php case "home": ?>
        <h1>Welcome Home</h1>
        <?php break; ?>
    <?php case "about": ?>
        <h1>About Us</h1>
        <?php break; ?>
    <?php case "contact": ?>
        <h1>Contact Us</h1>
        <?php break; ?>
    <?php default: ?>
        <h1>Page Not Found</h1>
<?php endswitch; ?>

PHP 8 Match Expression

PHP 8 introduced match, a more powerful and safer alternative to switch:

Feature switch match (PHP 8+)
Returns value No (statement) Yes (expression)
Comparison type Loose (==) Strict (===)
Requires break Yes No (implicit)
Fall-through Possible Not possible
No match handling Continues silently Throws UnhandledMatchError
Output
Click Run to execute your code

Match Syntax

Match is an expression that returns a value:

<?php
$role = "editor";

// Match returns a value directly
$permissions = match($role) {
    "admin" => ["create", "read", "update", "delete", "manage"],
    "editor" => ["create", "read", "update"],
    "viewer" => ["read"],
    default => []
};

print_r($permissions);

// Multiple values in one arm
$isWeekend = match($dayNumber) {
    1, 2, 3, 4, 5 => false,
    6, 7 => true,
    default => throw new InvalidArgumentException("Invalid day")
};
?>
Pro Tip: Prefer match over switch in PHP 8+ for:
  • Cleaner, more concise code
  • Type-safe strict comparisons
  • No accidental fall-through bugs
  • When you need to return a value

Common Mistakes

1. Forgetting break statements

<?php
$fruit = "apple";

// โŒ WRONG: Missing break causes fall-through!
switch ($fruit) {
    case "apple":
        echo "Red fruit\n";  // Executes
    case "banana":
        echo "Yellow fruit\n";  // Also executes!
    case "grape":
        echo "Purple fruit\n";  // Also executes!
}

// โœ… CORRECT: Add break to each case
switch ($fruit) {
    case "apple":
        echo "Red fruit\n";
        break;
    case "banana":
        echo "Yellow fruit\n";
        break;
    case "grape":
        echo "Purple fruit\n";
        break;
}
?>

2. Relying on loose comparison

<?php
$value = "0";

// โŒ WRONG: Loose comparison matches unexpectedly
switch ($value) {
    case 0:
        echo "Zero (integer)";  // This matches "0" string!
        break;
    case "0":
        echo "Zero (string)";  // Never reached
        break;
}

// โœ… CORRECT: Use match for strict comparison (PHP 8+)
$result = match($value) {
    0 => "Zero (integer)",
    "0" => "Zero (string)",  // This matches correctly
    default => "Something else"
};
?>

3. No default case

<?php
$status = "archived";

// โŒ WRONG: No handling for unexpected values
switch ($status) {
    case "active":
        processActive();
        break;
    case "pending":
        processPending();
        break;
}
// "archived" silently does nothing!

// โœ… CORRECT: Always include default
switch ($status) {
    case "active":
        processActive();
        break;
    case "pending":
        processPending();
        break;
    default:
        throw new Exception("Unknown status: $status");
}
?>

Exercise: HTTP Status Handler

Task: Create a function that returns an appropriate message and CSS class for HTTP status codes.

Requirements:

  • Handle status codes: 200, 201, 301, 400, 401, 403, 404, 500
  • Return an array with 'message' and 'class' keys
  • Group similar codes (e.g., 2xx = success, 4xx = error)
  • Handle unknown codes with a default
Show Solution
<?php
function getStatusInfo($code) {
    // Using match for PHP 8+
    return match($code) {
        200 => ['message' => 'OK', 'class' => 'success'],
        201 => ['message' => 'Created', 'class' => 'success'],
        301 => ['message' => 'Moved Permanently', 'class' => 'redirect'],
        400 => ['message' => 'Bad Request', 'class' => 'error'],
        401 => ['message' => 'Unauthorized', 'class' => 'error'],
        403 => ['message' => 'Forbidden', 'class' => 'error'],
        404 => ['message' => 'Not Found', 'class' => 'error'],
        500 => ['message' => 'Server Error', 'class' => 'error'],
        default => ['message' => 'Unknown Status', 'class' => 'unknown']
    };
}

// Test it
$codes = [200, 404, 500, 999];
foreach ($codes as $code) {
    $info = getStatusInfo($code);
    echo "$code: {$info['message']} ({$info['class']})\n";
}
?>

Summary

  • switch: Compare one value against multiple cases
  • case: Define each possible value to match
  • break: Required to prevent fall-through (unless intentional)
  • default: Handles unmatched values (always include it!)
  • Fall-through: Multiple cases can share the same code block
  • match (PHP 8+): Modern alternative with strict comparison and returns a value
  • Comparison: switch uses ==, match uses ===

What's Next?

Now that you can make decisions with if and switch, let's learn about While Loops - repeating code until a condition is no longer true!