Pętle
Pętle (ang. loops, iterations) to instrukcje, które pozwalają wielokrotnie powtórzyć fragment programu. W PHP dostępne są następujące rodzaje pętli:
for – gdy znamy liczbę iteracji
foreach – do iteracji po elementach tablicy
while – gdy warunek sprawdzamy przed wykonaniem iteracji
do…while – gdy warunek sprawdzamy po wykonaniu iteracji
Pętle for… i foreach…
Budowa pętli for wygląda następująco
for( inicjalizacja zmiennych; sprawdzenie warunku; modyfikacja zmiennych)
{
instrukcja1;
instrukcja...;
}
Elementy pętli for:
- Inicjalizacja – wykonywana raz przed pierwszą iteracją
- Warunek – sprawdzany przed każdą iteracją; jeśli false, pętla kończy działanie
- Modyfikacja – wykonywana po każdej iteracji
Przykład 1: Napisz skrypt, który wyświetli 100 kolejnych liczb całkowitych począwszy od 3.
for ($i = 3; $i <= 102; $i++) {
echo $i;
if ($i < 102) {
echo ', ';
}
}
Przykład 2: Napisz skrypt, obliczający n! (n silnia).
$n = 5;
if ($n == 0 || $n == 1) {
$silnia = 1;
} else {
$silnia = 1;
for ($i = 2; $i <= $n; $i++) {
$silnia *= $i;
}
}
echo "Silnia z $n = $silnia";
// Wynik: Silnia z 5 = 120
Przykład 3: Napisz skrypt, który za pomocą znaków * (gwiazdki) narysuje trójkąt.
define('X', 15); // liczba musi być nieparzysta
echo '<pre>';
for ($w = 1; $w <= X; $w++) {
for ($k = 1; $k <= X + $w; $k++) {
if ($k == X + $w) {
echo "\n";
} elseif ($k > X - $w && $k < X + $w) {
echo '*';
} else {
echo ' ';
}
}
}
echo '</pre>';
//uproszczona wersja
$wysokosc = 8;
echo '<pre>';
for ($i = 1; $i <= $wysokosc; $i++) {
echo str_repeat(' ', $wysokosc - $i);
echo str_repeat('*', 2 * $i - 1);
echo "\n";
}
echo '</pre>';
Przykład 4: Napisz skrypt wyświetlający ciąg Fibonacciego i wypisz wartość ostatniego elementu.
$n = 10;
if ($n <= 0) {
echo "n musi być liczbą dodatnią";
} elseif ($n == 1) {
echo "1. element ciągu Fibonacciego to: 0";
} elseif ($n == 2) {
echo "2. element ciągu Fibonacciego to: 1";
} else {
$f1 = 0; // pierwszy element
$f2 = 1; // drugi element
echo "0 1 ";
for ($i = 3; $i <= $n; $i++) {
$fn = $f1 + $f2;
echo $fn . " ";
$f1 = $f2;
$f2 = $fn;
}
echo "<br>$n. elementem ciągu Fibonacciego jest $f2";
}
Pętla for może operować na literach, zakres literowy jest podobny jak podział kolumn w Excelu
for ($i = 'a'; $i <= 'z'; $i++) {
echo $i . ' ';
}
// Wynik: a b c d e f g h i j k l m n o p q r s t u v w x y z
Pętla for może mieć postać nieskończoną:
$i = 1;
for (;;) {
echo "Wykonuję się $i raz<br>";
if ($i == 10) {
break;
}
$i++;
}
//Uwaga: Zawsze upewnij się, że pętla nieskończona ma warunek przerwania (break), inaczej spowoduje zawieszenie skryptu!
Pętla for może przyjmować wiele warunków, będą one wykonywane po sobie
for ($i = 1, $j = 0; $i <= 10; $j += $i, print "i wynosi = $i, a j = $j<br/>", $i++);
Możemy z pętli wyciągnąć warunki:
for ($i = 1; ; $i++) {
if ($i > 10) {
break;
}
echo $i;
}
foreach
Pętla foreach służy do wykonywania operacji na kolejnych elementach tablicy.
$tablica = ['jabłko', 'banan', 'gruszka'];
foreach ($tablica as $wartosc) {
echo $wartosc . '<br>';
}
jeżeli chcemy operować również na indeksach, możemy je pobrać:
$tablica = [
'a' => 'jabłko',
'b' => 'banan',
'c' => 'gruszka'
];
foreach ($tablica as $klucz => $wartosc) {
echo "$klucz -> $wartosc<br>";
}
Pętle while…
Pętla while wykonuje instrukcje tak długo, jak długo warunek jest prawdziwy. Warunek sprawdzany jest przed każdą iteracją.
while (warunek) {
// instrukcje
}
Przykład 1: Wyświetl wszystkie liczby całkowite nieujemne, mniejsze od podanej liczby.
$x = 10;
$min = 0;
echo "Liczby całkowite mniejsze od $x, to:<br>";
while ($min < $x) {
echo $min;
if ($min < $x - 1) {
echo ' ';
}
$min++;
}
// Wynik: 0 1 2 3 4 5 6 7 8 9
Przykład 2: Napisz skrypt wyznaczający NWD (największy wspólny dzielnik).
$x = 15;
$y = 10;
$a=$x;
$b=$y;
while($a!=$b)
{
if($a>$b) $a-=$b;
else $b-=$a;
}
$nwd = $a; // lub b - obie zmienne przechowują wynik NWD(a,b)
echo('Dla a='.$x.' i b='.$y.' NWD = '.$nwd);
Pętle do… while…
Pętla do…while wykonuje instrukcje co najmniej raz, a następnie sprawdza warunek. Warunek sprawdzany jest po każdej iteracji.
do {
// instrukcje
} while (warunek);
Przykład 1: Napisz skrypt wyświetlający wszystkie liczby całkowite od zera do danej liczby.
$x = 15;
$min = 0;
do {
echo $min;
if ($min < $x) {
echo ' ';
}
$min++;
} while ($min <= $x);
// Wynik: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Różnica między while a do…while
// while - może w ogóle się nie wykonać
$i = 10;
while ($i < 5) {
echo "Nie wypisze się";
}
// do...while - wykona się przynajmniej raz
$i = 10;
do {
echo "Wypisze się raz"; // wykona się mimo że warunek jest fałszywy
} while ($i < 5);
Kontrola przepływu pętli
Działanie pętli lub skryptu możemy przerwać w dowolnej chwili lub możemy pominąć część instrukcji do wykonania:
- instrukcja break; powoduje natychmiastowe wyjście z pętli
- instrukcja continue; powoduje przeskoczenie do następnego obiegu pętli
- instrukcja exit; powoduje zakończenie wykonywania skryptu
Przerywanie działania pętli za pomocą instrukcji break;
for ($i = 3; $i <= 100; $i++) {
if ($i > 90) {
break; // wyjście z pętli
}
echo $i . ' ';
}
echo '<br>Ta instrukcja zostanie wykonana';
// Wypisze liczby 3-90, a następnie tekst
// Przerwij dwie pętle naraz
for ($i = 0; $i < 5; $i++) {
for ($j = 0; $j < 5; $j++) {
if ($j == 2) {
break 2; // wyjdź z obu pętli
}
echo "[$i][$j] ";
}
}
Przeskok do następnej iteracji (obiegu pętli) za pomocą instrukcji continue;
// Wypisz tylko liczby parzyste od 1 do 100
for ($i = 1; $i <= 100; $i++) {
if ($i % 2 != 0) {
continue; // pomiń nieparzyste
}
echo $i;
if ($i < 100) {
echo ', ';
}
}
Przerywanie wykonywania skryptu za pomocą instrukcji exit;
for ($i = 3; $i <= 10; $i++) {
if ($i > 9) {
exit('Koniec skryptu'); // lub die()
}
echo $i . ' ';
}
echo '<br>Ta instrukcja NIE zostanie wykonana';
Tabela porównawcza pętli
| Pętla | Warunek sprawdzany | Min. wykonań | Przypadek użycia |
|---|---|---|---|
| for | Przed iteracją | 0 | Znana liczba iteracji |
| foreach | Automatycznie | 0 (jeśli tablica pusta) | Iteracja po tablicy/obiekcie |
| while | Przed iteracją | 0 | Nieznana liczba iteracji, warunek przed |
| do…while | Po iteracji | 1 | Nieznana liczba iteracji, warunek po |
Kiedy używać poszczególnych pętli:
- for – gdy znasz dokładną liczbę iteracji lub potrzebujesz indeksu
- foreach – gdy iterujesz po tablicy lub kolekcji
- while – gdy nie znasz liczby iteracji, warunek sprawdzany przed wykonaniem
- do…while – gdy pętla musi wykonać się przynajmniej raz
Pamiętaj:
- Zawsze upewnij się, że pętla ma warunek zakończenia
- Używaj break i continue świadomie
- Preferuj wbudowane funkcje (array_map, array_filter) zamiast ręcznych pętli
- Unset referencji po foreach z &
- Unikaj modyfikacji tablicy podczas iteracji foreach
- Używaj składni alternatywnej w szablonach HTML
Zadania do samodzielnego wykonania:
Zadanie 1 (dla klas, które miały już HTMLa): Za pomocą pętli for stwórz tabelę w HTML składająca się z 2 wierszy i 10 kolumn.
Zadanie 1 (dla klas, które nie miały HTMLa): Za pomocą pętli for wypisz na ekranie dowolne znaki, tak aby układały się w 2 wiersze po 10 znaków.
Zadanie 2: Za pomocą pętli for, while i do… while napisz skrypt, który będzie zwiększał zmienną $i od 1 do 100 o 2, a następnie zmniejszał ją do 1 o 4.
Zadanie 3: Napisz skrypt, który dla zmiennej $n=10 i $n>0 będzie ją zmniejszał o 1 i wypisywał: wartości kwadratów zmiennej $n; następnie wartości kwadratów zmiennej $n dla $n parzystych.
Zadanie 4: Za pomocą pętli for, while i do… while napisz skrypt, który wypisze ilość iteracji pętli dla zmiennej $i<=10. Tam gdzie to możliwe zastosuj $i++, ++$i, $i- -, – -$i.
Zadanie 5: Napisz skrypt, który sprawdzi, czy podana liczba jest liczbą pierwszą.
Zadanie 6: Za pomocą pętli for stwórz tabliczkę mnożenia wg przykładu:

Zadanie 7: Napisz skrypt, który za pomocą znaków * (gwiazdki) narysuje kwadrat. Gwiazdki leżące na obwodzie mają mieć kolor niebieski, a gwiazdki leżące na przekątnych zielone.
Zadanie 8: Napisz skrypt, który po podaniu przez użytkownika promienia koła, za pomocą znaków * (gwiazdki), narysuje je.
Zadanie 9: Oblicz ilość bloków z jakich został zbudowany sześcian o boku długości 6.
Zadanie 10: Wyświetl kolejno liczby od 1 do 10 (każda w nowej linii). Wykorzystaj pętle for
Zadanie 11: Wyświetl liczby malejąco od 10 do 0. Użyj pętli for.
Zadanie 12: Wyświetl kolejno liczby od 10 do 0 z krokiem 0,5. Użyj pętli for.
Zadanie 13: Wyświetl: „PHP1 PHP2 PHP3 PHP4 PHP5 PHP6 PHP7 PHP8 PHP9 PHP10”. Użyj pętli while
Zadanie 14: Napisz skrypt z użyciem pętli do…while wyświetlający następującą listę:
• Element nr 1
• Element nr 2
• Element nr 3
• Element nr 4
Zadanie 15: Napisz skrypt sumujący wszystkie liczby nieparzyste z przedziału od 0 do 10. Użyj instrukcji continue.
Zadanie 16: Napisz skrypt wyświetlający: “1-2-3-5-6-7-8-9”. Użyj dowolnej pętli i instrukcji przerywającej (wykluczono wartość 4).
Zadanie 17: Napisz skrypt wyświetlający szachownicę.
TaskQuest — Twój projekt na cały semestr
Karta pracy
Projekt: TaskQuest — grywalizowana aplikacja do zarządzania zadaniami. Użytkownik loguje się, dodaje zadania, za ich wykonanie zdobywa punkty XP, awansuje na poziomy, zdobywa odznaki i widzi swoją pozycję w rankingu klasy. Każda lekcja rozbudowuje tę samą aplikację o nową funkcję.
PHP — instrukcje warunkowe, wybór, operator warunkowy
Cel lekcji
Nauczyć aplikację podejmować decyzje na podstawie danych.
Co dziś budujesz
Logikę awansu na poziom oraz tytuły zależne od poziomu.
Ważna uwaga o progu poziomu
Skoro $xp cały czas rośnie i się nie resetuje, to próg potrzebny do kolejnego poziomu też musi rosnąć — inaczej po awansie na poziom 2 użytkownik z 100 XP awansowałby na poziom 3 już przy 101 XP, co byłoby za łatwe. Dlatego próg do następnego poziomu liczymy jako $poziom * XP_NA_POZIOM (poziom 1→2 potrzeba 100 XP, poziom 2→3 potrzeba 200 XP, itd.).
Ograniczenie tej wersji: pojedynczy if sprawdza próg i awansuje tylko o jeden poziom na raz. Jeśli ktoś zdobędzie od razu bardzo dużo XP i „przeskoczy” dwa progi naraz, ten kod tego nie złapie w jednym uruchomieniu. To celowe uproszczenie — w lekcji 5 (pętle) zamienimy ten if na while, żeby awansować użytkownika o tyle poziomów, ile faktycznie mu się należy, za jednym razem.
Kroki do wykonania
- Oblicz próg kolejnego poziomu: $progNastepnegoPoziomu = $poziom * XP_NA_POZIOM;.
- Napisz warunek if: jeśli $xp >= $progNastepnegoPoziomu, zwiększ $poziom o 1 i wyświetl komunikat „Awansowałeś!”.
- Za pomocą switch przypisz użytkownikowi tytuł zależny od poziomu, np. 1 = Nowicjusz, 2 = Wojownik, 3 i więcej = Mistrz.
- Zdefiniuj zmienną $wykonalDzisiajZadanie — na razie ustaw ją ręcznie na true albo false, tylko po to, żeby przetestować działanie operatora warunkowego (prawdziwe sprawdzanie, czy użytkownik był dziś aktywny, zrobimy dopiero w lekcji 7, gdy poznamy obsługę dat).
- Za pomocą operatora warunkowego (?: lub ??) wyświetl na podstawie $wykonalDzisiajZadanie krótką etykietę statusu: „Aktywny” albo „Nieaktywny”.
- Przetestuj różne wartości $xp (w tym taką, która przeskakuje próg) oraz obie wartości $wykonalDzisiajZadanie, żeby zobaczyć różne komunikaty.
Podpowiedzi / fragmenty kodu
<?php
$progNastepnegoPoziomu = $poziom * XP_NA_POZIOM;
if ($xp >= $progNastepnegoPoziomu) {
$poziom++;
echo "Awansowałeś na poziom $poziom!";
}
switch ($poziom) {
case 1:
$tytul = "Nowicjusz";
break;
case 2:
$tytul = "Wojownik";
break;
default:
$tytul = "Mistrz";
}
// Tymczasowo ustawiane ręcznie - w lekcji 7 zastąpimy to sprawdzeniem daty
$wykonalDzisiajZadanie = true;
$status = $wykonalDzisiajZadanie ? "Aktywny" : "Nieaktywny";
echo "Status: $status";
?>
Do samodzielnego sprawdzenia
☐ Próg kolejnego poziomu jest liczony wzorem ($poziom * XP_NA_POZIOM), a nie sztywną liczbą.
☐ Zmiana wartości $xp faktycznie zmienia poziom i tytuł na stronie.
☐ Rozumiem i potrafię wyjaśnić, dlaczego pojedynczy if nie obsłuży awansu o dwa poziomy naraz.
☐ switch obsługuje co najmniej 3 przypadki plus default.
☐ Etykieta statusu poprawnie zmienia się w zależności od $wykonalDzisiajZadanie.
Pytania kontrolne
- Dlaczego próg kolejnego poziomu musi rosnąć wraz z poziomem, a nie może być stałą liczbą?
- Co się stanie w powyższym kodzie, jeśli użytkownik z poziomu 1 (próg 100) zdobędzie od razu 250 XP? Ile poziomów awansuje po jednym uruchomieniu skryptu i dlaczego?
- Kiedy lepiej użyć switch zamiast wielu if/elseif?
- Co robi operator ?? i czym różni się od ?:?