Menu

Оператор switch в PHP: case, break и проваливание

switch ($value) сравнивает одно значение со списком меток case и выполняет код от первого совпадения до break. Несколько case, проваливание, default, switch(true) и почему switch использует нестрогое сравнение ==.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

switch ($value) сравнивает одно значение со списком меток case и выполняет код под первой совпавшей меткой. Каждый case заканчивается на break; default обрабатывает всё, что ни с чем не совпало.

Задайте $day значения 'fri', 'sun' или 'wed' и запустите снова. Если default стоит последним, break ему не нужен.

Несколько case для одного блока

Чтобы выполнить один и тот же код для нескольких значений, поставьте метки case подряд без ничего между ними. Совпавшая метка продолжает выполнение в коде ниже.

В отличие от match, у switch нет синтаксиса через запятую case 'jpg', 'jpeg':. Метки подряд это единственный способ.

Проваливание: что бывает без break

Именно break останавливает switch. Без него PHP выполняет совпавший case и продолжает выполнять все case ниже, не глядя на их метки, пока не встретит break или конец.

Здесь проваливание задумано: каждый тариф получает свои возможности и всё из более дешёвых тарифов. Если пишете так намеренно, добавьте комментарий вроде // no break, чтобы следующий читатель его не "исправил". Если же не собирались, пропущенный break одна из самых частых ошибок в switch.

switch использует нестрогое сравнение (==)

Каждый case проверяется через ==, а не ===. Числовая строка совпадает с числом, null совпадает с false и "", а true совпадает с любым значением, которое считается истинным. Нажимайте на ячейки, чтобы сравнить два оператора.

switch сравнивает через ==, match через ===
Point at or tap a cell to read it as PHP.
$a == $b01"0""1"""nullfalsetrue"a""10""1e1"
0
1
"0"
"1"
""
null
false
true
"a"
"10"
"1e1"
Every cell computed by PHP 8.3.19.

Практическое следствие: строка "1" из формы попадает в case 1: без всякого преобразования, и часто это как раз то, что нужно. Но switch (true) с непустой строкой или null, встретивший case false:, могут выбрать неожиданный case.

Обратите внимание на строку с null: он не доходит до case false:, потому что null == 0 уже истинно, а case 0: стоит раньше. При нестрогом сравнении порядок case меняет результат. Начиная с PHP 8, 0 == "a" ложно (в PHP 7 было истинно), поэтому нечисловая строка больше не совпадает с case 0:. Если нужно ===, используйте выражение match, о нём в конце страницы.

switch(true) для диапазонов и условий

Меткой case может быть любое выражение. С switch (true) каждый case это условие, и побеждает первое, которое равно true.

Следите, чтобы каждый case был настоящим логическим значением. Из-за нестрогого сравнения case $name: совпадёт всякий раз, когда $name непустая строка.

switch внутри цикла: break и continue

Внутри цикла break в switch выходит только из switch, а не из цикла. Чтобы остановить цикл, используйте break 2. continue внутри switch ведёт себя как break, и PHP при компиляции предупреждает: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?. Пишите continue 2, чтобы перейти к следующей итерации цикла.

switch и match

В PHP 8 появился match, который закрывает большинство задач switch меньшим количеством кода. Он сравнивает через ===, возвращает значение, никогда не проваливается, допускает условия через запятую и выбрасывает UnhandledMatchError, когда ничего не совпало, так что забытый case не пройдёт молча.

Оставляйте switch, когда в case нужно несколько инструкций или когда проваливание и есть смысл, как в примере с тарифами. Для сопоставления значения с результатом match короче и безопаснее.

Часто задаваемые вопросы

Как использовать несколько case для одного блока в switch PHP?

Поставьте метки case подряд без кода между ними: case 'sat': case 'sun': echo 'weekend'; break;. Каждая метка проваливается в общий код. Синтаксиса case 'sat', 'sun': в switch нет; такая форма через запятую есть у match.

Использует ли switch в PHP строгое сравнение?

Нет. switch сравнивает через нестрогое ==, поэтому case '1': совпадает с целым 1, а case 0: с '0'. Для строгого сравнения === используйте выражение match или switch (true) с === внутри каждого case.

Что будет, если забыть break в switch PHP?

Выполнение провалится дальше: после совпавшего case PHP продолжит выполнять код всех case ниже, пока не встретит break, return или конец switch. Иногда это задумано, но обычно это ошибка.

Может ли switch в PHP проверять диапазоны вроде "больше чем"?

Да, через switch (true): каждый case содержит условие, например case $score >= 90:, и выполняется первое истинное. Выражение match (true) делает то же со строгим сравнением и возвращает значение.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ