INF.03-03-22.06-SGCzerwiec 2022 · 37 kroków · ok. 77 min · 35 kryteriów z klucza
Rozwiązanie krok po kroku: Portal zawodów wędkarskich (Nowoczesny kod (grid, PDO))
To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza wedkarstwo z czterema zapytaniami, odbite i przeskalowane zdjęcie, strona zawody.html z formularzem i skrypt zgloszenie.php, który dopisuje zawody do bazy - i tak samo spełnia każde kryterium klucza. Inna jest droga:
dwie siatki CSS zamiast float: bloki lewy i prawy stoją w znaczniku <header> z kolumnami 75% i 25%, a dwa bloki stopki w <footer> z kolumnami 50% i 50% - klucz wprost dopuszcza szerokości w grid-template-columns, a blok główny nie potrzebuje clear,
zmienne CSS dla kolorów z arkusza, wiersze formularza w blokach <div> zamiast <br>, przyciski <button>,
skrypt na PDO: dane z formularza są sprawdzane (łowisko musi istnieć w tabeli lowisko, data musi być prawdziwa, sędzia wpisany), a do bazy trafiają zapytaniem przygotowanym,
skrypt wypisuje wynik (arkusz tego nie wymaga, a pusta strona nic nie mówi użytkownikowi) przez funkcję e() (htmlspecialchars) i stosuje wzorzec PRG - odświeżenie strony nie dodaje zawodów drugi raz,
zapytania z listą kolumn w INSERT i aliasami tabel w złączeniu.
Na końcu krótkie porównanie z wersją podstawową (zakładka obok). Baza i zdjęcie pochodzą z prawdziwego archiwum pliki3.zip, a podgląd skryptu to wynik prawdziwego uruchomienia kodu w PHP na bazie z arkusza.
Jak liczą się punkty. Klucz ma 35 kryteriów (R.1.1 - R.5.5), każde za 1 punkt. Próg zdania to 75%, czyli 27 punktów. Przy każdym kroku jest napisane, które kryteria spełnia.
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 35 kryteriów (pkt)
Krok 1: Baza danych wedkarstwo
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie wedkarstwo
Rozpakuj pliki3.zip z pulpitu (hasło ZaWodY7% - wielkość liter ma znaczenie, na końcu znak procentu) do folderu z numerem zdającego: baza.sql i zawody.jpg. W phpMyAdmin Nowa → wedkarstwo albo zapytaniem:
CREATE DATABASE wedkarstwo CHARACTER SET utf8mb4 COLLATE utf8mb4_polish_ci;
Arkusz nie podaje porównywania, więc wybór należy do Ciebie. Tabele z baza.sql mają zestaw znaków (latin1) zapisany we własnej definicji, więc ustawienie bazy ich nie zmienia - ma to skutek przy zapisie z formularza (krok z zapytaniem w skrypcie).
Typowe błędy
Nazwa bazy musi brzmieć dokładnie wedkarstwo - skrypt łączy się z bazą po nazwie (R.5.1).
Krok 2: Import tabel z pliku baza.sql
ok. 2 min
Polecenie z arkusza
Do bazy wedkarstwo zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum
Przy zaznaczonej bazie wedkarstwo: Import → baza.sql → Wykonaj. Zadanie korzysta z trzech tabel z obrazu 1: zawody_wedkarskie (zawody: zwycięzca Karty_wedkarskie_id, łowisko Lowisko_id, data, sędzia), karty_wedkarskie (wędkarze) i lowisko (rodzaj: 1 morze, 2 jezioro, 3 rzeka, 4 zalew, 5 staw).
Krok 3: Zrzut ekranu import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych wedkarstwo 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, cały ekran z paskiem zadań, 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: nowe zawody (INSERT)
Kryteria: ,
R.1.2 Zapisano plik o nazwie kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Utworzono zapytanie 1 dodające rekord do tabeli zawody_wedkarskie o wartościach: klucz główny nadawany automatycznie, 2, 4, „2021-09-28”, Andrzej Nowak. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO zawody_wedkarskie VALUES (NULL, '2', '4', '2021-09- 28', 'Andrzej Nowak');(możliwe różne warianty INSERT INTO) oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnym dodaniu rekordu lub tabela z dodanym rekordem
ok. 3 min
Polecenie z arkusza
Zapytanie 1: wstawiające rekord do tabeli zawody_wedkarskie o wartościach: klucz główny nadawany automatycznie, Karty_wedkarskie_id - 2; Lowisko_id - 4; data_zawodow - „2021-09-28”; sedzia – Andrzej Nowak
INSERT INTO z jawną listą kolumn: po nazwie tabeli cztery kolumny, po VALUES wartości w tej samej kolejności. Kolumny id nie ma na liście - ma AUTO_INCREMENT, więc baza nada jej następny numer sama (tu 5). Lista kolumn sprawia, że zapytanie nie zależy od kolejności kolumn w tabeli i od razu widać, która liczba trafia gdzie. Liczby bez apostrofów, data i tekst w apostrofach. Klucz uznaje „różne warianty INSERT INTO”. Zapytanie do kwerendy.txt, zrzut kw1.jpg.
Krok 5: Zapytanie 2: zawody sędziego Krzysztofa Dobrowolskiego
Kryteria:
R.1.4 Utworzono zapytanie 2 wybierające jedynie pola id oraz data_zawodow z tabeli zawody_wedkarskie dla sędziego Krzysztofa Dobrowolskiego . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, data_zawodow FROM zawody_wedkarskie WHERE sedzia = 'Krzysztof Dobrowolski'; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest tylko jeden rekord: 4, 2018-06-21
ok. 1 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola id oraz data_zawodow z tabeli zawody_wedkarskie dla sędziego Krzysztofa Dobrowolskiego
W bazie imię i nazwisko sędziego są w jednym polu, w mianowniku: sedzia = 'Krzysztof Dobrowolski'. Wynik (sprawdzony na bazie z archiwum): jeden wiersz 4, 2018-06-21 - jak w kluczu. Zrzut kw2.jpg.
R.1.5 Utworzono zapytanie 3 wybierające jedynie pola imię, nazwisko i punkty z tabeli karty_wedkarskie dla zwycięzcy zawodów wędkarskich o identyfikatorze zawody_wedkarskie.id=4. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, punkty FROM karty_wedkarskie JOIN zawody_wedkarskie ON karty_wedkarskie.id = zawody_wedkarskie.Karty_wedkarskie_id WHERE zawody_wedkarskie.id = 4; (możliwe też INNER JOIN lub przyrównanie kluczy w WHERE) oraz wynik działania udokumentowano zrzutem, na którym widoczny jest tylko jeden rekord z danymi: Andrzej Nowak, 3
ok. 3 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola imie, nazwisko i punkty z tabeli karty_wedkarskie dla zwycięzcy zawodów wędkarskich o identyfikatorze 4 (identyfikator dotyczy zawodów, a nie wędkarza), należy użyć relacji
aliasy tabelk (karty) i z (zawody) - obie tabele mają kolumnę id, a przedrostek mówi wprost, o które id chodzi,
JOIN ... ON z.Karty_wedkarskie_id = k.id - relacja z obrazu 1: zawody wskazują swojego zwycięzcę,
WHERE z.id = 4 - numer zawodów, nie wędkarza (przed tym ostrzega nawias w arkuszu).
Wynik: Andrzej Nowak 3 - jak w kluczu. Zrzut kw3.jpg.
Typowe błędy
WHERE k.id = 4 (numer wędkarza) daje pusty wynik - w bazie są tylko dwaj wędkarze.
kwerendy.txtTekstzmienione: 6 linii
-- Zapytanie 1INSERT INTO zawody_wedkarskie (Karty_wedkarskie_id, Lowisko_id, data_zawodow, sedzia)VALUES (2, 4, '2021-09-28', 'Andrzej Nowak');-- Zapytanie 2SELECT id, data_zawodowFROM zawody_wedkarskieWHERE sedzia = 'Krzysztof Dobrowolski';-- Zapytanie 3SELECT k.imie, k.nazwisko, k.punktyFROM karty_wedkarskie AS kJOIN zawody_wedkarskie AS z ON z.Karty_wedkarskie_id = k.idWHERE z.id = 4;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: dwa punkty więcej dla wędkarza numer 1
Kryteria:
R.1.6 Utworzono zapytanie 4 aktualizujące dane w tabeli karty_wedkarskie , wartość pola punkty jedynie dla rekordu o identyfikatorze 1 należy zwiększyć o 2. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE karty_wedkarskie SET punkty = punkty + 2 WHERE karty_wedkarskie.id = 1; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnej aktualizacji lub tabela ze zmienioną wartością
ok. 2 min
Polecenie z arkusza
Zapytanie 4: aktualizujące dane w tabeli karty_wedkarskie, wartość pola punkty dla rekordu o identyfikatorze 1 należy zwiększyć o 2
SET punkty = punkty + 2 - nowa wartość liczona ze starej, nie trzeba znać aktualnej liczby punktów; WHERE id = 1 - tylko Jan Kowalski. Miał 23 punkty, po zapytaniu ma 25. Zrzut kw4.jpg: komunikat i tabela po zmianie.
Typowe błędy
SET punkty = 25 daje dziś ten sam wynik, ale nie jest „zwiększeniem o 2” - klucz wymaga zapytania uniwersalnego.
kwerendy.txtTekstzmienione: 5 linii
-- Zapytanie 1INSERT INTO zawody_wedkarskie (Karty_wedkarskie_id, Lowisko_id, data_zawodow, sedzia)VALUES (2, 4, '2021-09-28', 'Andrzej Nowak');-- Zapytanie 2SELECT id, data_zawodowFROM zawody_wedkarskieWHERE sedzia = 'Krzysztof Dobrowolski';-- Zapytanie 3SELECT k.imie, k.nazwisko, k.punktyFROM karty_wedkarskie AS kJOIN zawody_wedkarskie AS z ON z.Karty_wedkarskie_id = k.idWHERE z.id = 4;-- Zapytanie 4UPDATE karty_wedkarskieSET punkty = punkty + 2WHERE id = 1;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-22 · po tym etapie masz 19 z 35 kryteriów (pkt)
Krok 8: Zdjęcie zawody.jpg: odbicie i wysokość 250 px
Kryteria:
R.2.1 Grafikę z pliku o nazwie zawody.jpg odbito w taki sposób, aby osoba na grafice znajdowała się po prawej stronie jak na obrazie 2 oraz przeskalowano z zachowaniem proporcji do wysokości 250 px. Odpowiadająca temu szerokość wynosi 251 px (± 2 px)
ok. 3 min
Polecenie z arkusza
Plik zawody.jpg, wypakowany z archiwum, należy odbić w taki sposób, aby osoba na grafice znajdowała się po prawej stronie, jak na obrazie 2 oraz przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 250 px i zapisać pod tą samą nazwą
Grafika jest taka sama jak w wersji podstawowej. W GIMP-ie Obraz → Przekształć → Odbij poziomo (wędkarz przechodzi na prawą stronę) i Obraz → Skaluj obraz z zamkniętym łańcuchem proporcji, wysokość 250 px - szerokość wyjdzie 251 px (415 × 413 px na wejściu), jak w kluczu (±2 px). Na koniec Plik → Nadpisz zawody.jpg.
Typowe błędy
Odbij pionowo stawia wędkarza do góry nogami - potrzebne jest odbicie w poziomie.
Podgląd strony po tym kroku
Krok 9: Plik zawody.html: HTML5, język, kodowanie
Kryteria:
R.2.2 Witrynę internetową zapisano w pliku o nazwie zawody.html oraz zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> oraz zadeklarowano dla witryny język polski
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie zawody.html zapisanej w języku HTML 5 oraz skryptu zgloszenie.php. Poniższe wymagania dotyczą tylko pliku zawody.html. Zadeklarowany język dla witryny: polski. Jawnie zastosowany właściwy standard kodowania polskich znaków
<!DOCTYPE html>, <html lang="pl"> i <meta charset="UTF-8"> jako pierwszy element <head> (R.2.2). Strona nie ma kodu PHP, więc ma rozszerzenie .html. Formularz zadziała tylko wtedy, gdy strona jest otwarta przez serwer XAMPP (http://localhost/...) - inaczej po wysłaniu przeglądarka pokaże kod PHP zamiast go wykonać.
R.3.6 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl3.css , formatowanie 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 styl3.css prawidłowo połączony z kodem strony
Nazwa pliku: styl3.css - z cyfrą 3. Całe formatowanie pochodzi z tego pliku, bez atrybutów style (R.3.6).
Typowe błędy
Klucz odbiera R.3.6 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast #).
Krok 12: Bloki: lewy i prawy w header, główny, dwie stopki w footer
Kryteria:
R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: lewy, prawy, główny i dwa bloki stopki. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: na górze dwa bloki: lewy i prawy, poniżej blok główny, na dole dwa bloki stopki. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
Strona ma trzy pasy, więc trzy główne znaczniki:
<header> - górny pas, a w nim dwa bloki <section>: lewy #title (nazwa portalu) i prawy #photo (zdjęcie),
<main> - blok główny z listą łowisk i formularzem,
<footer> - dolny pas, a w nim dwa bloki stopki: #downloads (odnośnik do kwerend) i #author (autor strony).
Pary bloków stoją we wspólnym rodzicu, więc w CSS każdy pas dostanie własną siatkę z kolumnami - bez float i clear. Wszystkie bloki to znaczniki sekcji HTML5 (R.2.4).
R.2.6 W bloku głównym umieszczono listę punktową z czterema elementami, zastosowano znaczniki <ul>, <li>
ok. 2 min
Polecenie z arkusza
Zawartość bloku głównego: Nagłówek trzeciego stopnia o treści: „Łowiska”. Lista punktowana (nieuporządkowana) zawierająca elementy: Zalew Węgrowski, Zbiornik Bukówka, Jeziorko Bartbetowskie, Warta-Obrzycko
<h3> - stopień nagłówka bierzesz z arkusza, nie z hierarchii strony. Lista punktowana to <ul> z czterema <li> (R.2.6); nazwy z polskimi literami, tak jak w arkuszu (w tabeli lowisko są zapisane bez nich).
Krok 16: Blok główny: formularz POST do zgloszenie.php
Kryteria:
R.3.5 Formularz wysyła dane metodą POST do skryptu zgloszenie.php
ok. 2 min
Polecenie z arkusza
Nagłówek trzeciego stopnia o treści: „Dodaj zawody wędkarskie”. Formularz wysyłający dane metodą bezpieczną do pliku zgloszenie.php zawierający pola
Drugi <h3> i <form> z action="zgloszenie.php" (dokąd trafią dane) i method="post" (R.3.5) - dane idą w treści żądania, a nie w adresie strony.
⚠️ Rozbieżność arkusz-klucz: arkusz każe wysyłać dane „metodą bezpieczną”, a w specyfikacji HTTP (RFC 9110) metody bezpieczne (safe) to GET i HEAD - te, które nie zmieniają danych na serwerze. Klucz CKE (R.3.5) wymaga POST - na egzaminie punkt daje wersja z klucza. Tu POST jest zresztą właściwy także według HTTP: formularz dopisuje dane do bazy.
Typowe błędy
Formularz bez method wysyła dane metodą GET - skrypt czytający $_POST niczego nie dostanie, a R.3.5 nie jest spełnione.
Pole edycyjne typu numerycznego poprzedzone tekstem: „Łowisko: ”
Napis w <label> przed polem, para we własnym bloku <div> - kolejne pole zacznie się od nowej linii bez <br>. <input type="number"> z name="fishery" - pod tą nazwą wartość trafi do $_POST. min="1" i required - przeglądarka nie wyśle pustego pola ani zera. To wygoda dla użytkownika, nie zabezpieczenie: skrypt i tak sprawdzi, czy takie łowisko istnieje.
R.3.3 Jedno pole edycyjne jest typu numerycznego, drugie typu date
ok. 1 min
Polecenie z arkusza
Pole edycyjne umożliwiające wybranie daty z kalendarza, poprzedzone tekstem: „Data: ”
<input type="date"> - przeglądarka pokazuje kalendarz. Na ekranie data ma format zależny od języka systemu (np. dd.mm.rrrr), ale do skryptu zawsze trafia jako 2021-10-02 - tak, jak potrzebuje pole DATE w bazie. Pole liczbowe i pole daty są gotowe (R.3.3).
R.2.8 W bloku głównym umieszczono formularz z trzema polami edycyjnymi i dwoma przyciskami, zastosowano znacznik <form>
R.3.4 Jeden przycisk czyści dane formularza, drugi wysyła dane do skryptu (input lub button z typem submit lub button bez typu)
ok. 2 min
Polecenie z arkusza
Przycisk czyszczący zawartość formularza z etykietą „CZYŚĆ”. Przycisk wysyłający zawartość formularza z etykietą „DODAJ”
Działanie przycisku zależy od typu: type="reset" przywraca pola do stanu początkowego bez żadnego skryptu, type="submit" wysyła formularz pod adres z action (R.3.4). Znacznik <button> ma napis między znacznikami, a nie w atrybucie value - w środku może stać też np. ikona. Formularz ma trzy pola i dwa przyciski (R.2.8).
R.2.5 W bloku lewym zapisano nagłówek h1: „Zawody polskich wędkarzy”, w bloku głównym dwa h3: „Łowiska” i „Dodaj zawody wędkarskie” oraz w drugiej stopce akapit o treści "Stronę przygotował:" z numerem zdającego
ok. 1 min
Polecenie z arkusza
Zawartość drugiego bloku stopki: akapit (paragraf) o treści: „Stronę przygotował: ”, dalej wstawiony numer zdającego, którym został podpisany arkusz.
Akapit <p> w drugim bloku stopki. Na egzaminie wpisujesz numer, którym podpisany jest arkusz (PESEL); tu stoi autor rozwiązania - „Bartosz Bryniarski”. Strona ma już <h1>, dwa <h3> i akapit w drugiej stopce (R.2.5).
Kroki 23-30 · po tym etapie masz 30 z 35 kryteriów (pkt)
Krok 23: Plik styl3.css: zmienne i krój czcionki
Kryteria:
R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (*): krój czcionki Verdana (w przypadku wymienionych kilku czcionek Verdana jest wymieniona jako pierwsza)
ok. 2 min
Polecenie z arkusza
Domyślne formatowanie wszystkich selektorów: krój czcionki Verdana
Dwa kolory z arkusza w zmiennych - SeaGreen pojawi się w trzech regułach (bloki górne, stopki, odnośnik), MintCream w dwóch. Selektor uniwersalny * z Verdaną na pierwszym miejscu (R.4.1) - krój dostają wszystkie elementy, także pola i przyciski formularza; sans-serif to krój zapasowy.
Wspólne dla bloku lewego i prawego: kolor tła SeaGreen, biały kolor czcionki, interlinia 150 px, wysokość 260 px, rozmiar czcionki 160%. Dodatkowo dla bloku lewego: szerokość 75%. Dodatkowo dla bloku prawego: szerokość 25%, wyrównanie tekstu do prawej strony
Wspólna reguła dla obu bloków i osobna dla prawego. Interlinia to line-height - przy 150 px nagłówek stoi wyraźnie niżej niż przy górnej krawędzi, jak na obrazie 2. text-align: right działa też na obraz, bo <img> jest elementem liniowym - zdjęcie dosuwa się do prawej krawędzi.
Szerokości 75% i 25% tu nie ma: w siatce procent przy bloku liczyłby się od jego kolumny, więc trafią do definicji kolumn siatki - klucz R.4.4 wprost to dopuszcza.
R.4.5 Ustawiono wysokość dla bloku lewego i prawego 260px oraz dla obu bloków stopki 70px
R.4.8 Ustawiono wyrównanie tekstu do prawej strony dla bloku prawego, do środka dla obu bloków stopki oraz ustawiono rozmiar czcionki 160% dla bloków lewego i prawego
ok. 1 min
Polecenie z arkusza
Wspólne dla obu stopek: kolor tła SeaGreen, biały kolor czcionki, szerokość 50%, wysokość 70 px, wyrównanie tekstu do środka
Jedna reguła dla obu bloków stopki; szerokość 50%, jak przy blokach górnych, w kolumnach siatki. Ustawione są już wysokości (R.4.5) oraz wyrównania tekstu z rozmiarem czcionki (R.4.8).
Dla selektora kontrolki (przyciski i pola edycyjne): margines zewnętrzny dolny 20 px
Pola są znacznikami input, a przyciski - button, więc reguła ma dwa selektory znaczników (uwaga arkusza wyklucza klasy). Margines zewnętrzny dolny to margin-bottom.
Typowe błędy
Sam selektor input nie obejmie przycisków <button> - wersja podstawowa ma przyciski <input type="reset"> i <input type="submit">, więc tam jeden selektor wystarcza.
R.4.9 Ustawiono cień dla selektora img o wartości box-shadow: 15px 15px 10px DimGray
ok. 1 min
Polecenie z arkusza
Dla selektora obrazu: cień o przesunięciu 15 px w obu osiach, rozmyciu 10 px i kolorze DimGray
box-shadow w kolejności ze składni podanej w arkuszu: przesunięcie poziome, pionowe, rozmycie, kolor. Dodatnie przesunięcia kładą cień w prawo i w dół. Selektor znacznika img (R.4.9).
R.4.2 Ustawiono kolor tła SeaGreen dla bloków lewego, prawego i obu bloków stopki oraz MintCream dla bloku głównego i selektora a
R.4.3 Ustawiono biały kolor czcionki dla bloków lewego, prawego i obu bloków stopki oraz SeaGreen dla odnośnika
R.4.6 Ustawiono interlinię dla bloku lewego i prawego: 150px oraz 70px dla odnośnika
R.4.7 Ustawiono marginesy wewnętrzne (padding) 80px dla bloku głównego, 15px dla odnośnika oraz ustawiono margin-bottom: 20px dla wszystkich kontrolek
R.4.10 Ustawiono brak podkreślenia dla odnośnika
ok. 2 min
Polecenie z arkusza
Dla selektora odnośnika: brak podkreślenia, kolor tła MintCream, kolor czcionki SeaGreen, marginesy wewnętrzne 15 px, interlinia 70 px
Selektor znacznika a. Brak podkreślenia to text-decoration: none. Interlinia 70 px równa wysokości stopki stawia napis w pionie na środku, a jasne tło z marginesem wewnętrznym robi z odnośnika „przycisk”, jak na obrazie 2. Ustawione są już wszystkie kolory (R.4.2, R.4.3), interlinie (R.4.6), marginesy (R.4.7) i brak podkreślenia (R.4.10).
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 układające bloki na stronie, np. float i clear albo display flex albo grid)
R.4.4 Ustawiono szerokość bloku lewego 75%, prawego 25%, obu bloków stopki 50% (width lub grid-template-columns lub flex)
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: na górze dwa bloki: lewy i prawy, poniżej blok główny, na dole dwa bloki stopki. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
display: grid na <header> i <footer> - każdy pas układa swoje dwa bloki w kolumny,
grid-template-columns: 75% 25% w nagłówku i 50% 50% w stopce - szerokości z arkusza (R.4.4).
<main> jest zwykłym blokiem między dwoma pasami, więc stoi pod blokami górnymi sam z siebie - bez float nie ma clear, a margines wewnętrzny 80 px liczy się od dolnej krawędzi bloków górnych, jak na obrazie 2 (R.3.1).
Typowe błędy
width: 75% przy bloku w siatce liczy się od kolumny: blok miałby 75% z 75% strony - szerokości podaje się w grid-template-columns.
Kroki 31-35 · po tym etapie masz 35 z 35 kryteriów (pkt)
Krok 31: Plik zgloszenie.php: połączenie z bazą i zamknięcie
Kryteria: ,
R.5.1 Skrypt zawiera działające połączenie z serwerem bazy danych i wybór bazy wedkarstwo
R.5.2 Ostatnią operacją na bazie jest jej zamknięcie (zgodne ze składnią)
ok. 4 min
Polecenie z arkusza
Wymagania dotyczące skryptu: Napisany w języku PHP, w pliku zgloszenie.php. Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie wedkarstwo. Na końcu działania skrypt zamyka połączenie z serwerem.
zgloszenie.php w tym samym folderze co strona - tam wysyła formularz. Plik ma dwie części: na górze blok PHP, który rozmawia z bazą i przygotowuje komunikat, a pod nim dokument HTML5 z tym samym arkuszem stylów, który komunikat wypisuje (<?= ... ?> to skrót od <?php echo ... ?>) i prowadzi z powrotem do strony zawodów. Arkusz nie każe skryptowi nic wypisywać, ale pusta biała strona nie mówi użytkownikowi, czy zapis się udał.
new PDO(...) - serwer localhost, baza wedkarstwo, kodowanie utf8mb4, użytkownik root bez hasła (R.5.1). ERRMODE_EXCEPTION - błąd bazy rzuca wyjątek,
$pdo = null - PDO nie ma funkcji „zamknij”: połączenie zamyka się, gdy znika ostatnie odwołanie do obiektu. Kolejne operacje będą dopisywane przed tą linią, więc zostanie ona ostatnią operacją na bazie (R.5.2),
try / catch (PDOException ...) - przy awarii bazy użytkownik zobaczy zwykłe zdanie zamiast komunikatu PHP ze szczegółami serwera.
PDO zamiast mysqli z tabeli 1 - klucz przyjmuje obie biblioteki (uwaga przy R.5). Podgląd: wynik prawdziwego uruchomienia skryptu.
zgloszenie.phpPHPnowy plik
<?php$message = '';try {$pdo = new PDO('mysql:host=localhost;dbname=wedkarstwo;charset=utf8mb4', 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]);$message = 'Połączenie z bazą działa.';$pdo = null; // zamknięcie połączenia - ostatnia operacja na bazie} catch (PDOException $exception) {$message = 'Nie udało się zapisać zawodów. Spróbuj ponownie za chwilę.';}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Zawody wędkarskie</title> <linkrel="stylesheet"href="styl3.css"></head><body> <main> <h3>Dodaj zawody wędkarskie</h3> <p><?= $message?></p> <p><ahref="zawody.html">Wróć do strony zawodów</a></p> </main></body></html>
Podgląd strony po tym kroku (zgloszenie.php)
Krok 32: Skrypt: dane z formularza i ich sprawdzenie
Kryteria:
R.5.4 Skrypt pobiera dane z tablicy globalnej odpowiadającej zastosowanej metodzie formularza ($_POST, $_GET, $_REQUEST)
ok. 4 min
Polecenie z arkusza
Skrypt działa na danych przesłanych z formularza
Formularz wysyła dane metodą POST, więc skrypt czyta je z tablicy $_POST - kluczami są nazwy z atrybutów name: fishery, date, referee (R.5.4). Zanim cokolwiek trafi do bazy, dane są sprawdzane:
?? '' - gdy pola nie ma (np. plik otwarty wprost z paska adresu), zmienna dostaje pusty napis zamiast ostrzeżenia „Undefined array key”,
łowisko: filter_var z FILTER_VALIDATE_INT i min_range 1 zwraca liczbę całkowitą albo false (dla 0, -3, 2.5, pustego pola),
data: DateTime::createFromFormat('!Y-m-d', ...) i porównanie z powrotem z tym samym formatem - odpada pusty napis i daty, których nie ma (2021-02-30 PHP po cichu zamieniłby na 2 marca),
sędzia: trim obcina spacje z brzegów, więc same spacje to puste pole.
Błędy trafiają do listy $errors, a połączenie z bazą powstaje tylko dla poprawnych danych. Sprawdzone na prawdziwym PHP: łowisko 0, data 2021-02-30 i sędzia ze spacji dają trzy komunikaty.
Typowe błędy
Klucz R.5.4 wymaga odczytu z tablicy globalnej ($_POST), dlatego nie ma tu filter_input. Wpisanie $_POST['lowisko'] przy polu name="fishery" daje pustą wartość - klucz w $_POST to dokładnie name pola.
zgloszenie.phpPHPzmienione: 32 linie
<?php// dane z formularza i ich sprawdzenie$fishery = filter_var($_POST['fishery'] ?? '', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);$date = $_POST['date'] ?? '';$referee = trim($_POST['referee'] ?? '');$errors = [];$parsedDate = DateTime::createFromFormat('!Y-m-d', $date);if ($fishery === false) {$errors[] = 'Podaj numer łowiska - liczbę całkowitą od 1.';}if ($parsedDate === false || $parsedDate->format('Y-m-d') !== $date) {$errors[] = 'Wybierz datę zawodów.';}if ($referee === '') {$errors[] = 'Podaj sędziego.';}$message = 'Zawody nie zostały dodane.';if ($errors === []) {try {$pdo = new PDO('mysql:host=localhost;dbname=wedkarstwo;charset=utf8mb4', 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]);$message = 'Dane z formularza są poprawne.';$pdo = null; // zamknięcie połączenia - ostatnia operacja na bazie } catch (PDOException $exception) {$message = 'Nie udało się zapisać zawodów. Spróbuj ponownie za chwilę.'; }}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Zawody wędkarskie</title> <linkrel="stylesheet"href="styl3.css"></head><body> <main> <h3>Dodaj zawody wędkarskie</h3> <p><?= $message?></p><?phpforeach ($errorsas$error): ?> <prole="alert"><?= $error?></p><?phpendforeach; ?> <p><ahref="zawody.html">Wróć do strony zawodów</a></p> </main></body></html>
Podgląd strony po tym kroku (zgloszenie.php)
Krok 33: Skrypt: sprawdzenie łowiska i zapytanie przygotowane
Kryteria: ,
R.5.3 Skrypt wysyła do bazy danych zmodyfikowane zapytanie 1, tak że w odpowiednich polach są wpisane dane pobrane z formularza
R.5.5 Skrypt dodaje rekord w tabeli zawody_wedkarskie - sprawdzić w phpMyAdmin
ok. 5 min
Polecenie z arkusza
Wysyła do bazy danych zapytanie 1, które w polu Karty_wedkarskie_id zawiera wartość 0, pozostałe wartości wypełnione są danymi z formularza
Najpierw skrypt pyta bazę, czy takie łowisko istnieje: SELECT akwen FROM lowisko WHERE id = :id i fetchColumn() - nazwa akwenu albo false. W bazie z arkusza nie ma kluczy obcych, więc bez tego sprawdzenia INSERT przyjąłby łowisko numer 9, którego nie ma.
Potem zapytanie 1 z danymi z formularza (R.5.3): lista kolumn bez id, 0 w polu Karty_wedkarskie_id (zwycięzca jeszcze nieznany - tak każe arkusz), a w miejscu wartości parametry:fishery, :date, :referee. prepare wysyła do bazy samą treść zapytania, execute([...]) - osobno dane, więc apostrof w nazwisku (Piotr O'Neill) zapisuje się poprawnie i nie zmienia zapytania. Po zapisie $statement = null i $pdo = null zamykają połączenie.
Sprawdzone na prawdziwej bazie (obok tabela w phpMyAdmin): po wysłaniu formularza z łowiskiem 4, datą 2021-10-02 i sędzią Janem Kowalewskim tabela ma nowy wiersz 5 - 0, 4, 2021-10-02, Jan Kowalewski (R.5.5).
⚠️ Sprzeczność w arkuszu: wartość 0 nie wskazuje żadnego wędkarza (karty mają numery 1 i 2). Baza ją przyjmuje tylko dlatego, że w pliku baza.sql nie ma kluczy obcych, choć obraz 1 oznacza pola jako FK. Arkusz i klucz CKE wymagają 0 - na egzaminie punkt daje wartość z klucza.
Typowe błędy
Tabela zawody_wedkarskie jest w latin1: sędzia z polską literą, np. „Łukasz Żak”, zapisze się jako „?ukasz ?ak” - bez wyjątku, tylko z ostrzeżeniem w bazie (sprawdzone). Testując formularz, wpisz sędziego bez polskich liter, jak „Jan Kowalewski” z bazy. Poza egzaminem tabelę przestawia się na utf8mb4 (ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4).
zgloszenie.phpPHPzmienione: 17 linii
<?php// dane z formularza i ich sprawdzenie$fishery = filter_var($_POST['fishery'] ?? '', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);$date = $_POST['date'] ?? '';$referee = trim($_POST['referee'] ?? '');$errors = [];$parsedDate = DateTime::createFromFormat('!Y-m-d', $date);if ($fishery === false) {$errors[] = 'Podaj numer łowiska - liczbę całkowitą od 1.';}if ($parsedDate === false || $parsedDate->format('Y-m-d') !== $date) {$errors[] = 'Wybierz datę zawodów.';}if ($referee === '') {$errors[] = 'Podaj sędziego.';}$message = 'Zawody nie zostały dodane.';$saved = false;if ($errors === []) {try {$pdo = new PDO('mysql:host=localhost;dbname=wedkarstwo;charset=utf8mb4', 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]);$statement = $pdo->prepare('SELECT akwen FROM lowisko WHERE id = :id');$statement->execute(['id' => $fishery]);$fisheryName = $statement->fetchColumn();if ($fisheryName === false) {$message = 'Nie ma łowiska o numerze ' . $fishery . '.'; } else {// zapytanie 1: Karty_wedkarskie_id = 0 (zwycięzca jeszcze nieznany - tak każe arkusz)$statement = $pdo->prepare('INSERT INTO zawody_wedkarskie (Karty_wedkarskie_id, Lowisko_id, data_zawodow, sedzia) VALUES (0, :fishery, :date, :referee)' );$statement->execute(['fishery' => $fishery, 'date' => $date, 'referee' => $referee]);$saved = true;$message = 'Zawody zostały dodane.'; }$statement = null;$pdo = null; // zamknięcie połączenia - ostatnia operacja na bazie } catch (PDOException $exception) {$message = 'Nie udało się zapisać zawodów. Spróbuj ponownie za chwilę.'; }}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Zawody wędkarskie</title> <linkrel="stylesheet"href="styl3.css"></head><body> <main> <h3>Dodaj zawody wędkarskie</h3> <p><?= $message?></p><?phpforeach ($errorsas$error): ?> <prole="alert"><?= $error?></p><?phpendforeach; ?> <p><ahref="zawody.html">Wróć do strony zawodów</a></p> </main></body></html>
Podgląd strony po tym kroku (zgloszenie.php)
Krok 34: Podsumowanie zgłoszenia i bezpieczne wypisywanie
ok. 2 min
Dodatek spoza arkusza - klucz go nie ocenia. Po zapisie skrypt pokazuje, co dopisał: nazwę łowiska (z zapytania sprawdzającego - użytkownik widzi, że numer 4 to Warta-Obrzycko), datę w znaczniku <time> i sędziego. To dane od użytkownika i z bazy, więc przechodzą przez funkcję e() z góry pliku - htmlspecialchars z ENT_QUOTES zamienia <, >, & i cudzysłowy na encje: znacznik wpisany w pole „Sędzia” pokaże się jako tekst, a nie wykona na stronie. Przez e() idą też komunikat i błędy - jedna zasada dla wszystkiego, co wypisujesz.
zgloszenie.phpPHPzmienione: 14 linii
<?phpfunctione(string|int|float|null$value): string{returnhtmlspecialchars((string) $value, ENT_QUOTES);}// dane z formularza i ich sprawdzenie$fishery = filter_var($_POST['fishery'] ?? '', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);$date = $_POST['date'] ?? '';$referee = trim($_POST['referee'] ?? '');$errors = [];$parsedDate = DateTime::createFromFormat('!Y-m-d', $date);if ($fishery === false) {$errors[] = 'Podaj numer łowiska - liczbę całkowitą od 1.';}if ($parsedDate === false || $parsedDate->format('Y-m-d') !== $date) {$errors[] = 'Wybierz datę zawodów.';}if ($referee === '') {$errors[] = 'Podaj sędziego.';}$message = 'Zawody nie zostały dodane.';$saved = false;if ($errors === []) {try {$pdo = new PDO('mysql:host=localhost;dbname=wedkarstwo;charset=utf8mb4', 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]);$statement = $pdo->prepare('SELECT akwen FROM lowisko WHERE id = :id');$statement->execute(['id' => $fishery]);$fisheryName = $statement->fetchColumn();if ($fisheryName === false) {$message = 'Nie ma łowiska o numerze ' . $fishery . '.'; } else {// zapytanie 1: Karty_wedkarskie_id = 0 (zwycięzca jeszcze nieznany - tak każe arkusz)$statement = $pdo->prepare('INSERT INTO zawody_wedkarskie (Karty_wedkarskie_id, Lowisko_id, data_zawodow, sedzia) VALUES (0, :fishery, :date, :referee)' );$statement->execute(['fishery' => $fishery, 'date' => $date, 'referee' => $referee]);$saved = true;$message = 'Zawody zostały dodane.'; }$statement = null;$pdo = null; // zamknięcie połączenia - ostatnia operacja na bazie } catch (PDOException $exception) {$message = 'Nie udało się zapisać zawodów. Spróbuj ponownie za chwilę.'; }}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Zawody wędkarskie</title> <linkrel="stylesheet"href="styl3.css"></head><body> <main> <h3>Dodaj zawody wędkarskie</h3> <p><?= e($message) ?></p><?phpif ($saved): ?> <ul> <li>Łowisko: <?= e($fisheryName) ?></li> <li>Data: <timedatetime="<?= e($date) ?>"><?= e($date) ?></time></li> <li>Sędzia: <?= e($referee) ?></li> </ul><?phpendif; ?><?phpforeach ($errorsas$error): ?> <prole="alert"><?= e($error) ?></p><?phpendforeach; ?> <p><ahref="zawody.html">Wróć do strony zawodów</a></p> </main></body></html>
Podgląd strony po tym kroku (zgloszenie.php)
Krok 35: Odświeżenie nie dodaje zawodów drugi raz (PRG)
ok. 4 min
Dodatek spoza arkusza - klucz go nie ocenia. Strona z komunikatem jest wynikiem żądania POST: odświeżenie (F5) wysyła formularz jeszcze raz i w tabeli są dwa takie same zawody. Wzorzec PRG (Post/Redirect/Get) to usuwa:
session_start() na samym początku pliku - sesja przechowa dane między dwoma żądaniami,
obsługa formularza stoi w if ($_SERVER['REQUEST_METHOD'] === 'POST'). Po udanym zapisie ($saved) skrypt - już po zamknięciu połączenia - wkłada dane do $_SESSION i wysyła header('Location: zgloszenie.php'), a potem exit - header tylko ustawia nagłówek odpowiedzi i nie zatrzymuje skryptu,
przeglądarka wczytuje plik jeszcze raz, zwykłym żądaniem GET. Gałąź elseif odczytuje dane z sesji, od razu je usuwa i pokazuje podsumowanie; kolejne odświeżenie zostawia już tylko zdanie z odnośnikiem do formularza.
Sprawdzone na prawdziwym PHP: przekierowanie 302, podsumowanie po nim, odświeżenie bez drugiego wiersza w tabeli, łowisko 9, sędzia <b>Jan</b> (wypisany jako tekst) i złe hasło do bazy - za każdym razem bez ostrzeżeń PHP.
Typowe błędy
header('Location: ...') po wypisaniu choćby jednego znaku (także pustej linii przed <?php) nie zadziała - nagłówki muszą wyjść przed treścią strony.
zgloszenie.phpPHPzmienione: 58 linii
<?phpsession_start();functione(string|int|float|null$value): string{returnhtmlspecialchars((string) $value, ENT_QUOTES);}$errors = [];$saved = false;$message = 'Formularz zgłoszenia jest na stronie zawodów.';if ($_SERVER['REQUEST_METHOD'] === 'POST') {// dane z formularza i ich sprawdzenie$fishery = filter_var($_POST['fishery'] ?? '', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);$date = $_POST['date'] ?? '';$referee = trim($_POST['referee'] ?? '');$parsedDate = DateTime::createFromFormat('!Y-m-d', $date);if ($fishery === false) {$errors[] = 'Podaj numer łowiska - liczbę całkowitą od 1.'; }if ($parsedDate === false || $parsedDate->format('Y-m-d') !== $date) {$errors[] = 'Wybierz datę zawodów.'; }if ($referee === '') {$errors[] = 'Podaj sędziego.'; }$message = 'Zawody nie zostały dodane.';if ($errors === []) {try {$pdo = new PDO('mysql:host=localhost;dbname=wedkarstwo;charset=utf8mb4', 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]);$statement = $pdo->prepare('SELECT akwen FROM lowisko WHERE id = :id');$statement->execute(['id' => $fishery]);$fisheryName = $statement->fetchColumn();if ($fisheryName === false) {$message = 'Nie ma łowiska o numerze ' . $fishery . '.'; } else {// zapytanie 1: Karty_wedkarskie_id = 0 (zwycięzca jeszcze nieznany - tak każe arkusz)$statement = $pdo->prepare('INSERT INTO zawody_wedkarskie (Karty_wedkarskie_id, Lowisko_id, data_zawodow, sedzia) VALUES (0, :fishery, :date, :referee)' );$statement->execute(['fishery' => $fishery, 'date' => $date, 'referee' => $referee]);$saved = true;$message = 'Zawody zostały dodane.'; }$statement = null;$pdo = null; // zamknięcie połączenia - ostatnia operacja na bazieif ($saved) {// PRG: dane do sesji i przekierowanie - odświeżenie nie zapisze zawodów drugi raz$_SESSION['contest'] = ['fishery' => $fisheryName, 'date' => $date, 'referee' => $referee];header('Location: zgloszenie.php');exit; } } catch (PDOException $exception) {$message = 'Nie udało się zapisać zawodów. Spróbuj ponownie za chwilę.'; } }} elseif (isset($_SESSION['contest'])) {// żądanie GET po przekierowaniu: dane z sesji, od razu usunięte ['fishery' => $fisheryName, 'date' => $date, 'referee' => $referee] = $_SESSION['contest'];unset($_SESSION['contest']);$saved = true;$message = 'Zawody zostały dodane.';}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Zawody wędkarskie</title> <linkrel="stylesheet"href="styl3.css"></head><body> <main> <h3>Dodaj zawody wędkarskie</h3> <p><?= e($message) ?></p><?phpif ($saved): ?> <ul> <li>Łowisko: <?= e($fisheryName) ?></li> <li>Data: <timedatetime="<?= e($date) ?>"><?= e($date) ?></time></li> <li>Sędzia: <?= e($referee) ?></li> </ul><?phpendif; ?><?phpforeach ($errorsas$error): ?> <prole="alert"><?= e($error) ?></p><?phpendforeach; ?> <p><ahref="zawody.html">Wróć do strony zawodów</a></p> </main></body></html>
Krok 36 · po tym etapie masz 35 z 35 kryteriów (pkt)
Krok 36: Co jest inaczej i którą wersję wybrać na egzaminie
ok. 3 min
Obie wersje dają komplet 35 punktów. Różnice:
wersja podstawowa
wersja nowoczesna
układ
float: left czterech bloków, clear bloku głównego
siatki w <header> (75% 25%) i <footer> (50% 50%)
bloki
#left, #right, main, dwa <footer>
dwie <section> w <header>, main, dwie <section> w <footer>
kolory
wpisane w każdą regułę
zmienne CSS
formularz
<br> po polach, <input type="reset/submit">
bloki <div>, <button>, min, required
zapytanie 1
VALUES (NULL, ...) w kolejności kolumn
lista kolumn bez id
biblioteka
mysqli (tabela 1 arkusza)
PDO z wyjątkami
dane z formularza
wklejone do zapytania
sprawdzone (także łowisko w bazie) i podane jako parametry
wynik
pusta strona
komunikat z podsumowaniem przez e()
odświeżenie po zapisie
dodaje zawody drugi raz
PRG - przekierowanie, dane z sesji
W prawdziwym projekcie dane logowania do bazy trzyma się zwykle w osobnym pliku (np. config.php), formularz chroni się tokenem CSRF, a tabele mają klucze obce i zestaw znaków utf8mb4 - klucz tego nie wymaga.
Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 arkusza i łatwiej ją napisać bez dokumentacji pod ręką. Nowoczesna jest odporna na błędne i podmienione dane z formularza. Obie biblioteki klucz przyjmuje.
Krok 37 · po tym etapie masz 35 z 35 kryteriów (pkt)
Krok 37: 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 weryfikowałeś poprawność działania witryny. Umieść go w folderze z numerem, którym został podpisany arkusz. Nagraj płytę z rezultatami pracy. W folderze z numerem, którym został podpisany arkusz powinny znajdować się pliki: import.png, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, przeglądarka.txt, styl3.css, zawody.html, zawody.jpg, zgloszenie.php, ewentualnie inne przygotowane pliki.
W przeglądarka.txt nazwa przeglądarki, w której sprawdzana była strona przez http://localhost/.... Sprawdź listę plików (zawody.jpg odbity, 251 × 250 px), nagraj płytę, sprawdź jej odczyt i opisz 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.