Dla każdego elementu tablicy zrób…
foreach po tablicy zwykłej i asocjacyjnej ($key => $value)array_sum, count, in_array, sortgrades.php ze średnią i ostrzeżeniemfor ($i = 2; $i <= 10; $i += 4) { echo $i . " "; }
while, a kiedy po for?while zapomnicie $i++?foreach: dla każdej szuflady$games = ["Minecraft", "Fortnite", "FIFA"];
echo "<ul>";
foreach ($games as $game) {
echo "<li>$game</li>";
}
echo "</ul>";
Czytacie: „dla każdego elementu z $games, nazwanego $game, zrób…”. Bez licznika, bez warunku, bez count: PHP sam wie, ile jest szuflad, i sam przechodzi do następnej.
$student = [
"name" => "Anna",
"age" => 18,
"city" => "Warszawa",
];
foreach ($student as $key => $value) {
echo "$key: $value<br>";
}
// name: Anna
// age: 18
// city: Warszawa
foreach ($games as $index => $game) {
echo ($index + 1) . ". $game<br>";
}
// 1. Minecraft
// 2. Fortnite
// 3. FIFA
Dwie zmienne: podpis szuflady (klucz) i zawartość (wartość). Na zwykłej tablicy kluczem jest numer od 0. Nazwy zmiennych wybieracie sami.
Ciekawostka z PHP Manual: od PHP 7.1.0 foreach potrafi rozpakować od razu dwie wartości z zagnieżdżonej tablicy, np. foreach ($pairs as [$a, $b]) zamiast osobno wyciągać $pair[0] i $pair[1]. To ten sam pomysł co $key => $value wyżej, tylko zamiast nazwy klucza dostajecie od razu dwie wartości z jednego wiersza.
$students = [
["name" => "Anna", "grades" => [5, 4, 5, 6]],
["name" => "Bartek", "grades" => [3, 2, 3]],
];
echo "<table>";
foreach ($students as $student) { // wiersz
echo "<tr><td>" . $student["name"] . "</td><td>";
foreach ($student["grades"] as $grade) { // oceny
echo $grade . " ";
}
echo "</td></tr>";
}
echo "</table>";
Ten sam schemat co tabliczka mnożenia: zewnętrzna pętla robi wiersz, wewnętrzna wypełnia go. Różnica: tu liczbę powtórzeń wyznacza tablica, nie licznik.
$grades = [4, 5, 3, 5]| Funkcja | Co robi | Przykład | Wynik |
|---|---|---|---|
array_sum($grades) | sumuje wszystkie wartości | array_sum($grades) | 17 |
count($grades) | liczy elementy | array_sum($grades) / count($grades) | 4.25 |
in_array($x, $grades) | sprawdza, czy wartość jest w tablicy | in_array(6, $grades) | false |
sort($grades) | sortuje rosnąco, zmienia tablicę | sort($grades); print_r($grades); | 3, 4, 5, 5 |
Średnia do pokazania: round(array_sum($grades) / count($grades), 2). Pętlą z $sum += $grade też się da, array_sum robi to w jednym słowie. sort po tablicy asocjacyjnej gubi podpisy szuflad.
| Sytuacja | Co się dzieje | Poprawka |
|---|---|---|
| Macie tablicę i chcecie przejść po wszystkim | for z count działa, ale łatwo pomylić < z <= | foreach: bez licznika nie ma błędu „o jeden” |
| Chcecie liczby od 1 do 10 albo co drugi element | nie ma tablicy, po której można iść | for z licznikiem i krokiem |
foreach ($games as $game) { $game = "X"; } | $games bez zmian: $game to kopia wartości | zmieniacie przez klucz: $games[$index] = "X" |
foreach po zmiennej, która nie jest tablicą | Warning: foreach() argument must be of type array|object, int given | print_r pokaże, co naprawdę jest w zmiennej |
echo $student["grades"]; | wypisze słowo Array i ostrzeżenie; tablicy nie da się wypisać jednym echo | wewnętrzny foreach albo implode(", ", …) (łączy elementy tablicy w jeden tekst) |
&$value zostaje na później) · php.net/manual/en/control-structures.foreach.php1. Która pętla w języku PHP pozwala wykonać operacje na wszystkich elementach tablicy z automatycznym indeksowaniem jej elementów?
forwhileforeachdo...whilefor($i = 1; $i <= 3; $i++) {
for($j = 1; $j <= 3; $j++) {
echo "Iteracja: ($i, $j)";
if($i == 2 and $j == 2) break;
}
}
2. Instrukcja break w przedstawionym kodzie PHP sprawi, że
and to inny zapis &&.
htdocs utwórz grades.php ze szkieletem HTML. W <head> styl: td, th { border: 1px solid #999; padding: 4px; } oraz .warning { background: #ffd0d0; }.$students: 5 uczniów, każdy to tablica z "name" i "grades" (od 3 do 4 ocen, jak na slajdzie). Co najmniej jeden ze średnią poniżej 2.Imię | Oceny | Średnia. Jeden wiersz na ucznia (foreach), oceny wypisane wewnętrznym foreach, średnia z round(array_sum(...) / count(...), 2).class="warning" (operator ?:). Sprawdź w localhost/grades.php.Ma się pojawić: tabela z 5 wierszami, np. Bartek | 3 2 3 | 2.67, a wiersz ucznia ze średnią 1.5 na różowo. Zero ostrzeżeń „Warning”.
Dla szybkich: pod tabelą wypisz najwyższą średnią w klasie (podpowiedź: zbieraj średnie do tablicy $averages[], potem max($averages)).
$students = [
["name" => "Anna", "grades" => [5, 4, 5, 6]],
["name" => "Bartek", "grades" => [3, 2, 3]],
["name" => "Celina", "grades" => [1, 2, 1, 2]],
["name" => "Dawid", "grades" => [4, 4, 5]],
["name" => "Ewa", "grades" => [2, 1, 2]],
];
echo "<table><tr><th>Imię</th><th>Oceny</th><th>Średnia</th></tr>";
foreach ($students as $student) {
$average = round(array_sum($student["grades"]) / count($student["grades"]), 2);
$rowClass = $average < 2 ? ' class="warning"' : '';
echo "<tr$rowClass><td>" . $student["name"] . "</td><td>";
foreach ($student["grades"] as $grade) {
echo $grade . " ";
}
echo "</td><td>$average</td></tr>";
}
echo "</table>";
| Wiersz | Średnia | Klasa |
|---|---|---|
| Anna | 5 | |
| Bartek | 2.67 | |
| Celina | 1.5 | warning |
| Dawid | 4.33 | |
| Ewa | 1.67 | warning |
Dla szybkich: $averages[] = $average; w pętli, po pętli echo max($averages); daje 5.
Bez komputera. Zapisz wynik każdego fragmentu, potem sprawdź w XAMPP.
// A
foreach ([3, 5, 7] as $n) {
echo $n * 2 . " ";
}
// B
$prices = ["bread" => 5, "milk" => 4];
foreach ($prices as $product => $price) {
echo "$product: $price; ";
}
// C
$grades = [4, 5, 3];
echo array_sum($grades) / count($grades);
// D
$names = ["Ola", "Jan", "Adam"];
sort($names);
echo $names[0];
Pułapka w D: sort zmienia tablicę, więc [0] to już nie „Ola”. Kto ma 4 na 4, tłumaczy B sąsiadowi.
| Fragment | Wynik | Dlaczego? |
|---|---|---|
| A | 6 10 14 | każdy element razy 2 |
| B | bread: 5; milk: 4; | klucz i wartość po kolei |
| C | 4 | 12 / 3 |
| D | Adam | po sort alfabetycznie: Adam, Jan, Ola |
foreach różni się od for i kiedy wybieracie które?foreach ($student as $key => $value) w porównaniu z foreach ($student as $value)?Następny temat: funkcje w PHP. Później w tym roku bazy danych: wiersze z MySQL przyjdą jako tablica tablic, dokładnie taka jak $students z dzisiaj.
| Na lekcji | W produkcji | Status |
|---|---|---|
$students wpisane ręcznie w kodzie | Ta sama tablica tablic przychodzi z bazy danych: $students = $result->fetch_all(MYSQLI_ASSOC); i dalej dokładnie ten sam foreach, co dziś. To już połowa tego, co czeka Was przy bazach danych. | nadal w użyciu |
foreach + echo "<tr>" | W szablonach (Blade, Twig) pętla wygląda tak: @foreach ($students as $student) … @endforeach. Ten sam pomysł, inny zapis, HTML czysty. | nadal w użyciu |
array_sum, count, sort | PHP ma kilkadziesiąt funkcji do tablic (array_map, array_filter, usort…). W zespole najpierw szuka się gotowej funkcji, dopiero potem pisze pętlę. | nadal w użyciu |
for ($i = 0; $i < count($arr); $i++) | Tablice dziś przechodzi się przez foreach. Narzędzia sprawdzające kod zgłaszają count liczone w każdym powtórzeniu pętli jako stratę czasu. | zastępowane |