PHP: instrukcje warunkowe i pętle, w tym foreach

INF.03 · teoria
autor: redakcja · 08.09.2026
Instrukcje warunkowe if, elseif, switch i match oraz pętle for, while, do...while i foreach w PHP: kiedy sprawdzany jest warunek, ile obrotów wykona pętla, po co są break i continue oraz jak pętla generuje listę i tabelę HTML. Lekcja 12.3 kursu INF.03.

[ INF.03: PYTANIA Z TEGO DZIAŁU ]

In­struk­cja ste­ru­ją­ca to kon­struk­cja języka, która de­cy­du­je, CZY i ILE RAZY wykona się frag­ment kodu: wa­ru­nek wy­bie­ra jedną z dróg, pętla po­wta­rza ten sam blok. Bez nich skrypt PHP idzie od góry do dołu i za każdym razem robi to samo. W części pi­sem­nej wra­ca­ją py­ta­nia z ramką kodu („ile ite­ra­cji zre­ali­zu­je przed­sta­wio­na pętla", „jaki ciąg liczb wy­pi­sze pętla", „jaką war­tość przyj­mie zmien­na po za­koń­cze­niu pętli", „która pętla wykona się co naj­mniej raz", „do czego służy break"). W za­da­niu prak­tycz­nym pętla while prze­cho­dzi po wier­szach za­py­ta­nia i ge­ne­ru­je z nich <li> albo <tr>, a if spraw­dza, czy for­mu­larz został już wy­sła­ny.

Wa­ru­nek: if, else, elseif

if (JEŻELI) to in­struk­cja wy­ko­nu­ją­ca blok w na­wia­sach klam­ro­wych tylko wtedy, gdy wa­ru­nek w na­wia­sach okrą­głych jest praw­dzi­wy. else (W PRZECIWNYM RAZIE) do­kła­da drugą drogę, na którą skrypt wcho­dzi przy wa­run­ku nie­speł­nio­nym, a elseif (A JEŻELI) wsta­wia między nie ko­lej­ne py­ta­nie. Wa­run­ki elseif spraw­dza­ne są po kolei, od góry: pierw­szy praw­dzi­wy wy­gry­wa, reszta zo­sta­je po­mi­nię­ta.
<?php $kwota = 250; if ($kwota >= 500) { $rabat = 10; } elseif ($kwota >= 200) { $rabat = 5; } else { $rabat = 0; } echo "Rabat: $rabat procent";
Wynik: Rabat: 5 procent. Kwota 250 nie prze­szła pierw­sze­go wa­run­ku, prze­szła drugi, więc else nic już nie robi. Zapis else if z od­stę­pem znaczy to samo co elseif, poza skład­nią al­ter­na­tyw­ną z dwu­krop­kiem, gdzie działa wy­łącz­nie elseif.
Wa­ru­nek zło­żo­ny łączy kilka po­rów­nań ope­ra­to­ra­mi lo­gicz­ny­mi: && (I) wymaga obu części, || (LUB) wy­star­czy jedna, ! (NIE) od­wra­ca wynik. Ope­ra­tor && łączy moc­niej niż ||, więc grupy trzeba za­my­kać w na­wia­sach.
<?php $ulica = "Bratkowa"; $numer = 12; if (($ulica == "Bratkowa" || $ulica == "Nasturcjowa") && $numer % 2 == 0) { echo "Adres pasuje"; }
Wynik: Adres pasuje. Bez na­wia­su wokół dwóch nazw ulic wa­ru­nek spraw­dzał­by co innego: pierw­szą ulicę sa­mo­dziel­nie albo drugą z pa­rzy­stym nu­me­rem.
Skró­tem dla naj­prost­sze­go wyboru jest ope­ra­tor trój­ar­gu­men­to­wy: wa­ru­nek, znak za­py­ta­nia, war­tość dla prawdy, dwu­kro­pek, war­tość dla fałszu.
<?php $kwota = 250; $rabat = $kwota >= 200 ? 5 : 0; echo $rabat;
Wynik: 5.
Pu­łap­ka: = przy­pi­su­je war­tość, == po­rów­nu­je war­to­ści, a === po­rów­nu­je war­tość i typ. Wa­ru­nek if ($a = 5) jest zawsze praw­dzi­wy, bo naj­pierw przy­pi­su­je 5, a potem oddaje tę piątkę jako wynik.

switch, case i match

switch (PRZEŁĄCZ) to in­struk­cja wyboru, która po­rów­nu­je JEDNĄ war­tość z listą przy­pad­ków case (PRZYPADEK) i wy­ko­nu­je kod od pierw­sze­go pa­su­ją­ce­go. Za­stę­pu­je długi łań­cuch elseif o wciąż tej samej zmien­nej. break kończy całą in­struk­cję, a default (DOMYŚLNY) łapie to, co nie pa­so­wa­ło do żad­ne­go przy­pad­ku.
<?php $dzien = 3; switch ($dzien) { case 1: echo "Poniedziałek"; break; case 6: case 7: echo "Weekend"; break; default: echo "Dzień roboczy"; }
Wynik: Dzień roboczy. Dwa przy­pad­ki jeden pod drugim bez break to zabieg celowy: 6 i 7 pro­wa­dzą do tego samego kodu. Za­po­mnia­ny break w środku bloku daje prze­lot, czyli wy­ko­na­nie także ko­lej­nych przy­pad­ków, bez spraw­dza­nia ich war­to­ści.
<?php $ocena = 5; switch ($ocena) { case 5: echo "bardzo dobry "; case 4: echo "dobry "; default: echo "koniec"; }
Wynik: bardzo dobry dobry koniec, choć ocena była tylko jedna. Obo­wiąz­ko­wa jest sama kon­struk­cja switch z wy­ra­że­niem w na­wia­sie: ani default, ani break po każdym przy­pad­ku, ani dwa przy­pad­ki nie są wy­ma­ga­ne.
match z PHP 8 robi to samo krócej: po­rów­nu­je ope­ra­to­rem ===, więc war­tość i typ muszą się zga­dzać, nie po­trze­bu­je break, zwraca war­tość za­miast wy­pi­sy­wać, a gdy nic nie pasuje i nie ma default, zgła­sza błąd.
<?php $dzien = 7; $nazwa = match ($dzien) { 6, 7 => "weekend", default => "dzień roboczy", }; echo $nazwa;
Wynik: weekend.

Pętle: for, while i do...while

Pętla to in­struk­cja po­wta­rza­ją­ca ten sam blok kodu, dopóki jej wa­ru­nek jest praw­dzi­wy. Jedno wy­ko­na­nie bloku to obrót, ina­czej ite­ra­cja, i to jego liczby do­ty­czy więk­szość pytań.
for (DLA) trzyma w na­wia­sie trzy części roz­dzie­lo­ne śred­ni­ka­mi: po­cząt­ko­wą war­tość licz­ni­ka, wa­ru­nek trwa­nia pętli i krok wy­ko­ny­wa­ny po każdym ob­ro­cie. Nadaje się tam, gdzie liczba po­wtó­rzeń jest znana z góry.
<?php for ($i = 5; $i <= 20; $i += 5) { echo $i . " "; }
Obrót
$i na wej­ściu
Wa­ru­nek $i <= 20
Co wy­pi­sze
$i po kroku
1
5
prawda
5
10
2
10
prawda
10
15
3
15
prawda
15
20
4
20
prawda
20
25
5
25
fałsz
nic, koniec pętli
25
Wynik: 5 10 15 20, czyli cztery obroty. Gdyby wa­ru­nek brzmiał $i < 20, ob­ro­tów byłoby trzy, bo dwu­dziest­ka już by nie weszła.
while (DOPÓKI) spraw­dza wa­ru­nek PRZED każdym ob­ro­tem, więc gdy jest on fał­szy­wy od po­cząt­ku, blok nie wykona się ani razu. Pasuje tam, gdzie nie wia­do­mo z góry, ile będzie po­wtó­rzeń: tak wła­śnie prze­cho­dzi się po wier­szach za­py­ta­nia do bazy.
do...while (WYKONUJ DOPÓKI) spraw­dza wa­ru­nek na KOŃCU obrotu, więc blok wy­ko­nu­je się co naj­mniej raz, nawet przy wa­run­ku fał­szy­wym. Po za­my­ka­ją­cym na­wia­sie stoi śred­nik.
<?php $i = 1; do { echo $i; $i++; } while ($i > 5);
Wynik: 1, jeden obrót mimo fał­szy­we­go wa­run­ku.
Bie­giem pętli ste­ru­ją dwa słowa. break prze­ry­wa całą pętlę i prze­no­si wy­ko­na­nie za jej klamrę, a continue (KONTYNUUJ) prze­ry­wa tylko bie­żą­cy obrót i prze­cho­dzi do na­stęp­ne­go. W pętli za­gnież­dżo­nej break wy­cho­dzi z jednej pętli, a break 2 z dwóch naraz.
Pętla nie­skoń­czo­na to taka, której wa­ru­nek nigdy nie staje się fał­szy­wy: while (true) albo while ($i < 10) z za­po­mnia­nym zwięk­sza­niem $i. Wy­cho­dzi się z niej przez break, ina­czej skrypt wisi do limitu czasu z php.ini.
Pętla
Kiedy spraw­dza wa­ru­nek
Mi­ni­mum wy­ko­nań
Do czego
for
przed ob­ro­tem
0
znana z góry liczba po­wtó­rzeń, licz­nik
while
przed ob­ro­tem
0
po­wta­rza­nie do skutku, wier­sze za­py­ta­nia
do...while
po ob­ro­cie
1
gdy blok ma wy­ko­nać się choć raz
foreach
przed ob­ro­tem
0
wszyst­kie ele­men­ty ta­bli­cy

fo­re­ach i pętle w kodzie HTML

foreach (DLA KAŻDEGO) to pętla prze­cho­dzą­ca po wszyst­kich ele­men­tach ta­bli­cy, bez licz­ni­ka i bez spraw­dza­nia jej dłu­go­ści. Ma dwie po­sta­cie: $tablica as $wartosc daje same war­to­ści, a $tablica as $klucz => $wartosc daje przy okazji indeks, pod którym war­tość leży. Same ta­bli­ce opi­su­je lekcja o ta­bli­cach w PHP.
<?php $produkty = ["Klawiatura", "Mysz", "Monitor 24"]; echo "<ol>"; foreach ($produkty as $nazwa) { echo "<li>" . $nazwa . "</li>"; } echo "</ol>";
Skrypt wy­pi­su­je nie listę, tylko jej kod, który prze­glą­dar­ka rysuje jako listę nu­me­ro­wa­ną od 1 do 3:
<ol><li>Klawiatura</li><li>Mysz</li><li>Monitor 24</li></ol>
Postać z klu­czem przy­da­je się przy cen­ni­ku: foreach ($ceny as $nazwa => $cena) daje w ko­lej­nych ob­ro­tach parę nazwa i cena, gotową do wy­pi­sa­nia w jednym wier­szu.
Wier­sze tabeli ge­ne­ru­je while, bo liczba wier­szy zwró­co­nych przez za­py­ta­nie nie jest znana z góry. Funk­cja mysqli_fetch_array oddaje ko­lej­ny wiersz wyniku, a gdy wier­szy za­brak­nie, zwraca fałsz i pętla się kończy. Po­łą­cze­nie z bazą opi­su­je lekcja PHP i baza danych.
<?php $wynik = mysqli_query($polaczenie, "SELECT nazwa, cena FROM produkt"); echo "<table>"; while ($wiersz = mysqli_fetch_array($wynik)) { echo "<tr><td>" . $wiersz['nazwa'] . "</td><td>" . $wiersz['cena'] . "</td></tr>"; } echo "</table>";
Wynik: jeden <tr> na każdy pro­dukt z tabeli produkt.
Gdy w pętli jest więcej HTML niż PHP, wy­god­niej­sza bywa skład­nia al­ter­na­tyw­na: klamrę otwie­ra­ją­cą za­stę­pu­je dwu­kro­pek, a za­my­ka­ją­cą słowo endforeach, endwhile, endfor albo endif. Znacz­ni­ki zo­sta­ją wtedy zwy­kłym HTML za­miast na­pi­sów skle­ja­nych w echo.
<ul> <?php foreach ($produkty as $nazwa): ?> <li><?php echo $nazwa; ?></li> <?php endforeach; ?> </ul>
Wynik jest taki sam jak przy pętli z echo: <li> z na­zwa­mi pro­duk­tów w środku <ul>.

Trzy klocki: se­kwen­cja, wybór, ite­ra­cja

Pro­gra­mo­wa­nie struk­tu­ral­ne to sposób pi­sa­nia pro­gra­mów, w którym cały kod składa się z trzech kon­struk­cji: se­kwen­cji (in­struk­cje wy­ko­ny­wa­ne jedna po dru­giej), wyboru (if, switch) i ite­ra­cji (pętle). Każdy blok ma jedno wej­ście i jedno wyj­ście, a skoków w do­wol­ne miej­sce kodu nie ma. Stąd wcię­cia: wcięty wiersz należy do klamry sto­ją­cej wyżej.
Za­pi­sa­nie al­go­ryt­mu w PHP to zło­że­nie jego kroków z tych trzech kloc­ków. Suma liczb z ta­bli­cy to ite­ra­cja plus se­kwen­cja do­da­wa­nia, a śred­nia to jedno dzie­le­nie po wyj­ściu z pętli.
<?php $oceny = [5, 3, 4, 6, 2]; $suma = 0; foreach ($oceny as $ocena) { $suma += $ocena; } $srednia = $suma / count($oceny); echo "Suma: $suma, średnia: $srednia";
Wynik: Suma: 20, średnia: 4.
Szu­ka­nie naj­więk­sze­go ele­men­tu do­kła­da do pętli wybór: do zmien­nej po­moc­ni­czej wpi­su­je się PIERWSZY ele­ment ta­bli­cy, a potem każdy ko­lej­ny po­rów­nu­je się z nią i pod­mie­nia, gdy jest więk­szy. Start od zera za­miast od pierw­sze­go ele­men­tu psuje ten al­go­rytm dla ta­bli­cy z samymi licz­ba­mi ujem­ny­mi. Zli­cza­nie liczb pa­rzy­stych to licz­nik ro­sną­cy tylko wtedy, gdy reszta z dzie­le­nia przez 2 wynosi zero, czyli gdy $liczba % 2 == 0. Silnia mnoży w pętli ko­lej­ne liczby przez wynik z po­przed­nie­go obrotu.
<?php $n = 5; $silnia = 1; for ($i = 2; $i <= $n; $i++) { $silnia *= $i; } echo $silnia;
Wynik: 120.

Ra­chu­nek ite­ra­cji krok po kroku

Py­ta­nie o liczbę ob­ro­tów roz­wią­zu­je się zawsze tak samo: wypisz licz­nik na wej­ściu, sprawdź wa­ru­nek, dopisz krok i po­wtórz do pierw­sze­go fałszu. Ten sam ra­chu­nek pokaże w prze­glą­dar­ce in­ter­pre­ter PHP: każdy obrót pętli jest w nim osob­nym kro­kiem z war­to­ścią licz­ni­ka.
<?php for ($i = 0; $i < 10; $i += 2) { echo $i . " "; }
Licz­nik przyj­mu­je ko­lej­no 0, 2, 4, 6, 8, a przy 10 wa­ru­nek $i < 10 jest już fał­szy­wy, więc ob­ro­tów jest pięć, a wynik to 0 2 4 6 8. Ten sam kod z wa­run­kiem $i <= 10 daje sześć ob­ro­tów i do­pi­su­je na końcu 10.
<?php $x = 1; while ($x < 100) { $x *= 2; } echo $x;
War­to­ści $x to 1, 2, 4, 8, 16, 32, 64 i 128. Ostat­ni obrót za­czy­na się przy 64 i kończy po­dwo­je­niem do 128, a wa­ru­nek 128 < 100 jest już fał­szy­wy: wynik to 128 po sied­miu ob­ro­tach. Pętla do...while z wa­run­kiem fał­szy­wym od po­cząt­ku, jak $i > 5 przy $i równym 1, wykona się do­kład­nie raz.
<?php $suma = 0; for ($i = 1; $i <= 10; $i++) { if ($suma > 10) { break; } $suma += $i; } echo $suma;
Suma rośnie 1, 3, 6, 10, 15. Na szó­stym ob­ro­cie wa­ru­nek $suma > 10 jest praw­dzi­wy, break wy­cho­dzi z pętli przed do­da­niem szóst­ki i wy­ni­kiem jest 15. Z continue pętla do­szła­by do dzie­sią­te­go obrotu, nic już nie do­da­jąc, więc wynik byłby ten sam.

Na eg­za­mi­nie

Py­ta­nia pi­sem­ne o in­struk­cje ste­ru­ją­ce mają kilka sta­łych kształ­tów. Ramka z pętlą i py­ta­nie o liczbę ite­ra­cji albo o wy­pi­sa­ny ciąg liczb: policz war­to­ści licz­ni­ka, pa­mię­ta­jąc, że wa­ru­nek ze zna­kiem < daje o jeden obrót mniej niż ten sam wa­ru­nek ze zna­kiem <=. Ramka z pętlą i py­ta­nie o war­tość zmien­nej po jej za­koń­cze­niu: prze­śledź obroty do pierw­sze­go fał­szy­we­go wa­run­ku. Pętla wy­ko­nu­ją­ca się co naj­mniej raz to do...while, pętla po wszyst­kich ele­men­tach ta­bli­cy z au­to­ma­tycz­nym in­dek­so­wa­niem to foreach, a in­struk­cja prze­zna­czo­na do wy­ko­na­nia okre­ślo­nej liczby ite­ra­cji to for, nie switch ani if. Py­ta­nie o in­struk­cję rów­no­waż­ną po­da­ne­mu switch: to łań­cuch if i elseif po­rów­nu­ją­cych tę samą zmien­ną z ko­lej­ny­mi war­to­ścia­mi, z else w miej­scu default.
Kilka od­po­wie­dzi myli się re­gu­lar­nie. break prze­ry­wa całą pętlę, a continue tylko bie­żą­cy obrót, więc po continue pętla kręci się dalej. W in­struk­cji switch obo­wiąz­ko­wa jest sama kon­struk­cja z wy­ra­że­niem w na­wia­sie, a nie default ani break. Wa­ru­nek na prze­dział od 2 do 6 wymaga &&, bo wersja z || jest praw­dzi­wa dla do­wol­nej liczby, a liczbę pa­rzy­stą wy­bie­ra reszta z dzie­le­nia przez 2 równa zeru, nie iloraz.
W za­da­niu prak­tycz­nym po­le­ce­nie brzmi zwykle: „lista nu­me­ro­wa­na wy­peł­nia­na przez skrypt" albo „dane wy­świe­tlo­ne w tabeli". Pierw­sze to <ol> wy­pi­sa­ne raz, a w środku <li> ge­ne­ro­wa­ne w pętli while po ko­lej­nych wier­szach za­py­ta­nia. Drugie to <table> z <tr> w tej samej pętli. In­struk­cja if spraw­dza tam, czy po­łą­cze­nie z bazą się udało i czy for­mu­larz został już wy­sła­ny. For­mu­larz i odbiór jego danych opi­su­ją lekcje o for­mu­la­rzach HTML i ob­słu­dze GET i POST.

Ściąga

Zapis
Znaczy
if (warunek) { }
wy­ko­naj blok, gdy wa­ru­nek jest praw­dzi­wy
elseif (warunek) { }
ko­lej­ne py­ta­nie, spraw­dza­ne po nie­uda­nym po­przed­nim
else { }
droga na wy­pa­dek, gdy żaden wa­ru­nek nie był praw­dzi­wy
$a = $x > 0 ? 1 : 0;
ope­ra­tor trój­ar­gu­men­to­wy, skrót zapisu if i else
switch ($x) { case 1: ... }
wybór jed­ne­go przy­pad­ku z listy, po nim break
default:
przy­pa­dek dla war­to­ści spoza listy, nie­obo­wiąz­ko­wy
match ($x) { 1 => "a" }
wybór z PHP 8, po­rów­nu­je === i zwraca war­tość
for ($i = 0; $i < 10; $i++)
10 ob­ro­tów, licz­nik od 0 do 9
while ($i < 10)
wa­ru­nek przed ob­ro­tem, może nie wy­ko­nać się ani razu
do { } while ($i < 10);
wa­ru­nek po ob­ro­cie, wykona się co naj­mniej raz
foreach ($tab as $wartosc)
po wszyst­kich ele­men­tach ta­bli­cy, bez licz­ni­ka
foreach ($tab as $klucz => $wartosc)
to samo, z in­dek­sem ele­men­tu
break;
wyj­ście z całej pętli albo z in­struk­cji switch
continue;
po­mi­nię­cie reszty obrotu, przej­ście do na­stęp­ne­go
endforeach;
za­mknię­cie pętli w skład­ni al­ter­na­tyw­nej z dwu­krop­kiem
Pobierz ściągę PDF
ZAWODNIK
egzamin zawodowy INF.02 · INF.03 · INF.04
Serwer Discord
Egzaminy zawodowe IT/Matury/Studia
@yastor
© 2026 Zawodnik · by Yastor
Arkusze i zasady oceniania pochodzą z CKE. Serwis nie jest powiązany z Centralną Komisją Egzaminacyjną.