INF.03-03-25.01-SGStyczeń 2025 · 50 kroków · ok. 101 min · 43 kryteria z klucza
Rozwiązanie krok po kroku: Kalendarz imienin w PHP (Wersja podstawowa)
Rozwiązanie buduje stronę o kalendarzu z imieninami: baza kalendarz z tabelą imienin na każdy dzień roku i cztery zapytania - wzorzec LIKE, równość, zliczanieCOUNT i dodanie kolumnyALTER TABLE, do tego eksport tabeli do pliku CSV, potem animacja GIF z dwunastu klatek, strona kalendarz.php z tabelą o scalonych wierszach, formularzem z polem daty, listą numerowaną z zagnieżdżonymi listami i animacją-odnośnikiem, style w styl.css i dwa skrypty PHP: pierwszy pokazuje dzisiejszy dzień tygodnia, datę i imieniny, drugi - imieniny w dniu wybranym w formularzu.
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 pisane najprościej, funkcjami mysqli_query i mysqli_fetch_row, a na końcu zostają przerobione na wersję z prawdziwych projektów: zapytania przygotowane, sprawdzenie daty i htmlspecialchars przy wypisywaniu.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: trzy bloki na siatce CSS zamiast float i clear, PDO z zapytaniem przygotowanym w funkcji, sprawdzenie daty z formularza i htmlspecialchars przy każdym wypisaniu od pierwszej linii - obie wersje są zgodne z kluczem.
Baza i klatki animacji pochodzą z prawdziwego archiwum pliki13 (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. PHP nie działa w podglądzie, więc przy krokach ze skryptami widać wynik z tej bazy dla dnia z ilustracji 2 arkusza (czwartek 25 maja 2023) i daty 24 stycznia 2024 wybranej w formularzu.
Jak liczą się punkty. Klucz ma 43 kryteria (R.1.1 - R.5.10), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 33 punkty - można stracić 10 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-8 · po tym etapie masz 7 z 43 kryteriów (pkt)
Krok 1: Baza danych kalendarz
Kryteria:
R.1.1 Wykonany import tabeli do bazy danych kalendarz, co jest udokumentowane w pliku import.png
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie kalendarz, z zestawem polskich znaków (np. utf8_unicode_ci).
Rozpakuj pliki13.7z z pulpitu (hasło k@L3ndarz) do folderu z numerem zdającego: baza.sql i dwanaście klatek kalendarz01.png - kalendarz12.png. W phpMyAdmin: Nowa, nazwa kalendarz, porównywanie z polskimi znakami, np. utf8_unicode_ci - imiona mają polskie litery.
Krok 2: Import tabeli z pliku baza.sql
Kryteria:
R.1.1 Wykonany import tabeli do bazy danych kalendarz, co jest udokumentowane w pliku import.png
ok. 2 min
Polecenie z arkusza
Do utworzonej bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum.
Wybierz bazę kalendarz, potem Import → baza.sql → Wykonaj. Powstaje jedna tabela imieniny z ilustracji 1: 366 wierszy - każdy dzień roku, łącznie z 29 lutego. Data jest zapisana tekstem w formacie mm-dd, bez roku: 7 listopada to 11-07. Imiona są w dopełniaczu, kilka w jednym polu: „Moniki, Floriana, Władysława”.
Krok 3: Zrzut ekranu import.png
Kryteria:
R.1.1 Wykonany import tabeli do bazy danych kalendarz, co jest udokumentowane w pliku import.png
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie PNG pod nazwą 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 i zapis jako import.png - komunikat o udanym imporcie i tabela imieniny w drzewie bazy.
Typowe błędy
Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).
Krok 4: Zapytanie 1: kiedy imieniny Karola
Kryteria: ,
R.1.2 Zapisany plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonane zapytanie 1 wybierające z tabeli imieniny jedynie daty, w których są imieniny Karola. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT data FROM imieniny WHERE imiona LIKE "%Karola%"; ("%Karol%" jest błędem ) oraz wynik działania udokumentowany zrzutem, na którym widoczne są jedynie trzy rekordy z wartościami: 05-30, 06-03, 11-04
ok. 3 min
Polecenie z arkusza
Zapytanie 1: wybierające z tabeli imieniny jedynie daty, w których są imieniny Karola.
SELECT data FROM imieniny - „jedynie daty”,
WHERE imiona LIKE "%Karola%" - imię może stać w dowolnym miejscu pola, więc % z obu stron.
Ważna pułapka: imiona są w dopełniaczu („imieniny Karola”), a w bazie są też Karoliny. Wzorzec %Karol% łapie i Karola, i Karolinę: 5 dni zamiast 3. Dlatego szukasz formy „Karola” - wynik 05-30, 06-03 i 11-04, jak w kluczu. Zapytanie zapisujesz w kwerendy.txt, zrzut jako kw1.png.
Typowe błędy
LIKE "%Karol%" klucz wprost nazywa błędem - wynik obejmuje imieniny Karoliny.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT data FROM imieniny WHERE imiona LIKE "%Karola%";
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: imieniny 4 maja
Kryteria:
R.1.4 Wykonane zapytanie 2 wybierające jedynie imiona osób, które obchodzą imieniny 4 maja. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imiona FROM imieniny WHERE data = "05-04"; oraz wynik działania udokumentowany zrzutem, na którym widoczny jest dokładnie 1 rekord z danymi: Moniki, Floriana, Władysława
ok. 1 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie imiona osób, które obchodzą imieniny 4 maja.
4 maja w formacie bazy to 05-04 - najpierw miesiąc, potem dzień, w cudzysłowie, bo pole jest tekstowe. Wynik: jeden wiersz „Moniki, Floriana, Władysława”. Zrzut: kw2.png. To zapytanie wróci w obu skryptach PHP - zamiast 05-04 wstawisz tam datę dzisiejszą albo datę z formularza.
Typowe błędy
data = "04-05" (dzień-miesiąc) szuka 5 kwietnia.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT data FROM imieniny WHERE imiona LIKE "%Karola%";-- Zapytanie 2SELECT imiona FROM imieniny WHERE data = "05-04";
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: ile dni z imieniem z cząstką „mir”
Kryteria:
R.1.5 Wykonane zapytanie 3 zliczające daty, w których imieniny obchodzi osoba, której imię zawiera cząstkę "mir". W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(data) FROM imieniny WHERE imiona LIKE "%mir%"; (COUNT możliwe również z * lub innym polem) oraz wynik działania udokumentowany zrzutem, na którym widoczna jest jedynie wartość 23
ok. 2 min
Polecenie z arkusza
Zapytanie 3: obliczające, ile jest dat, w których imieniny obchodzi osoba, której imię zawiera cząstkę mir (np. Miron, Dobromir, Sędzimira).
COUNT(data) zwraca liczbę wierszy spełniających warunek, a nie same wiersze. Wzorzec %mir% łapie cząstkę w środku i na końcu imienia: Dobromira, Sędzimira, Kazimierza. LIKE w MySQL przy porównywaniu utf8_..._ci nie rozróżnia wielkości liter, więc łapie też „Mirosława”. Wynik: 23, jak w kluczu. Zrzut: kw3.png.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT data FROM imieniny WHERE imiona LIKE "%Karola%";-- Zapytanie 2SELECT imiona FROM imieniny WHERE data = "05-04";-- Zapytanie 3SELECT COUNT(data) FROM imieniny WHERE imiona LIKE "%mir%";
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: nowe pole zyczenia
Kryteria:
R.1.6 Wykonane zapytanie 4 dodające do tabeli imieniny pole zyczenia typu napisowego, które pomieści 500 znaków. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE imieniny ADD COLUMN zyczenia VARCHAR(500); (COLUMN opcjonalne, dowolny typ tekstowy o długości min. 500 ) oraz wynik działania udokumentowany zrzutem, na którym widoczna jest informacja o poprawnym wykonaniu zapytania lub tabela z dodaną kolumną
ok. 2 min
Polecenie z arkusza
Zapytanie 4: dodające do tabeli imieniny pole zyczenia typu napisowego, które pomieści 500 znaków.
Zmiana budowy tabeli to ALTER TABLE, a nowa kolumna - ADD COLUMN z nazwą i typem. „Napisowe na 500 znaków” to VARCHAR(500) (pasuje też TEXT). Istniejące wiersze dostają w nowej kolumnie NULL. Zrzut kw4.png: komunikat o wykonaniu albo struktura tabeli z kolumną zyczenia.
Typowe błędy
VARCHAR(50) (literówka w długości) nie pomieści 500 znaków - klucz wymaga typu tekstowego o długości co najmniej 500.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT data FROM imieniny WHERE imiona LIKE "%Karola%";-- Zapytanie 2SELECT imiona FROM imieniny WHERE data = "05-04";-- Zapytanie 3SELECT COUNT(data) FROM imieniny WHERE imiona LIKE "%mir%";-- Zapytanie 4ALTER TABLE imieniny ADD COLUMN zyczenia VARCHAR(500);
Podgląd strony po tym kroku
Krok 8: Eksport tabeli do imieniny.csv
Kryteria:
R.1.7 Zapisany plik imieniny w formacie CSV, zawierający wyeksportowane rekordy z tabeli imieniny
ok. 2 min
Polecenie z arkusza
Wyeksportuj dane z tabeli imieniny do pliku w formacie CSV i nadaj mu nazwę imieniny.
W phpMyAdmin klikasz tabelę imieniny, potem Eksport, format CSV i Eksportuj. Plik pobiera się jako imieniny.csv - przenosisz go do folderu z numerem zdającego. Przy ustawieniach domyślnych każdy wiersz to wartości oddzielone przecinkami, w cudzysłowach; pusta kolumna zyczenia (dodana zapytaniem 4) wychodzi jako NULL. Plik ma 366 wierszy (R.1.7).
Typowe błędy
Eksport całej bazy (zakładka Eksport bez wybranej tabeli) w formacie SQL to inny plik niż wymagany CSV z tabeli imieniny.
Kroki 9-29 · po tym etapie masz 22 z 43 kryteriów (pkt)
Krok 9: Warstwy animacji: dwanaście klatek
Kryteria:
R.2.1 Utworzony plik kalendarz.gif o rozmiarze 500 x 500 px, z przezroczystością, zawierający animację złożoną z plików, kolejno od kalendarz01.png do kalendarz12.png (widać kolejne ruchy strzałki-słońca ), jeden obraz na klatkę
ok. 4 min
Polecenie z arkusza
Na animację składają się pliki, kolejno: kalendarz01.png, kalendarz02.png, kalendarz03.png, kalendarz04.png, kalendarz05.png, kalendarz06.png, kalendarz07.png, kalendarz08.png, kalendarz09.png, kalendarz10.png, kalendarz11.png i kalendarz12.png. Nie należy zmieniać właściwości grafik: przezroczystości i wymiarów 500 x 500 px.
W GIMP-ie: Plik → Otwórz jako warstwy, zaznaczasz wszystkie dwanaście plików naraz. Każdy plik staje się osobną warstwą, a warstwa w GIF-ie to jedna klatka. Kolejność: najniższa warstwa jest pierwszą klatką - na liście warstw kalendarz01 musi być na dole, a kalendarz12 na górze (w razie potrzeby Warstwa → Stos → Odwróć kolejność warstw). Obrazów nie skalujesz i nie spłaszczasz - zostają 500 × 500 z przezroczystym tłem (R.2.1).
Krok 10: Eksport kalendarz.gif: 350 ms na klatkę
Kryteria: ,
R.2.1 Utworzony plik kalendarz.gif o rozmiarze 500 x 500 px, z przezroczystością, zawierający animację złożoną z plików, kolejno od kalendarz01.png do kalendarz12.png (widać kolejne ruchy strzałki-słońca ), jeden obraz na klatkę
R.2.2 Ustawiony czas wyświetlenia obrazów animacji na 350 ms, co jest udokumentowane zrzutem parametry_animacji.png
ok. 4 min
Polecenie z arkusza
Każdy obraz jest pokazywany w animacji przez 350 ms, jedna klatka na warstwę. Udokumentuj ustawienie parametru za pomocą zrzutu ekranu o nazwie parametry_animacji.png. Zrzut musi obejmować cały obszar ekranu z widocznym paskiem zadań.
Plik → Eksportuj jakokalendarz.gif. W oknie eksportu zaznaczasz Jako animację, opóźnienie między klatkami 350 ms i rozmieszczenie klatek Jedna klatka na warstwę (zastąp) - bez tego klatki nakładałyby się na siebie i strzałka-słońce zostawiałaby ślad. Zanim klikniesz Eksportuj, robisz zrzut całego ekranu z tym oknem: parametry_animacji.png (R.2.2). Animacja w podglądzie obraca strzałkę jak wskazówkę.
Typowe błędy
Zwykły eksport GIF bez zaznaczonego „Jako animację” zapisuje tylko jedną, spłaszczoną klatkę.
Podgląd strony po tym kroku
Krok 11: Plik kalendarz.php w HTML5
Kryteria:
R.2.3 Witryna internetowa zapisana w pliku kalendarz.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "Kalendarz”, Strona zawiera sekcje head i body
ok. 2 min
Polecenie z arkusza
Cechy witryny: Składa się ze strony o nazwie kalendarz.php. Zapisana w języku HTML5.
Strona ma rozszerzenie .php, bo za chwilę dojdą do niej skrypty - ale na razie to zwykły HTML5 i podgląd pokazuje go wprost. Na egzaminie plik leży w htdocs XAMPP-a i otwierasz go przez http://localhost/....
R.2.3 Witryna internetowa zapisana w pliku kalendarz.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "Kalendarz”, Strona zawiera sekcje head i body
R.2.3 Witryna internetowa zapisana w pliku kalendarz.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "Kalendarz”, 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>.
R.2.3 Witryna internetowa zapisana w pliku kalendarz.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "Kalendarz”, Strona zawiera sekcje head i body
ok. 1 min
Polecenie z arkusza
Tytuł strony widoczny na karcie przeglądarki: „Kalendarz”.
R.3.2 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.
Krok 16: Bloki: nagłówek, napis, trzy bloki, stopka
Kryteria:
R.2.4 Zdefiniowany układ strony dzielący ją na bloki: nagłówkowy, napisu, lewy, środkowy, prawy, stopki przy pomocy semantycznych znaczników sekcji języka HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, do stopki - footer. Dopuszcza się dodatkowe użycie bloków div lub section
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: nagłówkowy, napisu, poniżej trzy bloki umieszczone obok siebie, na dole stopka. Podział zrealizowany 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 ilustracją 2.
<header> i <footer> - jak wymaga klucz (R.2.4). Blok napisu i trzy bloki treści to <section> z identyfikatorami po angielsku: caption, left, middle, right - po nich dobierze się do nich styl. Ustawienie trzech bloków obok siebie zrobisz w CSS.
R.2.5 Umieszczone w bloku nagłówkowym <h1>: "Dni, miesiące, lata…", w bloku środkowym <h2>: "Sprawdź kto ma urodziny", w bloku prawym <h2> "Rodzaje kalendarzy" oraz przynajmniej jeden paragraf
ok. 1 min
Polecenie z arkusza
Zawartość bloku nagłówkowego: Nagłówek pierwszego stopnia o treści „Dni, miesiące, lata...”.
R.2.5 Umieszczone w bloku nagłówkowym <h1>: "Dni, miesiące, lata…", w bloku środkowym <h2>: "Sprawdź kto ma urodziny", w bloku prawym <h2> "Rodzaje kalendarzy" oraz przynajmniej jeden paragraf
ok. 1 min
Polecenie z arkusza
Zawartość bloku napisu: Paragraf z efektem działania Skryptu 1.
Na razie pusty akapit <p> - jego treść wypisze później Skrypt 1.
R.2.7 Pierwszy wiersz tabeli zawiera komórki nagłówkowe, zastosowany znacznik <th>
ok. 1 min
Polecenie z arkusza
Zawartość bloku lewego: Tabela o 2 kolumnach i 13 wierszach, z czego niektóre wiersze są scalone. Pierwszy wiersz zawiera komórki nagłówkowe. Treść i wygląd tabeli przedstawiony jest na ilustracji 3.
Pierwszy wiersz to komórki nagłówkowe <th>: „liczba dni” i „miesiąc” (R.2.7). Przeglądarka pogrubia je i wyśrodkowuje sama.
Krok 20: Tabela: miesiące po 31 dni - komórka scalona
Kryteria:
R.2.6 W bloku lewym utworzona tabela o 2 kolumnach i 13 wierszach, z czego wiersze w pierwszej kolumnie są scalone zgodnie z ilustracją 3 arkusza egzaminacyjnego. Zastosowane znaczniki <table>, <tr>, <td> oraz atrybut rowspan
ok. 3 min
Polecenie z arkusza
Tabela o 2 kolumnach i 13 wierszach, z czego niektóre wiersze są scalone.
Siedem miesięcy ma 31 dni. Liczbę 31 wpisujesz raz, w pierwszym z siedmiu wierszy, z atrybutem rowspan="7" - komórka sięga w dół przez siedem wierszy. Dlatego w kolejnych sześciu wierszach jest już tylko jedna komórka z nazwą miesiąca: drugą kolumnę zajmuje komórka scalona (R.2.6).
Typowe błędy
Wpisanie liczby dni w każdym wierszu mimo rowspan przesuwa nazwy miesięcy do trzeciej, nieistniejącej kolumny.
R.2.6 W bloku lewym utworzona tabela o 2 kolumnach i 13 wierszach, z czego wiersze w pierwszej kolumnie są scalone zgodnie z ilustracją 3 arkusza egzaminacyjnego. Zastosowane znaczniki <table>, <tr>, <td> oraz atrybut rowspan
ok. 2 min
Polecenie z arkusza
Treść i wygląd tabeli przedstawiony jest na ilustracji 3.
To samo dla czterech miesięcy po 30 dni (rowspan="4") i ostatni wiersz bez scalania: „28 lub 29” i luty. Razem 13 wierszy: nagłówek i 12 miesięcy (R.2.6).
R.2.5 Umieszczone w bloku nagłówkowym <h1>: "Dni, miesiące, lata…", w bloku środkowym <h2>: "Sprawdź kto ma urodziny", w bloku prawym <h2> "Rodzaje kalendarzy" oraz przynajmniej jeden paragraf
ok. 1 min
Polecenie z arkusza
Zawartość bloku środkowego: Nagłówek drugiego stopnia o treści: „Sprawdź kto ma urodziny”.
<h2>. Treść jest z arkusza - choć strona pokazuje imieniny, a nie urodziny.
Krok 23: Formularz wysyłany metodą POST do tej samej strony
Kryteria: ,
R.2.8 W bloku środkowym umieszczony formularz z polem edycyjnym i przyciskiem "wyślij", zastosowany znacznik <form>
R.3.5 Formularz wysyła dane metodą POST do tego samego pliku (poprawne również bez atrybutu action )
ok. 2 min
Polecenie z arkusza
Formularz przesyłający dane metodą bezpieczną, do tego samego pliku.
„Metoda bezpieczna” w rozumieniu arkusza to method="post": dane idą 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. Bez atrybutu action formularz wysyła dane do tego samego pliku - kalendarz.php przeładuje się i odczyta datę w Skrypcie 2 (R.2.8, R.3.5).
R.3.4 Pole edycyjne jest typu date , minimalna wartość 2024-01-01, maksymalna 2024-12-31 oraz zawiera atrybut required
ok. 3 min
Polecenie z arkusza
Pole edycyjne o typie przeznaczonym do wprowadzania daty. Kalendarz wyświetla tylko daty z 2024 roku (od 1 stycznia 2024 do 31 grudnia 2024). Pole edycyjne jest wymagane. Pole edycyjne w stanie początkowym po naciśnięciu przycisku kalendarza zostało przedstawione na ilustracji 4.
type="date" - przeglądarka dokłada przycisk z kalendarzem,
min="2024-01-01" i max="2024-12-31" - daty zawsze w formacie rrrr-mm-dd; spoza zakresu nie da się wybrać (opis w ramce „Pole edycyjne typu data” arkusza). Ponieważ zakres obejmuje jeden rok, Chrome od razu podpowiada rok 2024 - jak na ilustracji 4,
required - formularza z pustym polem nie da się wysłać,
name="date" - pod tą nazwą Skrypt 2 znajdzie datę w $_POST.
Kliknij ikonę kalendarza w podglądzie (R.3.4).
Typowe błędy
Bez atrybutu name przeglądarka nie wysyła wartości pola - $_POST zostaje pusty, a Skrypt 2 nic nie wypisze.
R.2.10 W bloku prawym umieszczony obraz z animacją z tekstem alternatywnym "Kalendarz Majów"
R.3.3 Kliknięcie animacji inicjuje otwarcie strony https://pl.wikipedia.org/wiki/Kalendarz_Majów w nowym oknie przeglądarki
ok. 2 min
Polecenie z arkusza
Zawartość bloku prawego: Animacja kalendarz.gif z tekstem alternatywnym „Kalendarz Majów”, której kliknięcie powoduje otwarcie strony internetowej https://pl.wikipedia.org/wiki/Kalendarz_Majów w nowym oknie przeglądarki.
Obraz wstawiasz do środka odnośnika <a> - wtedy cały obraz jest klikalny. target="_blank" otwiera stronę w nowym oknie (karcie) przeglądarki (R.2.10, R.3.3). Animowany GIF wstawia się tak samo jak zwykły obraz.
R.2.5 Umieszczone w bloku nagłówkowym <h1>: "Dni, miesiące, lata…", w bloku środkowym <h2>: "Sprawdź kto ma urodziny", w bloku prawym <h2> "Rodzaje kalendarzy" oraz przynajmniej jeden paragraf
ok. 1 min
Polecenie z arkusza
Nagłówek drugiego stopnia o treści „Rodzaje kalendarzy”.
Krok 28: Lista numerowana z dwiema listami w środku
Kryteria:
R.2.9 W bloku prawym umieszczona jedna lista numerowana z dwoma elementami, każdy z nich zagnieżdża listę punktowaną, pierwsza podlista ma trzy elementy, druga dwa. Zastosowane znaczniki <ol>, <ul> i <li>, zagnieżdżenie wewnątrz znacznika <li>
ok. 3 min
Polecenie z arkusza
Lista numerowana (uporządkowana) z zagnieżdżonymi dwoma listami punktowanymi (nieuporządkowanymi), zgodna z ilustracją 5.
Lista numerowana to <ol>, punktowana - <ul>. Zagnieżdżenie polega na tym, że cała lista <ul> stoi wewnątrz elementu <li> - przed jego zamknięciem </li>. Pierwszy punkt („słoneczny”) ma podlistę z trzema elementami, drugi („księżycowy”) z dwoma (R.2.9).
Typowe błędy
<ul> wstawione między dwa <li> (po </li>) przeglądarka pokaże podobnie, ale to błąd składni - klucz wymaga zagnieżdżenia wewnątrz <li>.
R.2.5 Umieszczone w bloku nagłówkowym <h1>: "Dni, miesiące, lata…", w bloku środkowym <h2>: "Sprawdź kto ma urodziny", w bloku prawym <h2> "Rodzaje kalendarzy" oraz przynajmniej jeden paragraf
ok. 1 min
Polecenie z arkusza
Zawartość stopki: paragraf o treści „Stronę opracował(a): ”, dalej numer zdającego.
Akapit w <footer>. Na egzaminie po dwukropku wpisujesz swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania.
Kroki 30-38 · po tym etapie masz 33 z 43 kryteriów (pkt)
Krok 30: Plik styl.css: czcionka strony
Kryteria:
R.4.1 Ustawiony dla ciała strony (dla body lub kontenera całej strony ): krój czcionki Bookman, Serif (tylko taka kolejność jest prawidłowa )
ok. 1 min
Polecenie z arkusza
Dla ciała strony: krój czcionki Bookman, a w przypadku braku: czcionka Serif.
Lista krojów po przecinku: przeglądarka bierze pierwszy, który ma, a serif to rodzina zapasowa - dowolna czcionka szeryfowa. Kolejność ma znaczenie: klucz uznaje tylko „Bookman, serif” (R.4.1).
styl.cssCSSnowy plik
body {font-family: Bookman, serif;}
Podgląd strony po tym kroku (kalendarz.php)
Krok 31: Nagłówek i stopka
Kryteria: , , ,
R.4.2 Ustawiony kolor tła Indigo dla bloków nagłówkowego i stopki, BlueViolet dla bloku napisu, Lavender dla bloków lewego i prawego, GhostWhite dla środkowego
R.4.3 Ustawiony biały kolor czcionki dla bloku nagłówkowego i stopki
R.4.5 Ustawione wyrównanie tekstu do środka dla bloków nagłówkowego, środkowego i stopki oraz do prawej strony dla bloku napisu
R.4.6 Ustawione marginesy wewnętrzne (padding) 10px dla bloków nagłówkowego, napisu, stopki i obrazu, 3px dla komórek tabeli oraz ustawione marginesy zewnętrzne (margin) 30px dla tabeli i formularza
ok. 1 min
Polecenie z arkusza
Wspólne dla bloku nagłówkowego i stopki: kolor tła Indigo, biały kolor czcionki, marginesy wewnętrzne 10 px, wyrównanie tekstu do środka.
Jedna reguła dla dwóch selektorów.
styl.cssCSSzmienione: 6 linii
body {font-family: Bookman, serif;}header, footer {background-color: Indigo;color: white;padding: 10px;text-align: center;}
Podgląd strony po tym kroku (kalendarz.php)
Krok 32: Blok napisu
Kryteria: , ,
R.4.2 Ustawiony kolor tła Indigo dla bloków nagłówkowego i stopki, BlueViolet dla bloku napisu, Lavender dla bloków lewego i prawego, GhostWhite dla środkowego
R.4.5 Ustawione wyrównanie tekstu do środka dla bloków nagłówkowego, środkowego i stopki oraz do prawej strony dla bloku napisu
R.4.6 Ustawione marginesy wewnętrzne (padding) 10px dla bloków nagłówkowego, napisu, stopki i obrazu, 3px dla komórek tabeli oraz ustawione marginesy zewnętrzne (margin) 30px dla tabeli i formularza
ok. 1 min
Polecenie z arkusza
Dla bloku napisu: kolor tła BlueViolet, marginesy wewnętrzne 10 px, wyrównanie tekstu do prawej strony.
Selektor identyfikatora zaczyna się od #. Napis Skryptu 1 stanie przy prawej krawędzi, jak na ilustracji 2.
R.4.2 Ustawiony kolor tła Indigo dla bloków nagłówkowego i stopki, BlueViolet dla bloku napisu, Lavender dla bloków lewego i prawego, GhostWhite dla środkowego
R.4.4 Ustawiona wysokość bloku lewego, środkowego i prawego 500px oraz szerokość bloku lewego 25%, środkowego 40%, prawego 35% (width lub grid-template-columns lub flex) oraz dla selektora img szerokość 50%
ok. 2 min
Polecenie z arkusza
Wspólny dla bloków lewego i prawego: kolor tła Lavender, wysokość 500 px. Dodatkowo szerokość bloku lewego 25%, bloku prawego 35%.
Wspólne cechy w jednej regule, szerokości osobno - każdy blok ma inną.
R.4.2 Ustawiony kolor tła Indigo dla bloków nagłówkowego i stopki, BlueViolet dla bloku napisu, Lavender dla bloków lewego i prawego, GhostWhite dla środkowego
R.4.4 Ustawiona wysokość bloku lewego, środkowego i prawego 500px oraz szerokość bloku lewego 25%, środkowego 40%, prawego 35% (width lub grid-template-columns lub flex) oraz dla selektora img szerokość 50%
R.4.5 Ustawione wyrównanie tekstu do środka dla bloków nagłówkowego, środkowego i stopki oraz do prawej strony dla bloku napisu
ok. 1 min
Polecenie z arkusza
Dla bloku środkowego: kolor tła GhostWhite, wyrównanie tekstu do środka, wysokość 500 px, szerokość 40%.
25% + 40% + 35% = 100% - trzy bloki wypełnią całą szerokość, o ile nie dostaną poziomych marginesów ani ramek.
R.4.4 Ustawiona wysokość bloku lewego, środkowego i prawego 500px oraz szerokość bloku lewego 25%, środkowego 40%, prawego 35% (width lub grid-template-columns lub flex) oraz dla selektora img szerokość 50%
R.4.6 Ustawione marginesy wewnętrzne (padding) 10px dla bloków nagłówkowego, napisu, stopki i obrazu, 3px dla komórek tabeli oraz ustawione marginesy zewnętrzne (margin) 30px dla tabeli i formularza
R.4.7 Ustawione dla obrazu opływanie tekstem po lewej stronie float:right
ok. 2 min
Polecenie z arkusza
Dla selektora obrazu: oblewanie tekstem po lewej stronie (obraz po prawej stronie), szerokość 50%, marginesy wewnętrzne 10 px.
float: right przesuwa obraz do prawej krawędzi bloku, a nagłówek i lista zajmują miejsce po jego lewej stronie - tekst „opływa” obraz (R.4.7). Szerokość 50% liczy się od szerokości bloku prawego.
R.4.6 Ustawione marginesy wewnętrzne (padding) 10px dla bloków nagłówkowego, napisu, stopki i obrazu, 3px dla komórek tabeli oraz ustawione marginesy zewnętrzne (margin) 30px dla tabeli i formularza
R.4.9 Ustawione dla tabeli i komórki tabeli obramowanie 1px solid Indigo
R.4.10 Ustawione dla tabeli obramowanie połączone border-collapse: collapse
ok. 2 min
Polecenie z arkusza
Wspólne dla tabeli i formularza: marginesy zewnętrzne 30 px. Dla tabeli i komórki tabeli: obramowanie połączone, linią ciągłą o szerokości 1 px i kolorze Indigo. Wspólne dla zwykłej komórki i komórki nagłówkowej tabeli: marginesy wewnętrzne 3 px.
Trzy reguły, każda dla innej grupy selektorów: table, form - margines, table, td - ramka i border-collapse: collapse, które łączy podwójne ramki sąsiednich komórek w jedną linię, td, th - odstęp tekstu od ramki (R.4.6, R.4.9, R.4.10).
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 2 w arkuszu egzaminacyjnym (prawidłowo zastosowane właściwości CSS decydujące o układzie strony np. float i clear albo display flex albo grid albo position )
ok. 2 min
Polecenie z arkusza
Podział zrealizowany 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 ilustracją 2.
float: left dla trzech bloków ustawia je obok siebie; clear: both dla stopki sprowadza ją pod nie. Blok napisu nie dostaje float, więc zostaje na całą szerokość nad blokami (R.3.1).
Kroki 39-47 · po tym etapie masz 43 z 43 kryteriów (pkt)
Krok 39: Połączenie z bazą kalendarz
Kryteria: ,
R.5.1 Skrypt jest napisany w języku PHP i zawiera przynajmniej jedną zgodną z treścią zadania instrukcję
R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy kalendarz oraz ostatnią operacją na bazie jest jej zamknięcie
ok. 2 min
Polecenie z arkusza
Łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie kalendarz.
Skrypt 1 piszesz w środku akapitu bloku napisu - to, co wypisze, stanie się treścią akapitu. mysqli_connect z czterema argumentami z arkusza łączy się z serwerem i od razu wybiera bazę kalendarz; uchwyt połączenia trzymasz w $connection - użyją go oba skrypty (R.5.1, R.5.2).
R.5.4 Skrypt 1 pobiera bieżący dzień tygodnia lub numer dnia tygodnia i przekształca go na dzień tygodnia zapisany w języku polskim
ok. 3 min
Polecenie z arkusza
Wyświetla tekst o treści „Dzisiaj jest <dzień tygodnia>, <data>, imieniny: <imiona>”, gdzie <dzień tygodnia> oznacza słowny zapis bieżącego dnia w języku polskim, np. „poniedziałek”.
date("l") zwraca nazwę dnia po angielsku („Thursday”), więc przekładasz numer dnia na polski. date("N") daje numer od 1 (poniedziałek) do 7 (niedziela) - opis w ramce z funkcjami daty arkusza. Tablica $days ma nazwy w tej samej kolejności, a jej indeksy liczą się od 0, stąd date("N") - 1 (R.5.4).
Typowe błędy
date("w") numeruje dni od niedzieli (0) - z tablicą zaczynającą się od poniedziałku każdy dzień przesunie się o jeden.
Krok 41: Skrypt 1: dzisiejsza data w dwóch formatach
Kryteria:
R.5.5 Skrypt 1 ustala bieżącą datę w formacie mm-dd oraz dd-mm-yy, np. $data = date("m-d"); $dataPelna = date("d-m-Y");
ok. 2 min
Polecenie z arkusza
Wysyła do bazy danych zmodyfikowane zapytanie 2, tak że jest sprawdzana data bieżąca w formacie mm-dd. <data> oznacza bieżącą datę w formacie dd-mm-yyyy.
Ta sama data potrzebna jest dwa razy, w różnych formatach. Litery formatu funkcji date: m - miesiąc z zerem, d - dzień z zerem, Y - rok czterocyfrowy. date("m-d") daje 05-25 - format pola data w bazie, a date("d-m-Y") - 25-05-2023 do wyświetlenia (R.5.5).
R.5.3 Przynajmniej jeden skrypt zawiera instrukcję wysyłającą do bazy danych zmodyfikowane zapytanie 2 (wstawiona data z formularza lub bieżąca data)
ok. 3 min
Polecenie z arkusza
Wysyła do bazy danych zmodyfikowane zapytanie 2, tak że jest sprawdzana data bieżąca w formacie mm-dd.
Zapytanie 2, w którym zamiast stałej 05-04 stoi zmienna $today. W napisie w cudzysłowie PHP sam wstawia wartość zmiennej, a apostrofy wokół niej są dla SQL-a - porównujesz tekst. mysqli_query wysyła zapytanie, a mysqli_fetch_row pobiera jedyny wiersz wyniku jako tablicę: $row[0] to pole imiona (R.5.3).
R.5.8 Skrypt 1 wyświetla w bloku napisu treść "Dzisiaj jest <dzień tygodnia>, <data>, imieniny: <imiona>”, gdzie <dzień tygodnia> oznacza dowolny słowny zapis bieżącego dnia, <data> oznacza bieżącą datę w formacie dd-mm-yyyy, a <imiona> - pole zwrócone zapytaniem
R.5.10 W skryptach zastosowana przynajmniej jedna zmienna lub funkcja oraz nazwy wszystkich funkcji i zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania
ok. 2 min
Polecenie z arkusza
Wyświetla tekst o treści „Dzisiaj jest <dzień tygodnia>, <data>, imieniny: <imiona>”, gdzie <imiona> oznacza pole zwrócone zapytaniem.
echo z trzema zmiennymi wstawionymi w napis. Element tablicy $row[0] w cudzysłowie PHP też rozwija. W dniu z ilustracji 2 strona pokazuje: „Dzisiaj jest czwartek, 25-05-2023, imieniny: Grzegorza, Urbana, Magdaleny” (R.5.8, R.5.10).
Krok 44: Skrypt 2: czy formularz został wysłany, zamknięcie połączenia
Kryteria:
R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy kalendarz oraz ostatnią operacją na bazie jest jej zamknięcie
ok. 2 min
Polecenie z arkusza
Na końcu zamykane jest połączenie z serwerem.
Skrypt 2 stoi pod formularzem. Przy pierwszym wejściu na stronę formularz nie był wysłany i w $_POST nie ma daty - isset sprawdza, czy pole date istnieje, i tylko wtedy wykonasz zapytanie. Za blokiem if, na samym końcu, mysqli_close zamyka połączenie - to ostatnia operacja na bazie (R.5.2).
Typowe błędy
mysqli_close wewnątrz if zamyka połączenie tylko po wysłaniu formularza - przy pierwszym wejściu zostaje otwarte.
Krok 45: Skrypt 2: data z formularza w formacie bazy
Kryteria: ,
R.5.6 Skrypt 2 zawiera instrukcję pobierającą dane z tablicy globalnej odpowiadającej zastosowanej metodzie formularza ($_POST, $_GET, $_REQUEST)
R.5.7 Skrypt 2 ustala datę z formatu pola edycyjnego na format w bazie mm-dd , np. $dataDoZapytania = date("m-d", strtotime($dzien));
ok. 3 min
Polecenie z arkusza
Pobiera datę z formularza, a następnie przekształca ją do formatu mm-dd.
Pole daty wysyła wartość w formacie 2024-01-24 - odczytujesz ją z tablicy $_POST, bo formularz ma method="post" (R.5.6). strtotime zamienia napis z datą na znacznik czasu, a date("m-d", ...) formatuje go na nowo: 01-24 - jak w bazie (R.5.7). To przykład z ramki funkcji daty arkusza.
Typowe błędy
date("m-d", $date) bez strtotime kończy się w PHP 8 błędem krytycznym „date(): Argument #2 ($timestamp) must be of type ?int, string given” - drugim argumentem date musi być znacznik czasu, a nie napis z datą (sprawdzone w PHP 8.2).
R.5.9 Skrypt 2 wyświetla pod formularzem treść: "Dnia <data> są imieniny: <imiona>", gdzie <data> oznacza datę pobraną z formularza w formacie yyyy-mm-dd, <imiona> - pole zwrócone zapytaniem
R.5.10 W skryptach zastosowana przynajmniej jedna zmienna lub funkcja oraz nazwy wszystkich funkcji i zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania
ok. 2 min
Polecenie z arkusza
Wyświetla tekst o treści „Dnia <data> są imieniny: <imiona>”, gdzie <data> oznacza datę pobraną z formularza w formacie yyyy-mm-dd, <imiona> - pole zwrócone zapytaniem.
Tu wypisz datę tak, jak przyszła z formularza (rrrr-mm-dd), bez przeliczania. Po wybraniu 24 stycznia i kliknięciu „wyślij” strona pokazuje: „Dnia 2024-01-24 są imieniny: Felicji, Franciszka, Rafała” - jak na ilustracji 2. Podgląd pokazuje stronę po wysłaniu formularza (R.5.9, R.5.10).
Kroki 48-49 · po tym etapie masz 43 z 43 kryteriów (pkt)
Krok 48: Funkcja z zapytaniem przygotowanym
ok. 4 min
Polecenie z arkusza
Należy stosować znaczące nazewnictwo zmiennych i funkcji w języku polskim lub angielskim.
To samo zapytanie wykonują oba skrypty - przenosisz je do funkcji namesForDay (imiona dla dnia). W środku zapytanie przygotowane: mysqli_prepare z ? w miejscu daty i mysqli_stmt_bind_param z typem "s" (tekst). Wartość idzie do bazy osobno od treści zapytania, więc nic wpisanego przez użytkownika nie zmieni samego zapytania. Funkcja zwraca „brak danych”, gdy dnia nie ma w bazie. Wynik wypisujesz przez htmlspecialchars. Stare linie zostają w komentarzu.
Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
Pobiera datę z formularza, a następnie przekształca ją do formatu mm-dd.
Atrybuty min, max i required działają tylko w przeglądarce - żądanie można wysłać z pominięciem formularza, z dowolnym tekstem w polu date. strtotime nie odrzuca dat nieistniejących: 2024-02-31 przelicza na 2 marca, więc wersja z egzaminu wypisuje „Dnia 2024-02-31 są imieniny: Heleny, Halszki, Pawła” - imiona z zupełnie innego dnia (sprawdzone na bazie z arkusza w PHP 8.2). DateTime::createFromFormat("Y-m-d", ...) odczytuje datę tylko w oczekiwanym formacie, a porównanie wyniku z powrotem z napisem odrzuca taką datę i strona prosi o poprawną. Datę też wypisujesz przez htmlspecialchars, a zapytanie idzie przez funkcję z poprzedniego kroku.
Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
Krok 50 · po tym etapie masz 43 z 43 kryteriów (pkt)
Krok 50: 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. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę.
W folderze z numerem zdającego muszą być: imieniny.csv, import.png, kalendarz.gif, kalendarz.php, kw1.png - kw4.png, kwerendy.txt, parametry_animacji.png, przeglądarka.txt i styl.css. 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.