foreach ($array as $value) wykonuje blok raz dla każdego elementu, a $value ma wartość bieżącego elementu. Aby dostać także klucz, napisz foreach ($array as $key => $value).
foreach działa na każdej tablicy, niezależnie od kluczy, i nigdy nie musisz obsługiwać licznika ani sprawdzać długości. To pętla, którą w PHP będziesz pisać najczęściej.
Przechodzenie po kluczach i wartościach
W $key => $value nazwy wybierasz sam: $name => $age, $id => $user, $k => $v. W liście kluczami są pozycje 0, 1, 2. W tablicy asocjacyjnej są to klucze tekstowe, które zdefiniowałeś.
Ostatnia pętla pokazuje szczegół, który zaskakuje: klucz tekstowy wyglądający jak liczba całkowita, na przykład "1", jest zapisywany jako liczba całkowita 1. "01" nie jest kanoniczną liczbą całkowitą, więc pozostaje stringiem.
Pobieranie indeksu w foreach
W liście kluczem jest indeks, więc wystarczy foreach ($items as $i => $item). W tablicy asocjacyjnej nie ma pozycji liczbowej, więc prowadź licznik. Aby inaczej potraktować pierwszy lub ostatni element, porównaj klucz z array_key_first() albo array_key_last().
Ostatnia pętla wypisuje przecinek między imionami, ale nie po ostatnim. Do dokładnie tego zadania krótsze jest implode(', ', array_keys($scores)); sprawdzenie array_key_last() przydaje się, gdy ostatni przebieg potrzebuje innej logiki, a nie tylko innego separatora.
Zmiana wartości tablicy w foreach (przez referencję)
$value jest kopią. Przypisanie do niej niczego w tablicy nie zmienia. Aby zmienić tablicę, przechodź przez referencję z &$value albo zapisuj z powrotem przez klucz.
Oba sposoby działają. Wersja z kluczem nie zostawia po pętli żadnego ukrytego stanu, dlatego wiele zespołów ją woli. Gdy budujesz nową tablicę zamiast zmieniać istniejącą, inną opcją jest array_map().
Pokrewne pytanie: co się stanie, jeśli dodajesz elementy w trakcie pętli? Zwykłe foreach przechodzi po tablicy w postaci z chwili startu pętli, więc $prices[] = ... w jej wnętrzu nie tworzy dodatkowych przebiegów. Pętla przez referencję przechodzi po bieżącej tablicy i odwiedza też nowe elementy.
Pułapka z unset() przy foreach przez referencję
Po foreach ($arr as &$v) zmienna $v nadal jest referencją do ostatniego elementu tablicy. Jeśli później użyjesz nazwy $v w zwykłej pętli, każdy przebieg zapisuje do tego ostatniego elementu. Uruchom to i spójrz na ostatni element:
Druga pętla przypisuje do $letters[2] kolejno A, potem B, a potem własną wartość ostatniego elementu, a przy ostatnim przebiegu to miejsce zawiera już B. Poprawka to jedna linia: wstaw unset($v); zaraz po każdym foreach przez referencję.
break i continue w foreach
break opuszcza pętlę, continue przechodzi do następnego elementu. Częsty wzorzec to wyszukiwanie: przechodź w pętli, aż znajdziesz to, czego potrzebujesz, a potem break, żeby nie sprawdzać reszty tablicy.
W pętlach zagnieżdżonych break 2 opuszcza pętlę wewnętrzną i tę, która ją otacza, a continue 2 przeskakuje do następnego przebiegu pętli zewnętrznej.
Tablice zagnieżdżone i foreach z list()
Wiersze danych to tablice w tablicy. Przechodź po wierszach, a potem po każdym wierszu, albo wyciągnij pola bezpośrednio w linii foreach przez destrukturyzację tablicy: [$a, $b] dla list, ['key' => $var] dla wierszy asocjacyjnych. list($a, $b) to starszy zapis [$a, $b].
Na stronie o destrukturyzacji znajdziesz więcej o składni [...] =, w tym pomijanie elementów i wzorce zagnieżdżone.
Budowanie listy lub tabeli HTML przez foreach
W szablonie forma z dwukropkiem foreach (...): i endforeach; utrzymuje czytelność pętli między znacznikami. Ten blok buduje tabelę, a nagłówki kolumn są linkami: kliknij jeden w zakładce Page, a ten sam skrypt uruchomi się ponownie z ustawionym $_GET['sort'], więc wiersze wrócą w nowej kolejności.
Dwa nawyki warte skopiowania z tego bloku: wartość sort z adresu URL jest sprawdzana z listą dozwolonych kolumn, zanim zostanie użyta, a każda wartość wypisywana do HTML, która może zawierać tekst użytkownika, przechodzi przez htmlspecialchars().
foreach po null, pustej tablicy lub obiekcie
Pusta tablica nie stanowi problemu: treść po prostu się nie wykona. null, string czy liczba już tak: PHP wypisuje ostrzeżenie i pomija pętlę. Dla $tags = null; foreach ($tags as $tag) wypisuje:
Warning: foreach() argument must be of type array|object, null given in /var/www/html/index.php on line 4
Zdarza się to najczęściej przy danych, których czasem brakuje, jak opcjonalne pole w zdekodowanym JSON. Podstaw pustą tablicę przez ??:
foreach ($data['tags'] ?? [] as $tag) {
echo $tag;
}
Słowo object w tym komunikacie nie jest przypadkowe: foreach po obiekcie odwiedza jego właściwości widoczne z miejsca, w którym działa pętla (poza klasą: publiczne), a kluczem jest nazwa właściwości. Klasy implementujące Iterator lub IteratorAggregate oraz generatory same decydują, co widzi foreach.
foreach vs for vs array_map
| Użyj | Kiedy |
|---|---|
foreach | Chcesz każdy element, z kluczem lub bez. Działa na każdej tablicy, liście czy asocjacyjnej. |
for | Liczysz (od 1 do 100, co drugi element) albo potrzebujesz sąsiadów przez indeks ($a[$i - 1]). Zobacz pętla for. |
array_map() | Budujesz nową tablicę, przekształcając każdy element, często w jednej linii z fn. |
array_filter() | Zostawiasz tylko elementy, które przechodzą test. |
Szybki sposób na decyzję: jeśli treść pętli tylko oblicza nową wartość dla każdego elementu, array_map(fn($x) => $x * 2, $a) mówi to w jednej linii. Jeśli ma efekty uboczne (wypisywanie, zapisywanie, liczenie kilku rzeczy naraz) albo potrzebuje break, napisz foreach.
Najczęściej zadawane pytania
Jak pobrać klucz i wartość w pętli foreach w PHP?
Użyj formy z =>: foreach ($array as $key => $value) { echo "$key: $value"; }. W zwykłej liście kluczem jest indeks (0, 1, 2), w tablicy asocjacyjnej jest nim klucz tekstowy, na przykład 'name'.
Jak pobrać indeks w pętli foreach w PHP?
W liście klucz już jest indeksem: foreach ($items as $i => $item). W tablicy asocjacyjnej prowadź własny licznik: ustaw $i = 0; przed pętlą i $i++ na końcu każdego przebiegu. array_key_first() i array_key_last() mówią, który klucz jest pierwszy, a który ostatni.
Jak zmienić wartości tablicy wewnątrz foreach w PHP?
Przechodź przez referencję z &: foreach ($prices as &$price) { $price *= 2; } unset($price);. Albo zapisuj przez klucz: foreach ($prices as $key => $price) { $prices[$key] = $price * 2; }. Zwykłe $price = ... zmienia tylko kopię.
Dlaczego foreach przez referencję w PHP powiela ostatni element?
Po foreach ($arr as &$v) zmienna $v nadal jest referencją do ostatniego elementu. Kolejne foreach ($arr as $v) zapisuje wtedy każdą wartość do tego ostatniego miejsca, więc na końcu powtarza się w nim przedostatnia wartość. Wywołaj unset($v); zaraz po pętli z referencją.
Jak przerwać pętlę foreach w PHP?
break; natychmiast zatrzymuje pętlę, a continue; przechodzi do następnego elementu. W pętlach zagnieżdżonych break 2; opuszcza i pętlę wewnętrzną, i zewnętrzną.