Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-03-21.01-SGStyczeń 2021 · 28 kroków · ok. 63 min · 40 kryteriów z klucza
Rozwiązanie krok po kroku: Kalkulator BMI z zapisem wyników (Nowoczesny kod (flex, PDO))
To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza egzamin z czterema zapytaniami, przeskalowana ilustracja z przezroczystością i strona bmi.php z tabelą przedziałów oraz formularzem, który liczy BMI i zapisuje pomiar - i tak samo spełnia każde kryterium klucza. Inna jest droga:
znaczniki <header>, <main> i <footer>: logo i baner to sekcje w nagłówku strony, bloki lewy i prawy stoją w kontenerze, a w rzędy ustawia je display: flex zamiast float i clear,
zmienne CSS dla kolorów z arkusza, etykiety <label> przy polach formularza,
PHP na PDO na górze pliku, przed HTML-em: odczyt danych z formularza z walidacją liczb, obliczenie, odczyt i zapis w bazie w jednym miejscu, a w HTML-u zostaje tylko wypisanie,
przedział BMI odczytany z tabeli bmi zapytaniem przygotowanym zamiast granic wpisanych w kod,
funkcja e() (htmlspecialchars) przy każdej wypisywanej wartości, try/catch/finally z zamknięciem połączenia w każdym przypadku.
To arkusz EE.09 ze stycznia 2021 - kwalifikacji formuły 2017, którą zastąpiła INF.03. 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; klucz przyjmuje zarówno mysqli, jak i PDO.
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.
Folder na pulpicie nazwany numerem PESEL - w tym rozwiązaniu Bartosz Bryniarski. Archiwum z3.zip rozpakuj do niego, hasło (Moj3BmI) razem z nawiasami. W środku: egzamin.sql, rys1.png i wzor.png.
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.
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
Trzy pola w kolejności kolumn tabeli na stronie. Wynik: 4 przedziały (niedowaga 0-18, waga prawidłowa 19-25, nadwaga 26-30, otyłość 31-100). Zapytanie do kwerendy.txt, zrzut 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.
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.
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-14 · 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ść.
Podgląd strony po tym kroku
Krok 9: Plik bmi.php: nagłówek dokumentu
Kryteria: , ,
R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie bmi oraz zastosowano właściwy standard kodowania polskich znaków
R.2.3 Nadano tytuł strony: "Twoje BMI”
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. 2 min
Polecenie z arkusza
Cechy witryny: Składa się ze strony o nazwie bmi.php. Zastosowany właściwy standard kodowania polskich znaków. Tytuł strony widoczny na karcie przeglądarki: „Twoje BMI”. Arkusz stylów w pliku o nazwie styl3.css prawidłowo połączony z kodem strony
Cała część <head> w jednym kroku:
<!DOCTYPE html> - HTML5, lang="pl" - język treści,
<meta charset="UTF-8"> jako pierwszy element <head> (R.2.2 - razem z nazwą pliku bmi.php),
<title>Twoje BMI</title> (R.2.3),
<meta name="viewport"> - telefon pokazuje stronę w swojej szerokości (arkusz tego nie wymaga),
<link rel="stylesheet" href="styl3.css"> (R.3.5 - punkt przyznawany razem z poprawnymi selektorami).
Krok 10: Bloki: nagłówek z logo i banerem, część główna, kolumny, stopka
Kryteria:
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
<header> z sekcjami logo i banner, <main> - blok główny (jeden na stronie, więc bez identyfikatora), kontener <div class="columns"> z sekcjami left i right oraz <footer> - stopka. Znaczniki HTML5 mówią, czym jest każda część strony; <header> i kontener kolumn dostaną w CSS display: flex.
Zawartość bloku logo: obraz wzor.png z tekstem alternatywnym „wzór BMI”. Zawartość bloku banera: nagłówek pierwszego stopnia o treści „Oblicz swoje BMI”
Obraz wzoru z tekstem alternatywnym i nagłówek <h1> - poziom narzucony przez arkusz.
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”
Tabela z wierszem nagłówkowym w <thead> (klucz wprost dopuszcza <thead>, R.2.10) i pustym <tbody>, w którym skrypt wypisze przedziały.
R.2.5 W bloku banera zapisano nagłówek h1: "Oblicz swoje BMI", w bloku lewym nagłówek h2: "Podaj wagę i wzrost"
R.2.7 W bloku lewym umieszczono formularz, zastosowano znacznik <form> oraz jego zamknięcie
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
R.3.3 Formularz wysyła dane metodą POST do tego samego pliku (poprawne również gdy nie zapisano atrybutu action)
ok. 3 min
Polecenie z arkusza
Zawartość bloku lewego: Nagłówek drugiego stopnia o treści: „Podaj wagę i wzrost”. 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. Napis „Wzrost w cm:”, następnie pole edycyjne typu numerycznego o wartości minimalnej 1. Przycisk wysyłający zawartość formularza z opisem „Oblicz i zapamiętaj wynik”
<h2> - razem z <h1> banera nagłówki są gotowe (R.2.5),
<form method="post">bez action wysyła dane do bieżącego adresu, czyli do tej samej strony (R.2.7, R.3.3),
napisy w <label for="…">: kliknięcie napisu ustawia kursor w polu, a czytnik ekranu odczyta go razem z polem,
dwa pola type="number" z min="1" i nazwami waga, wzrost oraz <button type="submit"> z opisem z arkusza (R.2.8, R.3.2).
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
Zawartość bloku prawego: obraz rys1.png z tekstem alternatywnym o treści: „ćwiczenia”. Zawartość stopki: Tekst: „Autor: ”, dalej wstawiony numer PESEL zdającego. Odsyłacz do pliku kwerendy.txt o treści „Zobacz kwerendy”
Ilustracja 330 × 400 px z tekstem alternatywnym (R.2.6). W stopce po „Autor: ” na egzaminie stoi numer PESEL, tu Bartosz Bryniarski, i odsyłacz do kwerendy.txt (R.3.4).
Kroki 15-21 · po tym etapie masz 30 z 40 kryteriów (pkt)
Krok 15: Zmienne kolorów i selektor body
Kryteria:
R.4.1 Ustawiono krój czcionki Georgia dla znacznika body lub kontenera całej strony
ok. 2 min
Polecenie z arkusza
Cechy formatowania CSS: Dla znacznika body: krój czcionki Georgia, kolor tła #FFFAFA
Reguła :root z zmiennymi CSS - kolory z arkusza dostają nazwy, a reguły odwołują się do nich przez var(--coral). Reguła body: Georgia z zapasowym krojem szeryfowym (R.4.1) i jasne tło.
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. 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
display: flex na <header> i kontenerze .columns ustawia ich sekcje w rzędzie. <main> i <footer> stoją między nimi zwykłymi blokami na całą szerokość - bez float i clear. Klucz ocenia układ w przeglądarce (R.3.1), a szerokości 25/75 i 40/60 stoją na samych blokach, jak oczekuje R.4.5.
Dla bloku logo: tło koloru #FF7F50, szerokość 25%, wysokość 100 px. Dla banera: tło koloru #FF7F50, wyrównanie tekstu do środka, szerokość 75%, wysokość 100 px, rozmiar czcionki 130%
Oba bloki 100 px wysokości, szerokości 25 + 75 = 100%, rozmiar czcionki banera 130% (R.4.10).
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
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. 2 min
Polecenie z arkusza
Dla znacznika tabeli: biały kolor czcionki, wyrównanie tekstu do środka, szerokość 80%, obramowanie 1px, kropkowane, białe. W momencie najechania kursorem na pojedynczy wiersz tabeli, kolor tła wiersza zmienia się na #D3D3D3 a czcionki na czarny
Biały tekst (R.4.3), wyrównanie do środka (R.4.6 razem z banerem i blokiem prawym), szerokość 80% (R.4.5), kropkowane białe obramowanie (R.4.8) i pseudoklasa tr:hover (R.4.9).
Kroki 22-23 · po tym etapie masz 36 z 40 kryteriów (pkt)
Krok 22: PDO: połączenie, zapytanie 1 i zamknięcie
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
R.5.3 Po wykonaniu operacji na bazie zastosowano funkcję zamknięcia bazy
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. 4 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. Działanie skryptu 1: Wysyła do bazy danych zapytanie 1. Po wykonaniu operacji na bazie skrypt zamyka połączenie z serwerem
Logika PHP stoi na górze pliku, przed <!DOCTYPE html> - najpierw dane, potem HTML, który je wypisuje.
e() zamienia wartość na tekst i przepuszcza go przez htmlspecialchars, więc znaki <, >, & i cudzysłowy pokażą się jako tekst,
new PDO(...) - localhost, baza egzamin w adresie DSN, root, puste hasło (R.5.1, R.5.2), PDO::ERRMODE_EXCEPTION - błąd bazy rzuca wyjątek,
$pdo->query(...)->fetchAll(PDO::FETCH_ASSOC) - zapytanie 1 (R.5.5) i cztery przedziały w tablicy $ranges, z polami dostępnymi po nazwach,
catch zapisuje neutralny komunikat, a finally wykonuje się po sukcesie i po błędzie: $pdo = null zamyka połączenie (R.5.3).
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. 3 min
Polecenie z arkusza
Dane otrzymane z bazy są umieszczane w kolejnych wierszach tabeli, w odpowiednich komórkach, tak jak na Obrazie 2
Pętla w składni alternatywnejforeach (...): / endforeach;, między nimi zwykły HTML wiersza, a w komórkach skrócone <?= ... ?> z e(). Trzy komórki w kolejności nagłówków (R.2.9, R.5.6); przy awarii bazy - jeden wiersz z komunikatem. Podgląd: cztery przedziały, jak na obrazie 2.
Kroki 24-26 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 24: Dane z formularza, obliczenie i wypisanie wyniku
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
R.5.7 Skrypt 2 liczy wskaźnik BMI na podstawie danych z formularza, wzór np. $waga / ($wzrost * $wzrost) * 10000;
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. 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. 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). 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”
$_POST['waga'] ?? null - wartość pola albo null, gdy formularza nie wysłano (R.5.4),
filter_var(..., FILTER_VALIDATE_FLOAT, ['options' => ['min_range' => 1]]) zwraca liczbę albo false - dla pustego pola, tekstu, zera i liczby mniejszej od 1. Warunek !== false dla obu pól daje zachowanie z arkusza: puste pole - brak akcji, a przy okazji żaden tekst ani zero nie trafi do dzielenia,
wzór z wzor.png z mnożeniem przez 10 000, bo wzrost jest w centymetrach (R.5.7),
w bloku lewym, pod formularzem, if (...): / endif; wypisuje paragraf z danymi i wynikiem, z <br> przed „BMI” (R.5.8).
Podgląd po wysłaniu 60 i 170: „BMI wynosi: 20.76124567474”, jak na obrazie 2. Sprawdzone też: pierwsze wejście, puste pole, tekst zamiast liczby i wzrost 0 - strona nie wypisuje wyniku i nie zgłasza błędu.
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
Zamiast przepisywać granice do kodu, skrypt pyta o nie tabelę bmi: SELECT id FROM bmi WHERE wart_min <= ? ORDER BY wart_min DESC LIMIT 1 - spośród przedziałów, które zaczynają się nie wyżej niż obliczone BMI, bierze ten o największym początku. Identyfikatory w tabeli to dokładnie numery z arkusza: 1 niedowaga, 2 waga prawidłowa, 3 nadwaga, 4 otyłość (R.5.9).
Porównanie z samym początkiem przedziału zamyka dziury między granicami całkowitymi (BMI 18,6 trafia do niedowagi, 25,5 - do wagi prawidłowej), a gdyby ktoś zmienił granice w bazie, skrypt od razu je uwzględni. BMI pochodzi z obliczeń, ale trafia do zapytania jako parametr ? zapytania przygotowanego (prepare + execute) - dane nigdy nie są doklejane do treści SQL.
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 trzema parametrami ?, a w execute ich wartości w tej samej kolejności: przedział, date('Y-m-d') (dzisiejsza data w formacie bazy) i obliczone BMI. Nie trzeba pilnować apostrofów wokół daty - zajmuje się tym PDO.
Zapis ma własny try/catch: gdy się nie powiedzie, pod wynikiem pojawi się „Nie udało się zapisać wyniku”, a BMI i tak jest wyświetlone. Sprawdzone w bazie po wysłaniu 60 i 170: rekord z bmi_id = 2, dzisiejszą datą (2026-11-10) i wynikiem 21 - kolumna wynik jest całkowita, więc baza zapisuje wartość bez części ułamkowej. Dla 54, 74, 80 i 95 kg przy 170 cm zapisały się przedziały 1, 2, 3 i 4.
Typowe błędy
Formularz wysyłany ponownie (F5 po wysłaniu) dopisuje kolejny rekord. Typowa odpowiedź na to - przekierowanie po zapisie (wzorzec PRG) - wymagałaby przechowania wyniku do wyświetlenia (np. w sesji), a arkusz każe pokazać wynik w odpowiedzi na wysłanie formularza.
Krok 27 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 27: Co jest inaczej i którą wersję wybrać na egzaminie
ok. 3 min
Obie wersje dają komplet 40 punktów. Różnice:
wersja podstawowa
wersja nowoczesna
bloki
sześć <section> jedna pod drugą
<header>, <main>, kontener kolumn i <footer>
układ
float: left i clear: both
display: flex na <header> i .columns
kolory
wpisane w każdej regule
zmienne --coral, --snow, --light-gray
formularz
napisy przed polami, <input type="submit">
<label for> i <button>
biblioteka
mysqli (tabela 1 arkusza), dwa połączenia
PDO z wyjątkami, jedno połączenie
dane z formularza
empty (w Dobrych praktykach is_numeric)
filter_var z FILTER_VALIDATE_FLOAT
przedział BMI
drabinka if z granicami w kodzie
zapytanie do tabeli bmi
zapis
INSERT z wklejonymi zmiennymi
zapytanie przygotowane z ?
wypisywanie
wprost (zabezpieczone w Dobrych praktykach)
zawsze przez e()
błąd bazy
„Fatal error” ze ścieżką pliku
catch i komunikat, wynik BMI dalej widoczny
Sprawdzone na prawdziwym PHP: opis przedziału ze znacznikiem <s> ta wersja pokazuje dosłownie, a bez bazy egzamin strona wyświetla tabelę z komunikatem „Baza danych jest chwilowo niedostępna”, liczy BMI i informuje, że wyniku nie zapisano.
Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 arkusza i łatwiej ją napisać bez dokumentacji; nowoczesna oddziela logikę od wyglądu i nie wywraca się na złych danych ani przy awarii bazy - klucz przyjmuje obie.
Krok 28 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 28: 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 nazwa przeglądarki, w której sprawdzana była strona. W folderze zdającego: bmi.php, import.png, kw1.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.