Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-03-21.01-SGStyczeń 2021 · 47 kroków · ok. 86 min · 40 kryteriów z klucza
Rozwiązanie krok po kroku: Kalkulator BMI z zapisem wyników (Wersja podstawowa)
Aplikacja internetowa do liczenia wskaźnika BMI: baza egzamin z tabelami bmi (przedziały wskaźnika) i wynik (zapisane pomiary), cztery zapytania (wybór pól, INSERT, relacja JOIN i warunek WHERE), ilustracja przeskalowana z zachowaniem przezroczystości oraz strona bmi.php: tabela przedziałów wypełniana skryptem z bazy i formularz, po którego wysłaniu drugi skrypt liczy BMI, wyznacza przedział i zapisuje pomiar w bazie z dzisiejszą datą.
To arkusz EE.09 ze stycznia 2021 - kwalifikacji formuły 2017, którą zastąpiła INF.03. W tej samej sesji był arkusz EE.09-04 (strona waga.php) z tą samą bazą, ale innymi zapytaniami, innym układem i odwrotną kolejnością skryptów - ma własne rozwiązanie. Kroki idą zdanie po zdaniu za treścią arkusza; skrypty są najpierw napisane najprościej, funkcjami mysqli z tabeli 1 arkusza, a na końcu sprawdzone na prawdziwych błędach i zabezpieczone.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, PDO)” jest drugi sposób rozwiązania tego samego arkusza: znaczniki <header>, <main> i <footer> z układem flex, zmienne CSS, PDO z zapytaniami przygotowanymi, walidacja liczb z formularza i przedział BMI odczytany z tabeli bmi - obie wersje są zgodne z kluczem.
Baza i grafika pochodzą z oryginalnego archiwum CKE z3.zip (załącznik na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP. Podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2, także po wysłaniu formularza danymi z obrazu 2 (waga 60, wzrost 170).
Jak liczą się punkty. Klucz ma 40 kryteriów (R.1.1 - R.5.9), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 30 punktów. 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 40 kryteriów (pkt)
Krok 1: Folder zdającego i archiwum z3.zip
ok. 2 min
Polecenie z arkusza
Aby wykonać zadanie, zaloguj się na konto Egzamin bez hasła. Na pulpicie znajdziesz archiwum ZIP o nazwie z3.zip zabezpieczone hasłem, nawiasy są częścią hasła: (Moj3BmI) Archiwum należy rozpakować. Na pulpicie konta Egzamin utwórz folder. Jako nazwy folderu użyj swojego numeru PESEL. Umieść w tym folderze rozpakowane pliki.
Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum z3.zip rozpakowujesz do tego folderu, podając hasło (Moj3BmI) - arkusz zaznacza, że nawiasy są częścią hasła, a wielkość liter ma znaczenie. W środku są trzy pliki: egzamin.sql (baza do importu), rys1.png (ilustracja do przeskalowania) i wzor.png (wzór BMI do bloku logo).
Typowe błędy
Pliki zapisane poza folderem zdającego nie trafią na płytę - a ocenia się tylko to, co jest na płycie.
Krok 2: XAMPP, baza egzamin i import egzamin.sql
ok. 2 min
Polecenie z arkusza
Do wykonania zadania należy użyć tabel: bmi oraz wynik przedstawionych na obrazie 1. Uruchom usługi MySQL i Apache za pomocą XAMPP Control Panel. Za pomocą narzędzia phpMyAdmin wykonaj podane operacje na bazie danych: Utwórz bazę danych o nazwie egzamin. Do bazy egzamin zaimportuj plik egzamin.sql z rozpakowanego archiwum
W XAMPP Control PanelStart przy Apache i MySQL, w phpMyAdmin (http://localhost/phpmyadmin) Nowa → nazwa egzamin → Utwórz, potem karta Import, plik egzamin.sql, Wykonaj. Plik zakłada sześć tabel, ale zadanie korzysta tylko z dwóch z obrazu 1: bmi (cztery przedziały wskaźnika: od - do i opis) i wynik (zapisane pomiary; pole bmi_id wskazuje przedział z tabeli bmi).
Krok 3: Zrzut import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych egzamin , czynność udokumentowano plikiem o nazwie import w formacie PNG
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z numerem PESEL, 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
Karta Struktura bazy egzamin pokazuje listę tabel z liczbą rekordów - to „elementy wskazujące na poprawnie wykonany import”. Zrzut całego ekranu z paskiem zadań zapisujesz jako import.png.
Typowe błędy
Ten zrzut jest w PNG, zrzuty kwerend w JPG - zły format albo wykadrowany zrzut nie jest oceniany.
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: przedziały BMI
Kryteria: ,
R.1.2 Zapisano plik tekstowy o nazwie kwerendy zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Utworzono zapytanie 1 wybierające jedynie pola informacja, wart_min i wart_max z tabeli bmi . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT informacja, wart_min, wart_max FROM bmi; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne są dokładnie 4 rekordy, jedynie pola informacja, wart_min, wart_max dla wartości: niedowaga, waga prawidlowa, nadwaga, otylosc
ok. 2 min
Polecenie z arkusza
Zapisz i wykonaj zapytania SQL działające na bazie egzamin. Zapytania zapisz w pliku kwerendy.txt, w folderze z numerem PESEL. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie JPG i nadaj im nazwy kw1, kw2, kw3, kw4. Zrzuty powinny obejmować cały ekran monitora z widocznym paskiem zadań. Zapytanie 1: wybierające jedynie pola informacja, wart_min i wart_max z tabeli bmi
SELECT informacja, wart_min, wart_max - „jedynie” te trzy pola, w kolejności kolumn przyszłej tabeli na stronie (bez id),
FROM bmi.
Wynik: 4 wiersze - niedowaga 0-18, waga prawidłowa 19-25, nadwaga 26-30, otyłość 31-100. Zapytanie wklejasz do kwerendy.txt, zrzut całego ekranu z wynikiem - kw1.jpg. To samo zapytanie wyśle skrypt 1.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT informacja, wart_min, wart_max FROM bmi;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: nowy pomiar w tabeli wynik
Kryteria:
R.1.4 Utworzono zapytanie 2 wstawiające do tabeli wynik rekord, o danych: klucz główny nadawany automatycznie, bmi_id = 3, data_pomiaru = 2020-05-10, wynik = 27. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO wynik(bmi_id, data_pomiaru, wynik) VALUES (3, "2020-05- 10", 27); (możliwe również bez pierwszego nawiasu lub przez listę przypisań ...SET bmi_id=3...) oraz wynik działania zapytania udokumentowano zrzutem wskazującym na poprawne wykonanie kwerendy 2
ok. 2 min
Polecenie z arkusza
Zapytanie 2: wstawiające do tabeli wynik rekord z danymi: klucz główny nadawany automatycznie, bmi_id = 3, data_pomiaru = 2020-05-10, wynik = 27
INSERT INTO wynik (bmi_id, data_pomiaru, wynik) - lista pól bez id: klucz główny ma AUTO_INCREMENT, więc baza nada go sama (tu: 2),
VALUES (3, '2020-05-10', 27) - wartości w kolejności pól; data jako tekst w apostrofach, w formacie RRRR-MM-DD.
phpMyAdmin odpowiada „1 wiersz wstawiony” - zrzut kw2.jpg. Zapytanie wykonaj raz: każde kolejne uruchomienie dopisze następny rekord.
Typowe błędy
Data bez apostrofów (2020-05-10) to dla bazy działanie odejmowania: 2020 - 5 - 10 = 2005, a nie data.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT informacja, wart_min, wart_max FROM bmi;-- Zapytanie 2INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (3, '2020-05-10', 27);
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: relacja wynik - bmi
Kryteria:
R.1.5 Utworzono zapytanie 3 wybierające jedynie pola wynik i data_pomiaru z tabeli wynik oraz informacja z tabeli bmi wykorzystano relację 1..n. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT wynik, data_pomiaru, bmi.informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id; możliwe też INNER JOIN lub bez JOIN (porównanie kluczy w warunku) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest co najmniej jeden wiersz jedynie z danymi: 20, 2020-05-24, waga prawidłowa. większa liczba wierszy wynika z wykonania kwerendy 2 lub wstawienia rekordów przez stronę ale nie z powodu nieprawidłowego przypisania kluczy w zapytaniu
ok. 3 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola wynik i data_pomiaru z tabeli wynik oraz informacja z tabeli bmi; zapytanie wykorzystuje relację
SELECT wynik, data_pomiaru, informacja - dwa pola z tabeli wynik, opis przedziału z tabeli bmi,
FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id - relacja z obrazu 1: bmi_id pomiaru wskazuje id przedziału.
Wynik po zapytaniu 2: dwa wiersze - 20, 2020-05-24, waga prawidlowa (rekord z importu) oraz 27, 2020-05-10, nadwaga. Zrzut: kw3.jpg.
Typowe błędy
Bez warunku ON baza łączy każdy pomiar z każdym przedziałem - wynik ma 8 wierszy zamiast 2.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT informacja, wart_min, wart_max FROM bmi;-- Zapytanie 2INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (3, '2020-05-10', 27);-- Zapytanie 3SELECT wynik, data_pomiaru, informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: granice nadwagi
Kryteria:
R.1.6 Utworzono zapytanie 4 wybierające jedynie pola wart_min i wart_max z tabeli bmi dla nadwagi. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT wart_min, wart_max FROM bmi WHERE informacja="nadwaga"; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest jeden wiersz jedynie z danymi 26, 30
ok. 2 min
Polecenie z arkusza
Zapytanie 4: wybierające jedynie pola wart_min i wart_max z tabeli bmi dla nadwagi (w polu informacja)
SELECT wart_min, wart_max FROM bmi z warunkiem WHERE informacja = 'nadwaga' - tekst w apostrofach, tak jak jest zapisany w bazie. Wynik: jeden wiersz 26, 30. Zrzut: kw4.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT informacja, wart_min, wart_max FROM bmi;-- Zapytanie 2INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (3, '2020-05-10', 27);-- Zapytanie 3SELECT wynik, data_pomiaru, informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id;-- Zapytanie 4SELECT wart_min, wart_max FROM bmi WHERE informacja = 'nadwaga';
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-22 · po tym etapie masz 19 z 40 kryteriów (pkt)
Krok 8: Grafika: wysokość 400 px z przezroczystością
Kryteria:
R.2.1 Plik rys1.png przeskalowano z zachowaniem proporcji do wysokości 400 px, odpowiadająca temu szerokość wynosi 330 px (± 5 px); przezroczystość została zachowana
ok. 2 min
Polecenie z arkusza
Plik rys1.png, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 400 px. Należy zachować przezroczystość obrazu
Oryginał ma 400 × 485 px i przezroczyste tło. W GIMP-ie Obraz → Skaluj obraz z zamkniętym łańcuchem proporcji, wysokość 400 px - szerokość: 400 × 400 / 485 = 329,9, czyli 330 px (klucz: 330 ±5). Zapis jako PNG - ten format przechowuje przezroczystość.
Typowe błędy
Eksport do JPG zamienia przezroczyste tło na białe albo czarne - przezroczystość jest częścią kryterium R.2.1.
Podgląd strony po tym kroku
Krok 9: Plik bmi.php
ok. 1 min
Polecenie z arkusza
Cechy witryny: Składa się ze strony o nazwie bmi.php
Plik bmi.php w folderze zdającego, obok grafik. Rozszerzenie .php, bo dojdą skrypty - na razie to czysty HTML. <!DOCTYPE html> oznacza HTML5, a lang="pl" mówi przeglądarce i czytnikom ekranu, że treść jest po polsku (arkusz tego nie wymaga).
R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie bmi oraz zastosowano właściwy standard kodowania polskich znaków
ok. 1 min
Polecenie z arkusza
Zastosowany właściwy standard kodowania polskich znaków
<meta charset="UTF-8"> jako pierwsza rzecz w <head>, a plik zapisany w UTF-8 (w Notepad++ menu Kodowanie). Klucz ocenia nazwę pliku i kodowanie razem (R.2.2) - bmi.html albo index.php to strata punktu.
R.3.5 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
<link rel="stylesheet" href="styl3.css"> w <head>. Plik stylów powstanie po HTML-u.
Typowe błędy
Klucz uznaje R.3.5 tylko wtedy, gdy wszystkie selektory trafiają w bloki - kropka zamiast # odbiera punkt. Formatowanie ma pochodzić wyłącznie z tego pliku, bez atrybutów style.
R.2.4 Wygląd strony zdefiniowano dzieląc ją na bloki: logo, baner, blok główny, lewy i prawy oraz stopka. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: obok siebie logo i baner, poniżej blok główny, poniżej bloki lewy i prawy oraz stopka. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2
Sześć znaczników <section> w kolejności z obrazu 2, każdy z identyfikatorem (nazwy po angielsku - arkusz ich nie narzuca): logo i banner w górnym rzędzie, blok główny main, bloki left i right w drugim rzędzie i stopka footer. Obok siebie ustawi je CSS.
Krok 16: Blok główny: tabela z wierszem nagłówkowym
Kryteria:
R.2.10 Pierwszy wiersz tabeli jest wierszem nagłówkowym, zastosowano znacznik <th> (opcjonalnie <thead> i <td>) oraz jego zamknięcie
ok. 2 min
Polecenie z arkusza
Zawartość bloku głównego: Tabela z trzema kolumnami. Komórki nagłówkowe w pierwszym wierszu: „Interpretacja BMI”, „Wartość minimalna”, „Wartość maksymalna”
<table> z pierwszym wierszem <tr> i trzema komórkami nagłówkowymi <th> (R.2.10). Kolejność kolumn jest taka jak pól w zapytaniu 1 (informacja, wart_min, wart_max). Kolejne wiersze („efekt działania skryptu nr 1”) wstawi skrypt przed </table>.
R.2.7 W bloku lewym umieszczono formularz, zastosowano znacznik <form> oraz jego zamknięcie
R.3.3 Formularz wysyła dane metodą POST do tego samego pliku (poprawne również gdy nie zapisano atrybutu action)
ok. 2 min
Polecenie z arkusza
Formularz wysyłający dane metodą POST do tej samej strony, zawierający: Napis „Waga:”, następnie pole edycyjne typu numerycznego o wartości minimalnej 1
<form method="post" action="bmi.php"> - formularz wysyła dane metodą POST do tej samej strony (R.3.3; klucz uznaje też formularz bez action, który wysyła do bieżącego adresu),
napis „Waga:” i pole type="number" z atrybutem min="1" - przeglądarka przyjmie tylko liczbę nie mniejszą niż 1,
name="waga" to klucz, pod którym wartość dotrze do PHP: $_POST['waga'].
<br> przenosi następne pole do nowej linii, jak na obrazie 2.
R.2.8 W formularzu umieszczono dwa pola edycyjne oraz przycisk "Oblicz i zapamiętaj wynik"
R.3.2 Przycisk wysyła dane z formularza oraz przynajmniej jedno pole do wprowadzania danych jest typu liczbowego
ok. 1 min
Polecenie z arkusza
Przycisk wysyłający zawartość formularza z opisem „Oblicz i zapamiętaj wynik”
<input type="submit"> z opisem w atrybucie value wysyła formularz. Dwa pola i przycisk (R.2.8), przycisk wysyła dane, a pola są liczbowe (R.3.2). Skrypt 2 stanie pod formularzem, w tym samym bloku.
bmi.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Twoje BMI</title> <linkrel="stylesheet"href="styl3.css"></head><body> <sectionid="logo"> <imgsrc="wzor.png"alt="wzór BMI"> </section> <sectionid="banner"> <h1>Oblicz swoje BMI</h1> </section> <sectionid="main"> <table> <tr> <th>Interpretacja BMI</th> <th>Wartość minimalna</th> <th>Wartość maksymalna</th> </tr> </table> </section> <sectionid="left"> <h2>Podaj wagę i wzrost</h2> <formmethod="post"action="bmi.php"> Waga: <inputtype="number"name="waga"min="1"><br> Wzrost w cm: <inputtype="number"name="wzrost"min="1"><br> <inputtype="submit"value="Oblicz i zapamiętaj wynik"> </form> </section> <sectionid="right"> </section> <sectionid="footer"> </section></body></html>
Podgląd strony po tym kroku (bmi.php)
Krok 21: Blok prawy: ilustracja
Kryteria:
R.2.6 W bloku logo umieszczono obraz wzor.png oraz w bloku prawym umieszczono obraz rys1.png. Przynajmniej jeden z obrazów ma tekst alternatywny: "wzór BMI" (dla wzor.png ) lub "ćwiczenia" (dla rys1.png ), gdy obraz nie istnieje powinien wyświetlać się tekst alternatywny
ok. 1 min
Polecenie z arkusza
Zawartość bloku prawego: obraz rys1.png z tekstem alternatywnym o treści: „ćwiczenia”
Przeskalowana ilustracja (330 × 400 px) z tekstem alternatywnym. Oba obrazy są na miejscu (R.2.6).
bmi.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Twoje BMI</title> <linkrel="stylesheet"href="styl3.css"></head><body> <sectionid="logo"> <imgsrc="wzor.png"alt="wzór BMI"> </section> <sectionid="banner"> <h1>Oblicz swoje BMI</h1> </section> <sectionid="main"> <table> <tr> <th>Interpretacja BMI</th> <th>Wartość minimalna</th> <th>Wartość maksymalna</th> </tr> </table> </section> <sectionid="left"> <h2>Podaj wagę i wzrost</h2> <formmethod="post"action="bmi.php"> Waga: <inputtype="number"name="waga"min="1"><br> Wzrost w cm: <inputtype="number"name="wzrost"min="1"><br> <inputtype="submit"value="Oblicz i zapamiętaj wynik"> </form> </section> <sectionid="right"> <imgsrc="rys1.png"alt="ćwiczenia"> </section> <sectionid="footer"> </section></body></html>
Zawartość stopki: Tekst: „Autor: ”, dalej wstawiony numer PESEL zdającego. Odsyłacz do pliku kwerendy.txt o treści „Zobacz kwerendy”
Na egzaminie po „Autor: ” wpisujesz swój numer PESEL - w tym rozwiązaniu w jego miejscu stoi Bartosz Bryniarski. Odsyłacz <a href="kwerendy.txt"> otwiera plik z zapytaniami z tego samego folderu (R.3.4).
Kroki 23-33 · po tym etapie masz 30 z 40 kryteriów (pkt)
Krok 23: Plik styl3.css: blok logo
ok. 1 min
Polecenie z arkusza
Cechy formatowania CSS: Dla bloku logo: tło koloru #FF7F50, szerokość 25%, wysokość 100 px
Nowy plik styl3.css w folderze zdającego - od teraz każda reguła trafia tutaj. Selektor identyfikatora z krzyżykiem #logo; #FF7F50 to koralowy pomarańcz (nazwa coral).
Dla banera: tło koloru #FF7F50, wyrównanie tekstu do środka, szerokość 75%, wysokość 100 px, rozmiar czcionki 130%
Szerokości górnego rzędu sumują się do 100% (25 + 75), oba bloki mają 100 px wysokości. font-size: 130% liczy się od czcionki rodzica; <h1> jest jeszcze dwa razy większy od tekstu swojego bloku (R.4.10).
R.4.4 Ustawiono wysokość bloku logo i banera na 100px, bloku lewego i prawego: 400px
ok. 1 min
Polecenie z arkusza
Dla bloku prawego: szerokość 60%, wysokość 400 px, wyrównanie tekstu do prawej strony
text-align: right przesuwa ilustrację (element w linii, jak tekst) do prawej krawędzi. Wysokości bloków są gotowe: górny rząd 100 px, dolny 400 px (R.4.4).
R.4.1 Ustawiono krój czcionki Georgia dla znacznika body lub kontenera całej strony
R.4.2 Ustawiono kolor tła #FFFAFA dla znacznika body lub kontenera całej strony, oraz kolor tła #FF7F50 dla bloków logo, banera, głównego i stopki
ok. 1 min
Polecenie z arkusza
Dla znacznika body: krój czcionki Georgia, kolor tła #FFFAFA
Reguła body na początku pliku - krój dziedziczą wszystkie bloki (R.4.1). #FFFAFA to prawie biały, ciepły odcień (snow) - tło bloków lewego i prawego. Wszystkie kolory tła z arkusza są gotowe (R.4.2).
R.4.7 Ustawiono marginesy wewnętrzne (padding) 70px dla bloku głównego, 20px dla stopki oraz marginesy zewnętrzne (margin) 80px dla znacznika form
ok. 1 min
Polecenie z arkusza
Dla znacznika formularza: marginesy zewnętrzne 80 px
Selektor znacznika form. margin to margines zewnętrzny - odsuwa formularz od nagłówka i od lewej krawędzi bloku, jak na obrazie 2. Marginesy wewnętrzne bloku głównego i stopki oraz ten margines są gotowe (R.4.7).
R.4.3 Ustawiono biały kolor czcionki dla znacznika tabeli
R.4.5 Ustawiono szerokość bloku logo na 25%, banera na 75%, bloku lewego na 40%, prawego na 60%, znacznika table 80%
R.4.6 Ustawiono wyrównanie tekstu do środka dla banera, znacznika tabeli oraz wyrównanie tekstu do prawej strony dla bloku prawego
R.4.8 Ustawiono obramowanie o szerokości 1px linią kropkowaną, białą dla znacznika tabeli
ok. 2 min
Polecenie z arkusza
Dla znacznika tabeli: biały kolor czcionki, wyrównanie tekstu do środka, szerokość 80%, obramowanie 1px, kropkowane, białe
Biały tekst na koralowym tle (R.4.3), tekst komórek na środku - razem z banerem i blokiem prawym wyrównania są gotowe (R.4.6). Szerokość 80% bloku głównego domyka listę szerokości (R.4.5). „Kropkowane” to dotted (dashed to kreski) - obramowanie całej tabeli (R.4.8).
R.4.9 W momencie najechania kursorem na pojedynczy wiersz tabeli kolor tła wiersza zmienia się na #D3D3D3, a czcionki na czarny (np. za pomocą pseudoklasy hover)
ok. 1 min
Polecenie z arkusza
W momencie najechania kursorem na pojedynczy wiersz tabeli, kolor tła wiersza zmienia się na #D3D3D3 a czcionki na czarny
Pseudoklasa :hover na selektorze wiersza tr - reguła działa tylko dla wiersza pod kursorem: jasnoszare tło (lightgray) i czarny tekst, który komórki dziedziczą zamiast białego z tabeli.
R.3.1 Wygląd układu bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z obrazem 2 w arkuszu egzaminacyjnym
ok. 3 min
Polecenie z arkusza
Podział strony na bloki: obok siebie logo i baner, poniżej blok główny, poniżej bloki lewy i prawy oraz stopka. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2
Cztery bloki o zadanej szerokości dostają float: left: logo i baner stają w jednym rzędzie (25% + 75%), lewy i prawy w drugim (40% + 60%). Blok główny i stopka mają clear: both - każdy zaczyna się pod opływanymi blokami i zajmuje całą szerokość. Klucz R.3.1 ocenia wygląd w przeglądarce - wersja nowoczesna pokazuje ten sam układ na flex.
Typowe błędy
Bloki o sumie szerokości 100% nie mogą mieć bocznych marginesów, obramowań ani padding - drugi blok rzędu spadłby niżej. Marginesy z arkusza dostają tylko bloki na całą szerokość: główny i stopka.
Kroki 34-38 · po tym etapie masz 36 z 40 kryteriów (pkt)
Krok 34: Skrypt 1: połączenie z bazą egzamin
Kryteria: ,
R.5.1 Skrypt napisano w języku PHP i zawiera on co najmniej jedną instrukcję poprawną składniowo
R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy egzamin
ok. 3 min
Polecenie z arkusza
Napisany w języku PHP, w pliku bmi.php. Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin
Skrypt 1 wypełnia tabelę, więc jego blok PHP stoi wewnątrz<table>, zaraz pod wierszem nagłówkowym - to, co wypisze, trafi dokładnie tam. Kod piszesz między <?php a ?>; serwer wykona go, zanim strona trafi do przeglądarki.
Pierwsza instrukcja: mysqli_connect z tabeli 1 arkusza - serwer localhost, użytkownik root, puste hasło '' i baza egzamin (połączenie i wybór bazy w jednej funkcji, R.5.1, R.5.2). Połączenie trafia do zmiennej $connection.
Od tego kroku podgląd to wynik działania strony na serwerze (prawdziwe uruchomienie w PHP 8.2). Stronę sprawdzasz przez http://localhost/… - przeglądarka sama nie wykona PHP.
R.5.5 Skrypt 1 wysyła do bazy danych zapytanie 1 lub Skrypt 2 wysyła do bazy zmodyfikowane zapytanie 2 tak, że dane wstawiane do tabeli są wyliczone z danych formularza lub zwrócone funkcją PHP np. date('Y-m-d')
ok. 2 min
Polecenie z arkusza
Działanie skryptu 1: Wysyła do bazy danych zapytanie 1
mysqli_query wysyła zapytanie 1 przepisane z kwerendy.txt (R.5.5). Wynik - cztery wiersze - trafia do zmiennej $result; trzeba je jeszcze z niego pobrać.
Krok 36: Skrypt 1: pętla po wierszach i pierwsza komórka
ok. 3 min
Polecenie z arkusza
Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
mysqli_fetch_row($result) pobiera kolejny wiersz wyniku jako tablicę numerowaną od zera: $row[0] to informacja, $row[1] wartość minimalna, $row[2] maksymalna,
while powtarza to, dopóki funkcja zwraca wiersz,
echo wypisuje wiersz <tr> z pierwszą komórką <td> - w napisie w cudzysłowie "…" PHP podstawia wartość $row[0], a \n kończy linię w źródle strony.
Podgląd: cztery wiersze z samym opisem przedziału - liczby dojdą w następnym kroku.
R.2.9 W bloku głównym umieszczono tabelę o trzech kolumnach i przynajmniej jednym wierszem danych, użyto znaczniki <table>, <tr>, <td> i ich zamknięcia; generowana skryptem lub HTML
R.5.6 Skrypt 1 wyświetla otrzymane dane w komórkach tabeli zgodnie z obrazem 2 arkusza egzaminacyjnego
ok. 2 min
Polecenie z arkusza
Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
Do wiersza dochodzą dwie komórki z granicami przedziału. Tabela ma trzy kolumny i cztery wiersze danych w znacznikach <tr> i <td> (R.2.9), a dane stoją w odpowiednich komórkach, jak na obrazie 2 (R.5.6).
R.5.3 Po wykonaniu operacji na bazie zastosowano funkcję zamknięcia bazy
ok. 1 min
Polecenie z arkusza
Po wykonaniu operacji na bazie skrypt zamyka połączenie z serwerem
mysqli_close($connection) po pętli - wszystkie wiersze są już wypisane (R.5.3). Skrypt 2 otworzy własne połączenie, tylko wtedy, gdy będzie miał co zapisać.
Typowe błędy
mysqli_close przed pętlą zamknie połączenie, zanim wiersze zostaną pobrane.
Kroki 39-43 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 39: Skrypt 2: odebranie danych z formularza
Kryteria:
R.5.4 W skrypcie działającym na danych przesłanych przez formularz zastosowano tablicę $_POST, zapis musi być poprawny składniowo i logicznie
ok. 3 min
Polecenie z arkusza
Działanie skryptu 2, który odbiera dane przesłane z formularza: Skrypt odbiera dane z dwóch pól edycyjnych. Jeśli przynajmniej jedno pole edycyjne jest puste, nie jest wykonywana żadna akcja
Skrypt 2 wypisuje wynik pod formularzem, więc jego blok PHP stoi w bloku lewym, za </form>.
Wartości pól wysłanych metodą POST są w tablicy $_POST, pod nazwami z atrybutów name (R.5.4),
empty jest prawdziwe dla pustego pola (i dla pola, którego w ogóle nie wysłano - przy pierwszym wejściu na stronę), więc warunek z && przepuszcza tylko wtedy, gdy wypełniono oba pola. W przeciwnym razie skrypt nic nie robi - tak każe arkusz,
wartości trafiają do zmiennych $waga i $wzrost.
Podgląd: strona po wysłaniu formularza danymi z obrazu 2 (60 i 170) - skrypt jeszcze nic nie wypisuje.
R.5.7 Skrypt 2 liczy wskaźnik BMI na podstawie danych z formularza, wzór np. $waga / ($wzrost * $wzrost) * 10000;
ok. 2 min
Polecenie z arkusza
Jeżeli wpisano dane, skrypt liczy wskaźnik BMI zgodnie ze wzorem znajdującym się na obrazie wzor.png (otrzymaną wartość należy pomnożyć przez 10000, gdyż wzrost podany jest w centymetrach)
Wzór z wzor.png: masa podzielona przez kwadrat wzrostu. Wzór liczy wzrost w metrach, a formularz podaje go w centymetrach: 170 cm to 1,7 m, a 170² jest 10 000 razy większe niż 1,7², stąd mnożenie przez 10000 (R.5.7). Nawias ($wzrost * $wzrost) jest konieczny - bez niego PHP podzieli wagę przez wzrost i wynik znów pomnoży przez wzrost. Dla 60 kg i 170 cm: 60 / 28 900 × 10 000 ≈ 20,76.
Typowe błędy
$waga / $wzrost * $wzrost * 10000 bez nawiasu daje 600 000 - działania o tym samym priorytecie PHP wykonuje od lewej.
R.5.8 Skrypt 2 wyświetla dane i obliczenia według wzoru: „Twoja waga: <podana_waga>; Twój wzrost: <podany_wzrost> BMI wynosi: <obliczona_wartość>”
ok. 2 min
Polecenie z arkusza
Dane i obliczenia są wyświetlone według wzoru: „Twoja waga: <podana_waga>; Twój wzrost: <podany_wzrost> BMI wynosi: <obliczona_wartość>”, łamanie linii przed „BMI”
Jeden echo z napisem w cudzysłowie, w który PHP podstawia trzy zmienne; <br> łamie linię przed „BMI” (R.5.8). Podgląd po wysłaniu 60 i 170: „Twoja waga: 60; Twój wzrost: 170”, a pod spodem „BMI wynosi: 20.76124567474” - dokładnie jak na obrazie 2 (PHP wypisuje liczbę zmiennoprzecinkową z 14 cyframi znaczącymi). Sprawdzone też: przy pierwszym wejściu i przy pustym polu wzrostu strona nie pokazuje nic.
R.5.9 Skrypt 2 wyznacza przedział BMI, zgodnie z tabelą bmi w bazie danych i przypisuje wartość 1 dla niedowagi, 2 dla wagi prawidłowej, 3 dla nadwagi i 4 dla otyłości (sprawdzić dla danych, które mieszczą się w przedziałach z tabeli bmi widocznej na obrazie 2 arkusza egzaminacyjnego)
ok. 3 min
Polecenie z arkusza
Następnie skrypt wyznacza przedział BMI, zgodnie z wartościami, jakie są umieszczone w tabeli i przypisuje wartość 1 dla niedowagi, 2 dla wagi prawidłowej, 3 dla nadwagi i 4 dla otyłości
Granice biorę z tabeli bmi (zapytanie 1): niedowaga do 18, waga prawidłowa 19-25, nadwaga 26-30, otyłość od 31. Tabela trzyma liczby całkowite, a BMI ma część ułamkową - wynik 18,6 nie mieści się ani w 0-18, ani w 19-25. Dlatego warunki porównują z początkiem następnego przedziału: poniżej 19 - niedowaga (1), poniżej 26 - waga prawidłowa (2), poniżej 31 - nadwaga (3), w pozostałych przypadkach otyłość (4) (R.5.9).
Drabinka if / elseif / else sprawdza warunki po kolei i zatrzymuje się na pierwszym prawdziwym, więc w drugim warunku nie trzeba już pisać $bmi >= 19. Dla 20,76 wychodzi przedział 2.
Typowe błędy
Warunki typu $bmi >= 19 && $bmi <= 25 zostawiają dziury między przedziałami: BMI 25,5 nie trafi nigdzie i rekord nie zostanie zapisany.
Skrypt wysyła do bazy danych zmodyfikowane zapytanie 2 wstawiające dane do bazy: bmi_id – wyznaczony przedział np. 3, jeśli obliczone BMI to nadwaga; data_pomiaru – aktualna data wyznaczona funkcją PHP, w formacie Y-m-d; wynik – obliczony wskaźnik BMI
Zapytanie 2 z kwerendy.txt z wartościami zamienionymi na zmienne:
mysqli_connect - nowe połączenie (pierwsze zamknął skrypt 1),
date('Y-m-d') zwraca dzisiejszą datę w formacie bazy, np. 2026-11-10,
INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES ($przedzial, '$data', $bmi) - przedział, data w apostrofach i wynik (R.5.5 jest już spełnione zapytaniem 1, a to drugi sposób z klucza),
mysqli_close po zapisie.
Sprawdzone w bazie po wysłaniu 60 i 170: nowy rekord ma bmi_id = 2 i dzisiejszą datę, a w polu wynik jest 21 - kolumna jest typu całkowitego (int), więc baza zaokrągla 20,76 do liczby całkowitej. Dla wag 54, 80 i 95 kg przy 170 cm (BMI 18,7, 27,7 i 32,9) zapisały się przedziały 1, 3 i 4.
Typowe błędy
Formularz wysyłany ponownie (odświeżenie strony po wysłaniu, F5) dopisuje kolejny rekord - przeglądarka pyta wtedy o ponowne przesłanie danych.
Kroki 44-46 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 44: Zabezpieczenie: tylko liczby dodatnie z formularza
ok. 4 min
Polecenie z arkusza
Działanie skryptu 2, który odbiera dane przesłane z formularza: Skrypt odbiera dane z dwóch pól edycyjnych. Jeśli przynajmniej jedno pole edycyjne jest puste, nie jest wykonywana żadna akcja
Pole type="number" pilnuje liczby tylko w przeglądarce - dane do serwera da się wysłać z pominięciem formularza (np. programem curl albo zmienionym w narzędziach F12 polem). Sprawdzone na wersji z poprzednich kroków:
wzrost „0.0” (warunek empty przepuszcza go, bo to nie jest ani pusty napis, ani „0”) - „Fatal error: Uncaught DivisionByZeroError: Division by zero”,
oba z pełną ścieżką do pliku na serwerze. Nowy warunek wpuszcza tylko wartości, dla których is_numeric zwraca prawdę i które są większe od zera; ?? '' podstawia pusty napis, gdy pola nie wysłano. Pusty napis nie jest liczbą, więc zachowanie z arkusza („pole puste - brak akcji”) zostaje. Przy okazji znika ryzyko wstrzyknięcia HTML-a przez wypisywaną wagę: napis <b>60</b> nie jest liczbą. Stara linia zostaje w komentarzu; na egzaminie klucz tego nie sprawdza.
Krok 45: Zabezpieczenie: błąd bazy bez szczegółów serwera
ok. 3 min
Polecenie z arkusza
Napisany w języku PHP, w pliku bmi.php. Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin
Od PHP 8.1 funkcje mysqli przy błędzie rzucają wyjątek. Sprawdzone: bez bazy egzamin strona urywa się w połowie tabeli, a zamiast reszty pojawia się „Fatal error: Uncaught mysqli_sql_exception: Unknown database 'egzamin'” z pełną ścieżką do pliku na serwerze - formularz i ilustracja w ogóle się nie wyświetlają.
Oba skrypty trafiają do bloków try. W skrypcie 1 catch (mysqli_sql_exception $exception) wypisuje jeden wiersz tabeli z neutralnym komunikatem (colspan="3" - komórka na całą szerokość), w skrypcie 2 - zdanie „Nie udało się zapisać wyniku” pod obliczonym BMI. Podgląd: strona uruchomiona bez bazy, po wysłaniu formularza - wynik się liczy, reszta strony działa.
Krok 46: Zabezpieczenie: htmlspecialchars na danych z bazy
ok. 2 min
Polecenie z arkusza
Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
Skrypt 1 wkleja do strony wszystko, co jest w bazie - także znaczniki HTML. Sprawdzone: opis przedziału zmieniony na nadwaga <s>tak</s> wersja z poprzednich kroków wyświetla z przekreślonym słowem. Tak samo trafiłby na stronę znacznik <script> - kod JavaScript uruchomiony u każdego gościa (atak XSS).
htmlspecialchars zamienia <, >, & i cudzysłowy na encje, więc przeglądarka pokazuje je jako tekst; array_map przepuszcza przez nią wszystkie komórki wiersza naraz. Podgląd: ten sam opis widać dosłownie.
Krok 47 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 47: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
Po zakończeniu pracy utwórz plik tekstowy. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny, zapisz go w folderze z numerem PESEL, jako przeglądarka.txt. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę przez http://localhost/…. W folderze zdającego muszą być: bmi.php, import.png, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, przeglądarka.txt, przeskalowany rys1.png, styl3.css i wzor.png. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem PESEL.
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.