Menu

Pętla foreach w PHP: klucz i wartość, indeks, referencja

foreach ($array as $value) odwiedza każdy element tablicy, a foreach ($array as $key => $value) daje też klucz. Strona opisuje pobieranie indeksu, zmianę wartości przez referencję i pułapkę z unset(), break i continue, tablice zagnieżdżone, list() w foreach i budowanie HTML.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

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żyjKiedy
foreachChcesz każdy element, z kluczem lub bez. Działa na każdej tablicy, liście czy asocjacyjnej.
forLiczysz (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ą.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ