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 совпадает с любым значением, которое считается истинным. Нажимайте на ячейки, чтобы сравнить два оператора.
| $a == $b | 0 | 1 | "0" | "1" | "" | null | false | true | "a" | "10" | "1e1" |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | |||||||||||
| 1 | |||||||||||
| "0" | |||||||||||
| "1" | |||||||||||
| "" | |||||||||||
| null | |||||||||||
| false | |||||||||||
| true | |||||||||||
| "a" | |||||||||||
| "10" | |||||||||||
| "1e1" |
Практическое следствие: строка "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) делает то же со строгим сравнением и возвращает значение.