Vannak esetek, amikor egy változó értékének megfelelően több lehetséges folytatási útvonalunk van. Másképp fogalmazva, egyfajta "forgalomirányító" szerkezetet kell igénybe vegyünk. Erre ott van az if .. else if .. else szerkezet, azonban előfordul, hogy sok lehetséges leágazásunk van. Ilyenkor szebb, átláthatóbb és kényelmesebb a switch szerkezetet használni. A logikája a következő: válasszunk (switch) esetágat a felsorolt lehetséges értékek (case) szerint (vagyis a case ágon levő mondat értéke TRUE). A szerkezete így néz ki:
switch (érték) {
case első_megfelelés:
első_esemény; break;
case második_megfelelés:
második_esemény; break;
default:
alapesemény; break;
}
Megjegyzés
Az esetágak (case) üresek is lehetnek: ebben az esetben az ellenőrzést a következő ágon folytatjuk. Nem szükséges alapesetet (default) létrehozni, ennek hiányában a switch eredmény nélkül ér véget. Tartsuk szem előtt, hogy a switch nem ellenőriz azonosságot!
Lássunk egy konkrét példát! Vizsgáljuk meg, hogy a kiinduló $honap string változóban található valamely hónap neve milyen évszakban található!
--------------------
<?php
$honap = 'február';
switch ($honap) {
case 'december':
case 'január':
case 'február':
echo "$honap - tél"; break;
case 'március':
case 'április':
case 'május':
echo "$honap - tavasz"; break;
case 'június':
case 'július':
case 'augusztus':
echo "$honap - nyár"; break;
case 'szeptember':
case 'október':
case 'november':
echo "$honap - ősz"; break;
default:
echo 'Érvényes hónapot adjon meg!'; break;
}
?>
--------------------
A fenti példában láthatjuk az üres leágazások logikáját és létjogosultságát, valamint egy alapszintű hibakezelést is becsempésztünk a default ágra: amennyiben nem hónapot adott meg, a programunk figyelmeztet rá.
A case ágak akár függvényeket is ki tudnak értékelni. Kicsit előreszaladva, a fenti példa így oldható meg tömbökkel és in_array() függvénnyel (az in_array() függvény azt vizsgálja, hogy egy érték benne van-e egy adott tömbben. A felépítése: bool in_array($érték, $tömb [, bool $azonossagi_vizsgalat = FALSE]) A visszatérő értéke logikai (IGAZ vagy HAMIS), a szögletes zárójelben levő rész elhagyható: ebben az esetben nincs típusazonossági vizsgálat.)
--------------------
<?php
$honap = 'szeptember';
$tel = array('december', 'január', 'február');
$tavasz = array('március', 'április', 'május');
$nyar = array('június', 'július', 'augusztus');
$osz = array('szeptember','október','november');
switch ($honap) {
case in_array($honap, $tel):
echo "$honap - tél"; break;
case in_array($honap, $tavasz):
echo "$honap - tavasz"; break;
case in_array($honap, $nyar):
echo "$honap - nyár"; break;
case in_array($honap, $osz):
echo "$honap - ősz"; break;
default:
echo "Érvényes hónapot adjon meg!"; break;
}
?>
--------------------
Az átirat az olvashatóság mellett tömörebb is lett, és amint láthatjuk, az eredmény ugyanaz. Melyik változatot válasszuk akkor? Erre is azt kell mondanunk, hogy azt, amelyik a projektünkbe jobban beleillik: mivel a második változat összesen öt változót hoz létre, picit memóriaigényesebb, mint az első, ahol csak egy változónk van, valamint a második változaton minden egyes leágazáson még külön függvényt kell meghívnunk ahelyett, hogy helyben végeznénk a műveletet, tehát processzorigényesebb is. (A mérések alapján (strace -c -Ttt), átlagolva az első változat 0.000016 másodpercig, míg a második 0.000036 másodpercig futott - 10.000 mérést végeztünk. Ez nem reprezentatív, de jól mutatja a leheletnyi különbséget a két megoldás között.)
-----------------------------------------------------------------------------------------------------
Feladatok
1. Egy csoportban tíz ember van: 3 szőke, 3 barna, 3 fekete és 1 vörös. A szőkék a kávét, a barnák a teát, a feketék a vizet, a vörös meg a bort szeretik. Ha mindegyiknek egyedi neve van, vizsgáljuk meg, hogy mit iszik egy tetszőlegesen kiválasztott egyén.
2. Írjunk egy programot, amely kiírja, hogy egy tetszőlegesen választott hónap hány napot tartalmaz. Tipp: csoportosítsunk!
3. A budapesti irányítószámok 1-gyel kezdődnek, és a 2. és 3. szám a kerületet jelöli. (Pl. 1064 - Budapest, VI. kerület) Ha tudjuk, hogy 23 kerület van, vizsgáljuk meg, hogy egy tetszőleges, 4 számjegyű irányítószám budapesti? Ha igen, írjuk ki a kerületet, ha nem, figyelmeztessük a felhasználót a hibáról!