Forum und email
switch

switch

Instrukcja switch jest podobna do serii instrukcji IF z warunkiem na to samo wyrażenie. W wielu przypadkach istnieje potrzeba porównania jednej zmiennej (lub wyrażenia) z wieloma różnymi wartościami i wykonania różnych fragmentów kodu, w zależności od wyniku porównania tej zmiennej z różnymi wartościami. Do tego właśnie służy instrukcja switch.

Poniżej znajdują się dwa przykłady wykonujące dokładnie to samo, przy czym jeden z nich wykorzystuje serię instrukcji if, zaś drugi używa instrukcji switch:

if ($i == 0) {
    print "i jest równe 0";
} elseif ($i == 1) {
    print "i jest równe 1";
} elseif ($i == 2) {
    print "i jest równe 2";
}

switch ($i) {
    case 0:
        print "i jest równe 0";
        break;
    case 1:
        print "i jest równe 1";
        break;
    case 2:
        print "i jest równe 2";
        break;
}

Ważne jest by zrozumieć, jak działa instrukcja switch, żeby uniknąć błędów. Instrukcja switch jest wykonywana linia po linii (dokładnie wyrażenie po wyrażeniu). Na początku żaden fragment kodu nie jest wykonywany. Dopiero kiedy zostaje odnalezione wyrażenie case, którego wartość odpowiada wyrażeniu przy instrukcji switch, PHP rozpoczyna wykonywanie kodu od miejsca, gdzie znajduje się ta instrukcja case. PHP wykonuje instrukcje aż do momentu kiedy blok switch się skończy, lub do momentu znalezienia instrukcji break. Jeśli nie napiszesz instrukcji break na końcu instrukcji w danym wyrażeniu case to PHP będzie wykonywać dalej instrukcje z następnego wyrażenia case. Na przykład:

switch ($i) {
    case 0:
        print "i jest równe 0";
    case 1:
        print "i jest równe 1";
    case 2:
        print "i jest równe 2";
}

W tym przypadku, jeśli $i jest równe 0, to PHP wykona wszystkie trzy instrukcje print. Jeśli natomiast będzie równe jeden - wtedy tylko dwie ostatnie. Zachowanie zgodne z oczekiwaniami będzie wtedy, kiedy $i będzie równe 2 - wtedy wykonane będzie tylko ostatnia instrukcja print. Trzeba zatem pamiętać o umieszczaniu na końcu instrukcji break, chyba że planuje się wykorzystać jakieś specjalne możliwości instrukcji switch, o czym dalej.

W instrukcji switch wartość wyrażenia jest obliczana tylko raz, a następnie jest porównywana z każdym z wyrażeń przy etykiecie case. Natomiast w instrukcji elseif wartość wyrażenia jest obliczana ponownie. Dlatego, jeśli twoje wyrażenie jest bardziej skomplikowane od zwykłego porównania, lub znajduje się w zwartej pętli (tight loop), switch może być szybszy.

Po etykiecie case mogą nie występować żadne instrukcje, co oznacza po prostu, że sterowanie zostaje przekazane do następnej etykiety case.

switch ($i) {
    case 0:
    case 1:
    case 2:
        print "i jest mniejsze od 3, ale nie jest ujemne";
        break;
    case 3:
        print "i jest równe 3";
}

Specjalną etykietą jest etykieta warunku domyślnego - default. Etykieta ta dotyczy sytuacji, w której wyrażenie nie pasowało do wartości przy innych etykietach typu case. W instrukcji switch ta etykieta powinna być ostatnia z listy. Na przykład:

switch ($i) {
    case 0:
        print "i jest równe 0";
        break;
    case 1:
        print "i jest równe 1";
        break;
    case 2:
        print "i jest równe 2";
        break;
    default:
        print "i jest różne od 0, 1 i 2";
}

Etykieta case może zawierać dowolną wartość typu prostego, czyli liczbę całkowitą, zmiennoprzecinkową lub łańcuch znaków. Tablice lub obiekty nie mogą być użyte, o ile nie zostaną przekształcone w jakiś typ prosty.

Instrukcja switch obsługuje też składnię alternatywną. Więcej informacji na ten temat w rozdziale Składnia alternatywna w strukturach kontrolnych.

switch ($i):
    case 0:
        print "i jest równe 0";
        break;
    case 1:
        print "i jest równe 1";
        break;
    case 2:
        print "i jest równe 2";
        break;
    default:
        print "i jest różne od 0, 1 i 2";
endswitch;