Statements: Switch

A switch statement typically consists of a controlling expression, some case labels, and optionally a default label. Based on the value of the controlling expression, execution passes to one of the case labels, the default label, or to the statement immediately following the switch statement. For example:

enum Bank: int {
  DEPOSIT = 1;
  WITHDRAWAL = 2;
  TRANSFER = 3;
}

function processTransaction(Transaction $t): void {
  $trType = ...;     // get the transaction type as an enum value
  switch ($trType) {

  case Bank::TRANSFER:
    // ...
    break;
  case Bank::DEPOSIT:
    // ...
    break;
  case Bank::WITHDRAWAL:
    // ...
    break;
  }
}

The switch has case labels for each of the possible value of enum Bank, where a case label is the keyword case followed by an expression, followed by :, followed by zero or more statements. Note that the so-called body of a case label need not be made a compound statement; the set of statements associated with a particular case label ends with a break statement or the closing brace (}) of the switch statement.

A default label is used as a catch-all. In the enumerated-type example above, assuming all possible values of type enum Bank have corresponding case labels, no default label is needed, as no other values can exist! However, that is not true when the switch controlling expression has type int. Here, we're unlikely to have case labels cover the complete range of int values, so a default label might be necessary. For example:

$v = 100;

switch ($v) {
  case 20:
    // ...
    break;
  case 10:
    // ...
    break;
  case 30:
    // ...
    break;
  default:
    // ...
    break;
}

A default label is the keyword default, followed by :, followed by zero or more statements. Note that the so-called body of a default label need not be made a compound statement; the set of statements associated with a particular default label ends with a break statement or the closing brace (}) of the switch statement.

If a switch contains more than one case label whose values compare equal to the controlling expression, the first in lexical order is considered the match.

An arbitrary number of statements can be associated with any case or default label. In the absence of a break statement at the end of a set of such statements, control drops through into any following case or default label. Thus, if all cases and the default end in break and there are no duplicate-valued case labels, the order of case and default labels is insignificant.

If no break statement is seen for a case or default before a subsequent case label, default label, or the switch-terminating } is encountered, an implementation might issue a warning. However, such a warning can be suppressed by placing a source line containing the special comment // FALLTHROUGH, at the end of that case or default statement group.

$v = 10;
switch ($v) {
  case 10:
    // ...
    // FALLTHROUGH
  case 30:
    // ...         // Handle 10 or 30
    break;
  default:
    // ...
    break;
}

Case-label values can be runtime expressions, and the types of sibling case-label values need not be the same.

Note switch uses == equality for comparing the value with the different cases.. See equality for more details.

$v = 30;
switch ($v) {
  case 30.0:  // <===== this case matches with 30
    // ...
    break;
  default:
    // ...
    break;
}
Was This Page Useful?
Thank You!
Thank You! If you'd like to share more feedback, please file an issue.