INF.03-03-24.06-SGCzerwiec 2024 · 53 kroki · ok. 88 min · 39 kryteriów z klucza
Rozwiązanie krok po kroku: Poziomy rzek Dolnego Śląska (Wersja podstawowa)
Serwis o poziomach rzek to baza rzeki (wodowskazy i ich pomiary, relacja 1..n) z czterema zapytaniami - wybór kolumn, złączenie JOIN z warunkiem na datę, to samo złączenie z porównaniem dwóch kolumn (stanWody > stanOstrzegawczy) i AVG z GROUP BY - oraz mapa Polski przygotowana w edytorze grafiki i strona poziomRzek.php. Formularz z trzema polami opcji wysyła wybór metodą POST, a skrypt formularza wypełnia tabelę wszystkimi wodowskazami, tylko tymi ponad stanem ostrzegawczym albo tylko ponad alarmowym. Skrypt 2 wypisuje średni stan wody z każdego dnia pomiarów.
Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypty są najpierw napisane najprościej, funkcjami z tabeli 1 arkusza (mysqli_query, mysqli_fetch_row, isset), a na końcu przerobione na wersję z prawdziwych projektów: tablica warunków zamiast drabinki if, wybrane pole opcji zaznaczone po wysłaniu, wszystkie wodowskazy od pierwszego wejścia, htmlspecialchars i średnie zaokrąglone do części setnych.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: bloki na siatce CSS (grid-template-areas), kolory w zmiennych i PHP na PDO z danymi pobranymi przed HTML-em - obie wersje są zgodne z kluczem.
Baza i grafiki pochodzą z prawdziwego archiwum pliki3 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 na bazie z arkusza - po wybraniu „Wszystkie” i kliknięciu „Pokaż” (obraz 2), a w krokach z warunkami po wybraniu pozostałych pól (obrazy 3 i 4).
Jak liczą się punkty. Klucz ma 39 kryteriów (R.1.1 - R.5.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 30 punktów - można stracić 9 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Baza danych
Kroki 1-7 · po tym etapie masz 6 z 39 kryteriów (pkt)
Krok 1: Baza danych rzeki
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie rzeki, z zestawem polskich znaków (np. utf8_unicode_ci)
Najpierw archiwum pliki3.zip z pulpitu (hasło St@ny%RzeK - małpa, procent, wielkość liter ma znaczenie) i folder z numerem zdającego, do którego trafiają rozpakowane pliki. W phpMyAdmin: Nowa, nazwa rzeki, porównywanie utf8_unicode_ci.
Krok 2: Import tabel z pliku baza.sql
ok. 2 min
Polecenie z arkusza
Do bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum
Zaznaczona baza rzeki, potem Import → baza.sql → Wykonaj. Powstają dwie tabele z obrazu 1: wodowskazy (17 punktów pomiarowych ze stanem ostrzegawczym i alarmowym) i pomiary (34 pomiary - po jednym dla każdego wodowskazu z 5 i 6 maja 2022). Pole wodowskazy_id łączy pomiar z wodowskazem - to relacja 1..n: jeden wodowskaz, wiele pomiarów.
Krok 3: Zrzut ekranu import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych rzeki czynność udokumentowano plikiem o nazwie import w formacie PNG
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel.
Print Screen, wklejenie do edytora grafiki i zapis jako import.png. Uwaga na formaty: import idzie do PNG, a zrzuty zapytań do JPEG.
Typowe błędy
Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).
Krok 4: Zapytanie 1: wodowskazy i stan alarmowy
Kryteria: ,
R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonano zapytanie 1 wybierające jedynie pola nazwa, rzeka, stanAlarmowy z tabeli wodowskazy . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy; oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 17 wierszy, jedynie pola nazwa, rzeka, stanAlarmowy
ok. 1 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie pola nazwa, rzeka, stanAlarmowy z tabeli wodowskazy
SELECT nazwa, rzeka, stanAlarmowy - trzy pola, w tej kolejności,
FROM wodowskazy - bez warunku, więc wszystkie wiersze.
Wynik: 17 wierszy, jak w kluczu. Zapytania trafiają do kwerendy.txt, zrzut do kw1.jpg.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: stany wody z 5 maja 2022
Kryteria:
R.1.4 Wykonano zapytanie 2 wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty 2022-05-05. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = wodowskazy_id WHERE dataPomiaru='2022-05-05'; (możliwe również INNER JOIN bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 17 wierszy, jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody
ok. 3 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty pomiaru 2022-05-05. Należy posłużyć się relacją
SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody - cztery pola wodowskazu i stan wody z pomiaru,
FROM wodowskazy JOIN pomiary - złączenie obu tabel,
ON wodowskazy.id = pomiary.wodowskazy_id - relacja z obrazu 1: pomiar wskazuje swój wodowskaz,
WHERE dataPomiaru = '2022-05-05' - data w apostrofach, w zapisie rok-miesiąc-dzień.
Wynik: 17 wierszy - każdy wodowskaz raz, ze stanem z 5 maja. Bez warunku na datę byłoby 34 (dwa pomiary na wodowskaz). To jest tabela z obrazu 2 - z tego zapytania powstanie skrypt formularza. Zrzut: kw2.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;-- Zapytanie 2SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05';
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: wodowskazy ponad stanem ostrzegawczym
Kryteria:
R.1.5 Wykonano zapytanie 3 wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty 2022-05-05 oraz takie, dla których stanWody jest wyższy niż stanOstrzegawczy. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = wodowskazy_id WHERE dataPomiaru='2022-05-05'AND stanWody > stanOstrzegawczy; (możliwe również INNER JOIN lub bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 5 wierszy, jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody, dla nazw: Jarnołtów, Łazany, Jelenia Góra, Nowogrodziec, Bardo
ok. 2 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty pomiaru 2022-05-05 oraz takie, dla których stanWody jest wyższy niż stanOstrzegawczy. Należy posłużyć się relacją
To zapytanie 2 z drugim warunkiem dopisanym przez AND:
AND stanWody > stanOstrzegawczy - warunek porównuje dwie kolumny tego samego wiersza, a nie kolumnę z liczbą; „wyższy niż” to ostra nierówność.
Wynik: 5 wierszy - Jarnołtów, Łazany, Jelenia Góra, Nowogrodziec, Bardo, jak w kluczu i na obrazie 3. Zrzut: kw3.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;-- Zapytanie 2SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05';-- Zapytanie 3SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05' AND stanWody > stanOstrzegawczy;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: średni stan wody w każdym dniu
Kryteria:
R.1.6 Wykonano zapytanie 4 wybierające jedynie datę pomiaru oraz liczące średnie stany wody z tabeli pomiary grupując je według daty pomiaru. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru; oraz wynik działania udokumentowano zrzutem, na którym są widoczne dane: 2022-05-05 167.6471 oraz 2022-05-06 179.5882; z dowolną dokładnością
ok. 2 min
Polecenie z arkusza
Zapytanie 4: wybierające jedynie datę pomiaru oraz liczące średnie stany wody z tabeli pomiary grupując je według daty pomiaru
SELECT dataPomiaru, AVG(stanWody) - data i średnia z grupy,
FROM pomiary,
GROUP BY dataPomiaru - jeden wiersz na każdy dzień.
Wynik: 2022-05-05 167.6471 i 2022-05-06 179.5882 (MySQL podaje średnią z czterema miejscami po przecinku). Zrzut: kw4.jpg. To zapytanie wyśle Skrypt 2.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;-- Zapytanie 2SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05';-- Zapytanie 3SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05' AND stanWody > stanOstrzegawczy;-- Zapytanie 4SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-28 · po tym etapie masz 19 z 39 kryteriów (pkt)
Krok 8: obraz1.png: przezroczyste tło
ok. 3 min
Polecenie z arkusza
Dla grafiki obraz1.png, wypakowanej z archiwum, należy nadać przezroczyste tło oraz wypełnić obszar województwa dolnośląskiego kolorem niebieskim o dowolnym odcieniu. Województwo dolnośląskie znajduje się w lewym dolnym rogu mapy – patrz obraz 2.
obraz1.png to mapa 100 × 100 pikseli: szare granice województw na białym tle, bez przezroczystości. W GIMP-ie najpierw Warstwa → Przezroczystość → Dodaj kanał alfa (bez niego usunięte piksele staną się kolorem tła, a nie przezroczystością). Potem Zaznaczanie spójnego obszaru (różdżka) i kliknięcie w biel poza mapą - z klawiszem Shift w każdym rogu, jeśli obszary się nie łączą - i klawisz Delete. Różdżka zatrzymuje się na granicy kraju, więc wnętrze województw zostaje białe. Podgląd pokazuje mapę po tym kroku na ciemnym tle - widać, że biel zniknęła tylko na zewnątrz.
Podgląd strony po tym kroku
Krok 9: obraz1.png: województwo dolnośląskie na niebiesko
Kryteria:
R.2.1 Grafika obraz1.png ma tło przezroczyste, województwo dolnośląskie jest wypełnione kolorem niebieskim (dowolny odcień)
ok. 2 min
Polecenie z arkusza
Dla grafiki obraz1.png, wypakowanej z archiwum, należy nadać przezroczyste tło oraz wypełnić obszar województwa dolnośląskiego kolorem niebieskim o dowolnym odcieniu. Województwo dolnośląskie znajduje się w lewym dolnym rogu mapy – patrz obraz 2.
Kolor pierwszego planu niebieski, narzędzie Wypełnienie kubełkiem z opcją Wypełnienie podobnych kolorów i kliknięcie we wnętrze województwa w lewym dolnym rogu mapy - nad nim leży lubuskie (łatwo się pomylić, oba są przy zachodniej granicy). Kubełek zalewa biel do granic województwa. Eksport: Plik → Wyeksportuj jakoobraz1.png - format PNG zachowuje przezroczystość.
Typowe błędy
Eksport do JPEG gubi przezroczystość - tło znowu staje się białe i R.2.1 przepada.
Podgląd strony po tym kroku
Krok 10: Plik poziomRzek.php w HTML5
ok. 1 min
Polecenie z arkusza
Składa się ze strony o nazwie poziomRzek.php zapisanej w języku HTML5
Deklaracja <!DOCTYPE html>, sekcje head i body. Nazwa pliku z wielką literą „R” w środku, jak w arkuszu - na serwerze wielkość liter w nazwach plików ma znaczenie. Rozszerzenie .php, bo dojdą skrypty; strona otwiera się przez http://localhost/....
R.2.2 Witrynę internetową zapisano w pliku poziomRzek.php oraz zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> i zadeklarowano język witryny polski np.<HTML lang="pl">. Strona zawiera sekcje head i body
ok. 1 min
Polecenie z arkusza
Jawnie zastosowany właściwy standard kodowania polskich znaków
<meta charset="UTF-8"> jako pierwszy element <head>. Ten krok zamyka kryterium R.2.2: nazwa pliku, deklaracja HTML5, język i kodowanie.
R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css , formatowanie CSS pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)
ok. 1 min
Polecenie z arkusza
Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony
Nazwa pliku: styl.css (nie style.css). Klucz przypomina, że R.3.5 przepada także wtedy, gdy któryś selektor jest źle zapisany, np. kropka zamiast # przy identyfikatorze.
Krok 15: Bloki: dwa banery, menu, lewy, prawy, stopka
Kryteria:
R.2.4 Układ strony zdefiniowano dzieląc ją na: dwa bloki banera, blok menu, lewy, prawy oraz stopkę. Zastosowano semantyczne znaczniki sekcji HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, stopki - footer, dopuszcza się zagnieżdżenie bloków div w znacznikach semantycznych
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: na górze dwa bloki banera, poniżej menu, poniżej bloki: lewy i prawy, na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
Banery to dwa header (klucz wymaga ich wprost, razem z footer dla stopki - R.2.4), rozróżnione identyfikatorami map i title. Menu z formularzem to nav, blok lewy z tabelą - main (główna treść strony), blok prawy z dodatkowymi informacjami - aside. Kolejność w kodzie jest taka jak na obrazie 2: od góry, od lewej.
R.3.3 Formularz wysyła dane metodą POST do tego samego pliku (poprawne również bez atrybutu action )
ok. 1 min
Polecenie z arkusza
Zawartość menu: Formularz wysyłający dane do skryptu na tej samej stronie, metodą bezpieczną.
method="post" - „metoda bezpieczna” z arkusza: wybór jedzie w treści żądania, nie w adresie strony. W specyfikacji HTTP „bezpieczne” są co prawda metody, które niczego nie zmieniają na serwerze (GET i HEAD), ale arkusz używa tego słowa w innym sensie, a klucz wymaga POST. Atrybut action jest pominięty - formularz bez niego wysyła dane do bieżącego pliku, czyli do skryptu na tej samej stronie (klucz: „poprawne również bez atrybutu action”).
Krok 19: Trzy pola opcji z etykietami w jednej grupie
ok. 3 min
Polecenie z arkusza
Obok siebie 3 pola opcji (radio) zgrupowane, tak aby było możliwe jednoczesne wybranie tylko jednego pola. Etykiety przy polach opcji: „Wszystkie”, „Ponad stan ostrzegawczy”, „Ponad stan alarmowy” (pola opcji będą formatowane jedną klasą CSS)
„Zgrupowane” to ten sam atrybut name (option) we wszystkich trzech polach - przeglądarka pozwala wtedy zaznaczyć tylko jedno, a do skryptu trafi jedna para option = wartość wybranego pola (all, warning albo alarm). Każde pole ma swoją etykietę <label> połączoną przez for/id (kliknięcie w napis zaznacza pole), a etykiety mają wspólną klasę radio-label - to nią CSS pokoloruje teksty przy polach. Pola i etykiety są liniowe, więc stoją obok siebie.
poziomRzek.phpPHPzmienione: 6 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> </form> </nav> <main> </main> <aside> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 20: Przycisk „Pokaż” wysyłający formularz
Kryteria: ,
R.2.9 W bloku menu umieszczono formularz z trzema polami opcji i przyciskiem. Pola opcji są podpisane etykietami: "Wszystkie", "Ponad stan ostrzegawczy", "Ponad stan alarmowy", zastosowano znaczniki <label> (dopuszczalne zastosowanie <span> lub <div>)
R.3.4 W jednym momencie można zaznaczyć tylko jedno pole opcji oraz przycisk wysyła dane do skryptu (typ submit lub button bez typu)
ok. 1 min
Polecenie z arkusza
Przycisk o treści „Pokaż”, wysyłający dane do skryptu
<button> bez atrybutu type wewnątrz formularza jest przyciskiem wysyłającym (submit). Formularz ma już trzy pola opcji z etykietami i przycisk (R.2.9), a jednocześnie da się zaznaczyć tylko jedno pole (R.3.4).
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> </main> <aside> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 21: Blok lewy: nagłówek
ok. 1 min
Polecenie z arkusza
Zawartość bloku lewego: Nagłówek trzeciego stopnia o treści: „Stany na dzień 2022-05-05”
<h3> na początku bloku lewego.
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> </main> <aside> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 22: Tabela: wiersz komórek nagłówkowych
Kryteria:
R.2.7 Pierwszy wiersz tabeli zawiera komórki nagłówkowe o treści: „Wodomierz”, „Rzeka”, „Ostrzegawczy”, „Alarmowy”, „Aktualny”, zastosowano znaczniki <th>
ok. 2 min
Polecenie z arkusza
Tabela zawierająca dane: Pierwszy wiersz wypełniony komórkami nagłówkowymi o treści: „Wodomierz”, „Rzeka”, „Ostrzegawczy”, „Alarmowy”, „Aktualny”
Komórki nagłówkowe to <th> (domyślnie pogrubione i wyśrodkowane), w jednym wierszu <tr>. Pięć kolumn odpowiada pięciu polom zapytania 2: nazwa, rzeka, stan ostrzegawczy, alarmowy i aktualny stan wody. Pozostałe wiersze wypisze skrypt formularza.
poziomRzek.phpPHPzmienione: 9 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr> </table> </main> <aside> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 23: Blok prawy: nagłówek „Informacje”
ok. 1 min
Polecenie z arkusza
Zawartość bloku prawego: Nagłówek trzeciego stopnia o treści: „Informacje”
<h3> na początku bloku prawego.
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr> </table> </main> <aside> <h3>Informacje</h3> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 24: Lista punktowana z trzema informacjami
Kryteria:
R.2.8 W bloku prawym umieszczono jedną listę punktowaną o trzech elementach, zastosowano znaczniki <ul>, <li>
ok. 1 min
Polecenie z arkusza
Lista punktowana (nieuporządkowana) zawierająca elementy: „Brak ostrzeżeń o burzach z gradem”, „Smog w mieście Wrocław”, „Silny wiatr w Karkonoszach”
Lista nieuporządkowana to <ul>, każdy element w <li>.
poziomRzek.phpPHPzmienione: 5 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 25: Nagłówek „Średnie stany wód”
ok. 1 min
Polecenie z arkusza
Nagłówek trzeciego stopnia o treści: „Średnie stany wód”
Drugi <h3> w bloku prawym. Pod nim Skrypt 2 wypisze średnie z zapytania 4.
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 26: Odnośnik „Dowiedz się więcej”
Kryteria:
R.3.2 Odnośnik o treści "Dowiedz się więcej" inicjuje otwarcie strony "https://komunikaty.pl"
ok. 1 min
Polecenie z arkusza
Odnośnik do adresu „https://komunikaty.pl” o treści „Dowiedz się więcej”
Adres zewnętrzny musi zaczynać się od https:// - bez tego przeglądarka szukałaby pliku komunikaty.pl w folderze strony. Między nagłówkiem a odnośnikiem stanie później Skrypt 2 („Efekt działania skryptu 2” w arkuszu).
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 27: Obraz rzeki
Kryteria:
R.2.10 W pierwszym banerze umieszczono obraz mapy z tekstem alternatywnym: „Mapa Polski” oraz w bloku prawym obraz rzeki i tekście alternatywnym „rzeka”
ok. 1 min
Polecenie z arkusza
Obraz o nazwie obraz2.jpg i tekście alternatywnym „rzeka”
Zdjęcie z archiwum pod odnośnikiem. Strona ma teraz oba obrazy z tekstami alternatywnymi (R.2.10).
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 28: Stopka z autorem
Kryteria:
R.2.5 W drugim banerze zapisano nagłówek h1: "Rzeki w województwie dolnośląskim", w bloku lewym h3: "Stany na dzień 2022-05-05", w bloku prawym h3: "Informacje" i "Średnie stany wód" oraz w stopce paragraf z numerem zdającego
ok. 1 min
Polecenie z arkusza
Zawartość stopki: akapit (paragraf) o treści: „Stronę wykonał: ”, dalej wstawiony numer zdającego
Na egzaminie w miejscu imienia i nazwiska wpisuje się numer zdającego, czyli PESEL; w tym rozwiązaniu stoi tam „Bartosz Bryniarski”. Strona ma już wszystkie nagłówki i paragraf stopki z klucza (R.2.5).
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Etap 3: Styl CSS
Kroki 29-40 · po tym etapie masz 30 z 39 kryteriów (pkt)
Domyślne formatowanie wszystkich selektorów: krój czcionki Georgia
Selektor uniwersalny * - krój dostają też przycisk i komórki tabeli.
styl.cssCSSnowy plik
* {font-family: Georgia;}
Podgląd strony po tym kroku (poziomRzek.php)
Krok 30: Oba banery: kolory, wyśrodkowanie, wymiary
Kryteria:
R.4.6 Ustawiono wyrównanie tekstu do środka dla obu banerów
ok. 2 min
Polecenie z arkusza
Wspólne dla obu bloków banera: kolor tła Navy, biały kolor czcionki, wyrównanie tekstu do środka, wysokość 100 px, szerokość 50%
Na stronie są dokładnie dwa znaczniki header i oba mają wyglądać tak samo, więc wystarczy selektor znacznika - identyfikatory map i title nie są tu potrzebne. Mapa ma 100 × 100 pikseli, więc wypełnia wysokość banera, a wyśrodkowanie stawia ją pośrodku lewej połowy strony (obraz 2).
R.4.4 Ustawiono wysokość obu banerów na 100px, bloków lewego i prawego na 550px
ok. 1 min
Polecenie z arkusza
Wspólne dla bloku lewego i prawego: kolor tła Azure, wysokość 550 px
Dwa selektory po przecinku. Ta sama wysokość obu bloków sprawia, że stopka zaczyna się równo pod nimi. Banery mają 100 px, a teraz bloki 550 px (R.4.4).
R.4.2 Ustawiono kolor tła Navy dla obu banerów, menu i stopki, Azure dla bloków lewego i prawego
R.4.3 Ustawiono biały kolor czcionki dla obu bloków banera i stopki, kolor Silver dla klasy formatującej teksty przy polach opcji
ok. 1 min
Polecenie z arkusza
Dla stopki: kolor tła Navy, biały kolor czcionki
Granatowe tło mają teraz oba banery, menu i stopka, a jasne Azure - bloki lewy i prawy (R.4.2). Biały kolor czcionki mają banery i stopka, srebrny - teksty przy polach opcji (R.4.3).
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu (prawidłowo zastosowano właściwości CSS decydujące o układzie strony, np. float i clear albo display flex albo grid)
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: na górze dwa bloki banera, poniżej menu, poniżej bloki: lewy i prawy, na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
Banery (50% + 50%) i bloki lewy z prawym (70% + 30%) płyną w lewo - float: left stawia je parami obok siebie. Menu i stopka zajmują całą szerokość i dostają clear: both: menu zaczyna się dopiero pod banerami (bez tego wjechałoby pod nie, bo pływające bloki nie zajmują miejsca w zwykłym układzie), a stopka - pod blokami lewym i prawym.
R.4.8 Ustawiono dla tabeli: obramowanie 1px solid Navy
R.4.7 Ustawiono marginesy wewnętrzne (padding) dla menu 20px oraz marginesy zewnętrzne (margin) dla klasy formatującej teksty przy polach opcji 50px, dla tabeli - auto
ok. 2 min
Polecenie z arkusza
Dla selektora tabeli: obramowanie linią ciągłą o szerokości 1 px i kolorze Navy, marginesy zewnętrzne automatycznie wyliczane przez przeglądarkę, szerokość 70%
Zgodnie z uwagą arkusza selektor to sam znacznik table - klucz nie uzna szerokości tabeli nadanej klasą (R.4.5). Ramka obejmuje całą tabelę, nie komórki - jak na obrazie 2. margin: auto dzieli wolne miejsce po równo na lewo i prawo, więc tabela szeroka na 70% bloku staje na środku. Marginesy menu, etykiet i tabeli są już ustawione (R.4.7).
R.4.5 Ustawiono szerokość dla obu banerów na 50%, bloku lewego 70%, bloku prawego 30% (width lub grid-template-columns lub flex), selektora table 70%, obrazu w prawym bloku 90%
ok. 1 min
Polecenie z arkusza
Dla obrazu w prawym bloku: szerokość 90%
Selektor potomka aside img - dotyczy tylko zdjęcia rzeki; mapa w banerze zostaje w rozmiarze 100 × 100. Szerokości banerów, bloków, tabeli i obrazu są komplet (R.4.5).
Kroki 41-49 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 41: Połączenie z bazą rzeki
Kryteria:
R.5.1 Skrypt zawiera instrukcje połączenia z serwerem bazy danych i wyboru bazy rzeki
ok. 2 min
Polecenie z arkusza
Skrypty łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie rzeki
Skrypt formularza stoi wewnątrz tabeli, pod wierszem nagłówkowym - to, co wypisze, stanie się kolejnymi wierszami. Jest pierwszy na stronie, więc otwiera połączenie: mysqli_connect z czterema argumentami łączy się z serwerem i wybiera bazę; uchwyt w zmiennej $connection posłuży też Skryptowi 2, który na stronie stoi niżej i zamknie połączenie. Pod nagłówkiem „Średnie stany wód” czeka już pusty blok Skryptu 2. Od tego kroku podgląd to wynik prawdziwego uruchomienia strony po wybraniu „Wszystkie” i kliknięciu „Pokaż”.
poziomRzek.phpPHPzmienione: 5 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 42: Skrypt formularza: po wysłaniu zapytanie 2
Kryteria:
R.5.3 Skrypt skojarzony z formularzem zawiera instrukcje wysyłające do bazy danych zapytanie 2 lub skrypt 2: zapytanie 4
ok. 3 min
Polecenie z arkusza
Skrypt skojarzony z formularzem, po wysłaniu danych z formularza, wyświetla dane w tabeli w zależności od wybranego pola opcji: Wszystkie dane wodomierzy są uzyskane za pomocą zapytania 2 (patrz obraz 2)
„Po wysłaniu danych z formularza” to warunek isset($_POST["option"]): przy pierwszym wejściu na stronę nikt nic nie wysłał i tabela ma sam nagłówek. Wewnątrz zapytanie 2 bez średnika na końcu - za chwilę będzie do niego dopisywany drugi warunek. mysqli_query wysyła je do bazy, wynik czeka w $result. Apostrofy wokół daty siedzą wewnątrz napisu PHP w cudzysłowach, więc nie trzeba ich niczym poprzedzać.
poziomRzek.phpPHPzmienione: 4 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";$result = mysqli_query($connection, $query); }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Krok 43: Skrypt formularza: wiersze z nazwą wodowskazu
ok. 2 min
Polecenie z arkusza
Pozostałe wiersze wypełnione przez skrypt skojarzony z formularzem
mysqli_fetch_row oddaje kolejny wiersz wyniku jako tablicę numerowaną od zera (w kolejności pól z SELECT), a po ostatnim zwraca null i pętla while się kończy. Na razie jedna komórka - widać 17 nazw wodowskazów, od Lubachowa do Ślęży.
poziomRzek.phpPHPzmienione: 3 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td></tr>"; } }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 44: Skrypt formularza: pięć kolumn w każdym wierszu
Kryteria: ,
R.5.4 Skrypt formularza wyświetla w tabeli wyniki działania zapytania zgodnie z obrazem 2 arkusza egzaminacyjnego
R.2.6 W bloku lewym umieszczono tabelę o 5 kolumnach, zastosowano znaczniki <table>, <tr>, <td> (tabelę wygenerowano skryptem lub w HTML)
ok. 2 min
Polecenie z arkusza
Wszystkie dane wodomierzy są uzyskane za pomocą zapytania 2 (patrz obraz 2)
Pozostałe komórki: rzeka, stan ostrzegawczy, alarmowy i aktualny. Podgląd wygląda jak blok lewy na obrazie 2 - 17 wierszy w kolejności zapytania 2 (R.5.4), a tabela ma pięć kolumn ze znaczników table, tr i td (R.2.6).
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 45: Skrypt formularza: ponad stan ostrzegawczy
Kryteria:
R.5.5 Gdy w formularzu wybrano "Ponad stan ostrzegawczy" i zatwierdzono, są wyświetlone tylko te rekordy, dla których stan aktualny jest wyższy niż ostrzegawczy
ok. 2 min
Polecenie z arkusza
Dane wodomierzy z przekroczonym stanem ostrzegawczym są uzyskane za pomocą zapytania 3 lub alternatywnie za pomocą zapytania 2 i odpowiednio przygotowanego warunku (patrz obraz 3)
Zapytanie 3 to zapytanie 2 z dopisanym warunkiem, więc zamiast przepisywać je drugi raz, wystarczy dokleić warunek operatorem . (łączenie napisów w PHP). Spacja na początku dopisku jest konieczna - bez niej powstałoby '2022-05-05'AND. Podgląd pokazuje stronę po wybraniu „Ponad stan ostrzegawczy”: 5 wierszy, jak na obrazie 3.
poziomRzek.phpPHPzmienione: 3 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";if ($_POST["option"] == "warning") {$query = $query . " AND stanWody > stanOstrzegawczy"; }$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 46: Skrypt formularza: ponad stan alarmowy
Kryteria:
R.5.6 Gdy w formularzu wybrano "Ponad stan alarmowy" i zatwierdzono, są wyświetlone tylko te rekordy, dla których stan aktualny jest wyższy niż alarmowy
ok. 2 min
Polecenie z arkusza
Dane wodomierzy z przekroczonym stanem alarmowym są uzyskane za pomocą zmodyfikowanego zapytania 3 lub alternatywnie za pomocą zapytania 2 i odpowiednio przygotowanego warunku (patrz obraz 4)
Druga gałąź elseif dokleja warunek ze stanem alarmowym. Dla wartości all żaden warunek nie pasuje i zostaje samo zapytanie 2. Podgląd po wybraniu „Ponad stan alarmowy”: tylko Łazany (300 przy stanie alarmowym 240), jak na obrazie 4.
poziomRzek.phpPHPzmienione: 2 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";if ($_POST["option"] == "warning") {$query = $query . " AND stanWody > stanOstrzegawczy"; } elseif ($_POST["option"] == "alarm") {$query = $query . " AND stanWody > stanAlarmowy"; }$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 47: Skrypt 2: zapytanie 4
ok. 1 min
Polecenie z arkusza
Wysyła do bazy danych zapytanie 4
Skrypt 2 korzysta z połączenia otwartego w skrypcie formularza. Zmienne $query i $result są użyte ponownie - tabela jest już wypisana.
poziomRzek.phpPHPzmienione: 2 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";if ($_POST["option"] == "warning") {$query = $query . " AND stanWody > stanOstrzegawczy"; } elseif ($_POST["option"] == "alarm") {$query = $query . " AND stanWody > stanAlarmowy"; }$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php$query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";$result = mysqli_query($connection, $query);?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 48: Skrypt 2: paragraf „data: średnia” dla każdego dnia
Kryteria:
R.5.7 W skrypcie 2 jest wyświetlany każdy zwrócony zapytaniem wiersz o treści: „<data>: <średnia>”, gdzie dane zapisane w <> są pobierane z bazy danych
ok. 2 min
Polecenie z arkusza
Każdy zwrócony zapytaniem wiersz jest wyświetlany w paragrafie o treści: „<data>: <średnia>”, gdzie dane zapisane w <> są pobierane z bazy danych
Każdy wiersz zapytania 4 to jeden <p> z datą, dwukropkiem i średnią. Podgląd: „2022-05-05: 167.6471” i „2022-05-06: 179.5882” - jak na obrazie 2. Ten skrypt wypisuje się zawsze, niezależnie od formularza.
poziomRzek.phpPHPzmienione: 3 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";if ($_POST["option"] == "warning") {$query = $query . " AND stanWody > stanOstrzegawczy"; } elseif ($_POST["option"] == "alarm") {$query = $query . " AND stanWody > stanAlarmowy"; }$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php$query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<p>$row[0]: $row[1]</p>"; }?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 49: Zamknięcie połączenia na końcu
Kryteria: ,
R.5.2 Ostatnią operacją na bazie jest jej zamknięcie
R.5.8 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych lub funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania
ok. 1 min
Polecenie z arkusza
Na końcu jest zamykane połączenie z serwerem.
Skrypt 2 jest ostatnim blokiem PHP na stronie, więc tu stoi mysqli_close - ostatnia operacja na bazie (R.5.2). Wszystkie zmienne mają nazwy mówiące, co przechowują ($connection, $query, $result, $row) - to kryterium R.5.8.
poziomRzek.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");if (isset($_POST["option"])) {$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";if ($_POST["option"] == "warning") {$query = $query . " AND stanWody > stanOstrzegawczy"; } elseif ($_POST["option"] == "alarm") {$query = $query . " AND stanWody > stanAlarmowy"; }$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } }?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php$query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<p>$row[0]: $row[1]</p>"; } mysqli_close($connection);?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Kroki 50-52 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 50: Tablica warunków i wszystkie wodowskazy od pierwszego wejścia
ok. 3 min
Polecenie z arkusza
Skrypt skojarzony z formularzem, po wysłaniu danych z formularza, wyświetla dane w tabeli w zależności od wybranego pola opcji: Wszystkie dane wodomierzy są uzyskane za pomocą zapytania 2 (patrz obraz 2)
Wersja egzaminacyjna przy pierwszym wejściu pokazuje pustą tabelę - użytkownik musi najpierw kliknąć „Pokaż”. Arkusz tego nie zabrania, ale stany wody są najważniejszą treścią strony. Operator ?? przyjmuje all, gdy formularza jeszcze nie wysłano. Drabinkę if/elseif zastępuje tablica warunków: klucz to wartość pola opcji, wartość - dopisek do zapytania. Wartość spoza tablicy (np. xyz wysłane z pominięciem formularza) też daje all - do zapytania trafia tylko tekst z tablicy, nigdy tekst od użytkownika. Dodanie czwartej opcji to jedna linia w tablicy. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
poziomRzek.phpPHPzmienione: 16 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");$conditions = ["all" => "","warning" => " AND stanWody > stanOstrzegawczy","alarm" => " AND stanWody > stanAlarmowy" ];$option = $_POST["option"] ?? "all";if (!isset($conditions[$option])) {$option = "all"; }$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'" . $conditions[$option];$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; }/* Wersja z egzaminu: if (isset($_POST["option"])) { $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'"; if ($_POST["option"] == "warning") { $query = $query . " AND stanWody > stanOstrzegawczy"; } elseif ($_POST["option"] == "alarm") { $query = $query . " AND stanWody > stanAlarmowy"; } $result = mysqli_query($connection, $query); while ($row = mysqli_fetch_row($result)) { echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } } */?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php$query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<p>$row[0]: $row[1]</p>"; } mysqli_close($connection);?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Obok siebie 3 pola opcji (radio) zgrupowane, tak aby było możliwe jednoczesne wybranie tylko jednego pola. Etykiety przy polach opcji: „Wszystkie”, „Ponad stan ostrzegawczy”, „Ponad stan alarmowy” (pola opcji będą formatowane jedną klasą CSS)
Na obrazach 3 i 4 po wysłaniu formularza zaznaczone jest pole, które wybrano - w wersji egzaminacyjnej strona ładuje się od nowa i wszystkie pola są puste, więc nie widać, który filtr działa. Krótki PHP w każdym polu dopisuje atrybut checked, gdy wartość pola zgadza się z wyborem. Formularz stoi na stronie przed skryptem z tablicą warunków, dlatego linia z $option przenosi się ze skryptu do osobnego bloku PHP na samym początku pliku (przed <!DOCTYPE html> - blok niczego nie wypisuje, więc dokument zaczyna się poprawnie); sprawdzenie w tablicy warunków zostaje w skrypcie. Podgląd: po wybraniu „Ponad stan ostrzegawczy” to pole zostaje zaznaczone, a w tabeli jest 5 wierszy. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
poziomRzek.phpPHPzmienione: 6 linii
<?php$option = $_POST["option"] ?? "all";?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"<?phpif ($option == "all") echo"checked"; ?>> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"<?phpif ($option == "warning") echo"checked"; ?>> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"<?phpif ($option == "alarm") echo"checked"; ?>> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");$conditions = ["all" => "","warning" => " AND stanWody > stanOstrzegawczy","alarm" => " AND stanWody > stanAlarmowy" ];if (!isset($conditions[$option])) {$option = "all"; }$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'" . $conditions[$option];$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; }/* Wersja z egzaminu: if (isset($_POST["option"])) { $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'"; if ($_POST["option"] == "warning") { $query = $query . " AND stanWody > stanOstrzegawczy"; } elseif ($_POST["option"] == "alarm") { $query = $query . " AND stanWody > stanAlarmowy"; } $result = mysqli_query($connection, $query); while ($row = mysqli_fetch_row($result)) { echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } } */?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php$query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<p>$row[0]: $row[1]</p>"; } mysqli_close($connection);?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Krok 52: Komórki w pętli, htmlspecialchars i średnie z dwoma miejscami po przecinku
ok. 3 min
Polecenie z arkusza
Każdy zwrócony zapytaniem wiersz jest wyświetlany w paragrafie o treści: „<data>: <średnia>”, gdzie dane zapisane w <> są pobierane z bazy danych
Trzy poprawki wyświetlania. Pięć komórek wypisuje pętla foreach po wartościach wiersza - zmiana liczby kolumn w zapytaniu nie wymaga zmian w echo. Każda wartość przechodzi przez htmlspecialchars, więc nazwa z < albo & w bazie nie rozbije tabeli. Średnia „167.6471” ma cztery miejsca po przecinku i kropkę dziesiętną - number_format zaokrągla ją do dwóch miejsc z polskim przecinkiem („167,65”). Dopisek „cm” to założenie tego rozwiązania: stany wody na wodowskazach podaje się w centymetrach, ale baza i arkusz jednostki nie podają - w razie wątpliwości lepiej go pominąć. Na egzaminie wystarczy wersja wcześniejsza - klucz sprawdza średnią z bazy „z dowolną dokładnością”, ale bez dopisków.
poziomRzek.phpPHPzmienione: 6 linii
<?php$option = $_POST["option"] ?? "all";?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Poziomy rzek</title> <linkrel="stylesheet"href="styl.css"></head><body> <headerid="map"> <imgsrc="obraz1.png"alt="Mapa Polski"> </header> <headerid="title"> <h1>Rzeki w województwie dolnośląskim</h1> </header> <nav> <formmethod="post"> <inputtype="radio"id="all"name="option"value="all"<?phpif ($option == "all") echo"checked"; ?>> <labelfor="all"class="radio-label">Wszystkie</label> <inputtype="radio"id="warning"name="option"value="warning"<?phpif ($option == "warning") echo"checked"; ?>> <labelfor="warning"class="radio-label">Ponad stan ostrzegawczy</label> <inputtype="radio"id="alarm"name="option"value="alarm"<?phpif ($option == "alarm") echo"checked"; ?>> <labelfor="alarm"class="radio-label">Ponad stan alarmowy</label> <button>Pokaż</button> </form> </nav> <main> <h3>Stany na dzień 2022-05-05</h3> <table> <tr> <th>Wodomierz</th> <th>Rzeka</th> <th>Ostrzegawczy</th> <th>Alarmowy</th> <th>Aktualny</th> </tr><?php$connection = mysqli_connect("localhost", "root", "", "rzeki");$conditions = ["all" => "","warning" => " AND stanWody > stanOstrzegawczy","alarm" => " AND stanWody > stanAlarmowy" ];if (!isset($conditions[$option])) {$option = "all"; }$query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'" . $conditions[$option];$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<tr>";foreach ($rowas$value) {echo"<td>" . htmlspecialchars($value) . "</td>"; }echo"</tr>"; }/* Wersja z egzaminu: if (isset($_POST["option"])) { $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'"; if ($_POST["option"] == "warning") { $query = $query . " AND stanWody > stanOstrzegawczy"; } elseif ($_POST["option"] == "alarm") { $query = $query . " AND stanWody > stanAlarmowy"; } $result = mysqli_query($connection, $query); while ($row = mysqli_fetch_row($result)) { echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>"; } } */?> </table> </main> <aside> <h3>Informacje</h3> <ul> <li>Brak ostrzeżeń o burzach z gradem</li> <li>Smog w mieście Wrocław</li> <li>Silny wiatr w Karkonoszach</li> </ul> <h3>Średnie stany wód</h3><?php$query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";$result = mysqli_query($connection, $query);while ($row = mysqli_fetch_row($result)) {echo"<p>$row[0]: " . number_format($row[1], 2, ",", "") . " cm</p>"; // było: "<p>$row[0]: $row[1]</p>" } mysqli_close($connection);?> <ahref="https://komunikaty.pl">Dowiedz się więcej</a> <imgsrc="obraz2.jpg"alt="rzeka"> </aside> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (poziomRzek.php)
Etap 6: Oddanie pracy
Krok 53 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 53: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt wystarczy nazwa przeglądarki, w której była sprawdzana strona.
W folderze z numerem zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, obraz1.png (po obróbce), obraz2.jpg, poziomRzek.php, przeglądarka.txt, styl.css i rozpakowany baza.sql. Po nagraniu płyty trzeba sprawdzić jej odczyt i opisać ją numerem zdającego.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.
Autor rozwiązania: Bartosz Bryniarski. Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.