Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-04-21.01-SGStyczeń 2021 · 48 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 (INSERT, wybór pól, relacja JOIN i warunek WHERE), ilustracja przeskalowana z zachowaniem przezroczystości oraz strona waga.php: formularz, po którego wysłaniu skrypt 1 liczy BMI, wyznacza przedział i zapisuje pomiar w bazie z dzisiejszą datą, oraz tabela przedziałów wypełniana skryptem 2 z bazy.
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-03 (strona bmi.php) z tą samą bazą, ale innymi zapytaniami, innym układem, inną ilustracją 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 z4.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 70, 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 z4.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 z4.zip zabezpieczone hasłem: #Wylicz3ni4BMI^ 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 z4.zip rozpakowujesz do tego folderu, podając hasło #Wylicz3ni4BMI^ (z krzyżykiem na początku i daszkiem na końcu; 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) 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: nowy pomiar w tabeli wynik
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 wstawiające do tabeli wynik rekord o danych: klucz główny nadawany automatycznie, bmi_id = 1, data_pomiaru = 2020-05-20, wynik = 15. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO wynik(bmi_id, data_pomiaru, wynik) VALUES (1, "2020-05- 20", 15); (możliwe bez pierwszego nawiasu lub przez listę przypisań) oraz wynik działania zapytania udokumentowano zrzutem na którym widoczne jest poprawne zapytanie lub dodany rekord w tabeli
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: wstawiające do tabeli wynik rekord o danych: klucz główny nadawany automatycznie, bmi_id = 1, data_pomiaru = 2020-05-20, wynik = 15
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 (1, '2020-05-20', 15) - wartości w kolejności pól; data jako tekst w apostrofach, w formacie RRRR-MM-DD.
Zapytanie wklejasz do kwerendy.txt; phpMyAdmin odpowiada „1 wiersz wstawiony” - zrzut całego ekranu to kw1.jpg. Zapytanie wykonaj raz: każde kolejne uruchomienie dopisze następny rekord.
Typowe błędy
Data bez apostrofów (2020-05-20) to dla bazy działanie odejmowania: 2020 - 5 - 20 = 1995, a nie data.
kwerendy.txtTekstnowy plik
-- Zapytanie 1INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (1, '2020-05-20', 15);
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: przedziały BMI
Kryteria:
R.1.4 Utworzono zapytanie 2 wybierające jedynie pola id, informacja i wart_min z tabeli bmi . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, informacja, wart_min FROM bmi; oraz wynik działania zapytania udokumentowano zrzutem, na którym są widoczne dokładnie cztery rekordy o id= 1, 2, 3, 4, jedynie pola id, informacja, wart_min
ok. 2 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola id, informacja i wart_min z tabeli bmi
SELECT id, informacja, wart_min - „jedynie” te trzy pola, w kolejności kolumn tabeli na stronie („lp.”, „Interpretacja”, „zaczyna się od…”),
FROM bmi.
Wynik: 4 wiersze o id 1-4 - niedowaga od 0, waga prawidłowa od 19, nadwaga od 26, otyłość od 31. Zrzut: kw2.jpg - do tego pliku prowadzi odsyłacz w stopce strony. To samo zapytanie wyśle skrypt 2.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (1, '2020-05-20', 15);-- Zapytanie 2SELECT id, informacja, wart_min FROM bmi;
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 z tabeli wynik oraz informacja z tabeli bmi . Wykorzystano relację. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT wynik, bmi.informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id; możliwe 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, waga prawidlowa. większa liczba wierszy wynika z wykonania kwerendy 1 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 z tabeli wynik oraz informacja z tabeli bmi; zapytanie wykorzystuje relację
SELECT wynik, informacja - wynik pomiaru z tabeli wynik i opis przedziału z tabeli bmi,
FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id - relacja z obrazu 1.
Wynik po zapytaniu 1: dwa wiersze - 20, waga prawidlowa (rekord z importu) oraz 15, niedowaga. 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 1INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (1, '2020-05-20', 15);-- Zapytanie 2SELECT id, informacja, wart_min FROM bmi;-- Zapytanie 3SELECT wynik, informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: granice niedowagi
Kryteria:
R.1.6 Utworzono zapytanie 4 wybierające jedynie pola wart_min i wart_max z tabeli bmi dla niedowagi. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT wart_min, wart_max FROM bmi WHERE informacja="niedowaga"; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest dokładnie jeden wiersz jedynie z danymi 0, 18
ok. 2 min
Polecenie z arkusza
Zapytanie 4: wybierające jedynie pola wart_min i wart_max z tabeli bmi dla niedowagi (pole informacja)
SELECT wart_min, wart_max FROM bmi z warunkiem WHERE informacja = 'niedowaga'. Wynik: jeden wiersz 0, 18. Zrzut: kw4.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (1, '2020-05-20', 15);-- Zapytanie 2SELECT id, informacja, wart_min FROM bmi;-- Zapytanie 3SELECT wynik, informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id;-- Zapytanie 4SELECT wart_min, wart_max FROM bmi WHERE informacja = 'niedowaga';
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ść 300 px z przezroczystością
Kryteria:
R.2.1 Plik rys1.png przeskalowano z zachowaniem proporcji do wysokości 300 px, odpowiadająca temu szerokość wynosi 364 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 300 px. Należy zachować przezroczystość obrazu
Oryginał ma 400 × 330 px i przezroczyste tło. W GIMP-ie Obraz → Skaluj obraz z zamkniętym łańcuchem proporcji, wysokość 300 px - szerokość: 400 × 300 / 330 = 363,6, czyli 364 px (klucz: 364 ±5). Zapis jako PNG - ten format przechowuje przezroczystość.
Typowe błędy
Eksport do JPG zamienia przezroczyste tło na jednolity kolor - przezroczystość jest częścią kryterium R.2.1.
Podgląd strony po tym kroku
Krok 9: Plik waga.php
ok. 1 min
Polecenie z arkusza
Cechy witryny: Składa się ze strony o nazwie waga.php
Plik waga.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 waga 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) - waga.html albo bmi.php to strata punktu.
R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl4.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 styl4.css prawidłowo połączony z kodem strony
<link rel="stylesheet" href="styl4.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: baner, logo, blok lewy i prawy, główny oraz stopka. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: obok siebie baner i logo, poniżej blok lewy i prawy, następnie główny 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): banner i logo w górnym rzędzie (baner po lewej), left i right w drugim rzędzie, pod nimi blok główny main i stopka footer. Obok siebie ustawi je CSS.
R.2.6 W bloku logo umieszczono obraz wzor.png oraz w bloku lewym umieszczono obraz rys1.png. Przynajmniej jeden z obrazów ma tekst alternatywny: "liczymy BMI" (dla wzor.png ) lub "zrzuć kalorie!" (dla rys1.png ), gdy obraz nie istnieje powinien wyświetlić się tekst alternatywny
ok. 1 min
Polecenie z arkusza
Zawartość bloku lewego: obraz rys1.png z tekstem alternatywnym o treści: „zrzuć kalorie!”
Przeskalowana ilustracja (364 × 300 px) z tekstem alternatywnym. Oba obrazy są na miejscu (R.2.6).
R.2.7 W bloku prawym 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ż bez 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
<form method="post" action="waga.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" - przeglądarka przyjmie w nim tylko liczbę,
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 "Licz BMI i zapisz 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 „Licz BMI i zapisz 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 1 stanie pod formularzem, w tym samym bloku.
Krok 21: 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 tabeli: „lp.”, „Interpretacja”, „zaczyna się od…”
<table> z pierwszym wierszem <tr> i trzema komórkami nagłówkowymi <th> (R.2.10). Kolejność kolumn jest taka jak pól w zapytaniu 2 (id, informacja, wart_min) - kolumnę „lp.” wypełni pole id. Kolejne wiersze („efekt działania skryptu nr 2”) wstawi skrypt przed </table>.
R.3.4 Kliknięcie odsyłacza otwiera dowolny plik ze zrzutem ekranu
ok. 1 min
Polecenie z arkusza
Zawartość stopki: Tekst: „Autor: ”, dalej wstawiony numer PESEL zdającego. Odsyłacz do pliku kw2.jpg o treści „Wynik działania kwerendy 2”
Na egzaminie po „Autor: ” wpisujesz swój numer PESEL - w tym rozwiązaniu w jego miejscu stoi Bartosz Bryniarski. Odsyłacz <a href="kw2.jpg"> otwiera zrzut wyniku zapytania 2 z tego samego folderu (R.3.4).
Kroki 23-33 · po tym etapie masz 30 z 40 kryteriów (pkt)
Krok 23: Plik styl4.css: baner
Kryteria:
R.4.10 Ustawiono rozmiar czcionki 150% dla banera
ok. 1 min
Polecenie z arkusza
Cechy formatowania CSS: Dla banera: tło koloru #4B0082, biały kolor czcionki, wyrównanie tekstu do środka, szerokość 75%, wysokość 100 px, rozmiar czcionki 150%
Nowy plik styl4.css w folderze zdającego - od teraz każda reguła trafia tutaj. Selektor identyfikatora z krzyżykiem #banner; #4B0082 to ciemny fiolet (nazwa indigo). font-size: 150% liczy się od czcionki rodzica, a <h2> jest jeszcze półtora raza większy od tekstu swojego bloku (R.4.10).
R.4.1 Ustawiono krój czcionki Helvetica dla znacznika body lub kontenera całej strony
R.4.2 Ustawiono kolor tła #FFE4B5 dla znacznika body lub kontenera całej strony, oraz kolor tła #4B0082 dla bloków banera, głównego i stopki
ok. 1 min
Polecenie z arkusza
Dla znacznika body: krój czcionki Helvetica, kolor tła #FFE4B5
Reguła body na początku pliku - krój dziedziczą wszystkie bloki (R.4.1). #FFE4B5 to jasny beż (moccasin). Wszystkie kolory tła z arkusza są gotowe (R.4.2). Komputer bez kroju Helvetica (np. Windows) podstawi inny - wersja nowoczesna dopisuje krój zapasowy.
R.4.7 Ustawiono marginesy wewnętrzne (padding) 60px dla bloku głównego oraz 40px dla stopki oraz marginesy zewnętrzne (margin) 40px dla znacznika form
ok. 1 min
Polecenie z arkusza
Dla znacznika formularza: marginesy zewnętrzne 40 px
Selektor znacznika form. margin to margines zewnętrzny - odsuwa formularz od nagłówka. 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 banera, stopki i znacznika tabeli
R.4.5 Ustawiono szerokość bloku logo na 25%, banera na 75%, bloku lewego na 45%, prawego na 55%, znacznika tabeli 90%
R.4.6 Ustawiono wyrównanie tekstu do środka dla banera, bloku prawego i znacznika tabeli
R.4.8 Ustawiono obramowanie o szerokości 1px linią kreskowaną, żółtą (dowolny odcień) dla znacznika tabeli
ok. 2 min
Polecenie z arkusza
Dla znacznika tabeli: biały kolor czcionki, wyrównanie tekstu do środka, szerokość 90%, obramowanie 1 px, kreskowane, żółte
Biały tekst - razem z banerem i stopką (R.4.3), tekst komórek na środku - razem z banerem i blokiem prawym (R.4.6), szerokość 90% bloku głównego domyka listę szerokości (R.4.5). „Kreskowane” to dashed (dotted to kropki) - 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 #9370DB a czcionki na żółty (dowolny odcień) (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 #9370DB a czcionki na żółty
Pseudoklasa :hover na selektorze wiersza tr - reguła działa tylko dla wiersza pod kursorem: jasny fiolet (mediumpurple) i żółty 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 baner i logo, poniżej blok lewy i prawy, następnie główny oraz stopka. Podział zrealizowany za pomocą znaczników sekcji, zgodnie z obrazem 2
Cztery bloki o zadanej szerokości dostają float: left: baner i logo stają w jednym rzędzie (75% + 25%), lewy i prawy w drugim (45% + 55%). Blok główny i stopka mają clear: both - zaczynają się pod opływanymi blokami i zajmują 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 mają tylko bloki na całą szerokość: główny i stopka.
Kroki 34-39 · po tym etapie masz 38 z 40 kryteriów (pkt)
Krok 34: Skrypt 1: odebranie danych z formularza
Kryteria: ,
R.5.1 Skrypt napisano w języku PHP i zawiera on co najmniej jedną instrukcję poprawną składniowo
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
Napisany w języku PHP, w pliku waga.php. Działanie skryptu 1, 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 1 wypisuje wynik pod formularzem, więc jego blok PHP stoi w bloku prawym, za </form>. Kod piszesz między <?php a ?>; serwer wykona go, zanim strona trafi do przeglądarki (R.5.1).
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.
Od tego kroku podgląd to wynik działania strony na serwerze (prawdziwe uruchomienie w PHP 8.2), tu po wysłaniu formularza danymi z obrazu 2 (70 i 170) - skrypt jeszcze nic nie wypisuje. Stronę sprawdzasz przez http://localhost/… - przeglądarka sama nie wykona PHP.
R.5.6 Skrypt 1 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² jest 10 000 razy większe niż 1,7², stąd mnożenie przez 10000 (R.5.6). Nawias ($wzrost * $wzrost) jest konieczny - bez niego PHP podzieli wagę przez wzrost i wynik znów pomnoży przez wzrost. Dla 70 kg i 170 cm: 70 / 28 900 × 10 000 ≈ 24,22.
Typowe błędy
$waga / $wzrost * $wzrost * 10000 bez nawiasu daje 700 000 - działania o tym samym priorytecie PHP wykonuje od lewej.
R.5.7 Skrypt 1 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.7). Podgląd po wysłaniu 70 i 170: „Twoja waga: 70; Twój wzrost: 170”, a pod spodem „BMI wynosi: 24.221453287197” - 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 wagi strona nie pokazuje nic.
R.5.8 Skrypt 1 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
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 (zrzut kw2.jpg i tabela na stronie: niedowaga od 0, waga prawidłowa od 19, nadwaga od 26, otyłość od 31; końce przedziałów to 18, 25, 30 i 100). 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.8).
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 24,22 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.
R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy egzamin
R.5.5 Skrypt 1 wysyła do bazy danych zapytanie 1 zmodyfikowane tak, że dane wstawiane do tabeli są wyliczone z danych formularza lub zwrócone funkcją PHP np. date('Y-m-d') lub Skrypt 2 wysyła do bazy zapytanie 2
ok. 3 min
Polecenie z arkusza
Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin. Skrypt wysyła do bazy danych zmodyfikowane zapytanie 1 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 1 z kwerendy.txt z wartościami zamienionymi na zmienne:
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.2),
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).
Połączenie powstaje dopiero wtedy, gdy jest co zapisać. Sprawdzone w bazie po wysłaniu 70 i 170: nowy rekord ma bmi_id = 2 i dzisiejszą datę, a w polu wynik jest 24 - kolumna jest typu całkowitego (int), więc baza zaokrągla 24,22 do liczby całkowitej.
Kroki 40-44 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 40: Skrypt 2: połączenie z bazą
ok. 2 min
Polecenie z arkusza
Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie egzamin
Skrypt 2 wypełnia tabelę, więc jego blok PHP stoi wewnątrz<table>, zaraz pod wierszem nagłówkowym - to, co wypisze, trafi dokładnie tam. Tabela ma być widoczna zawsze, nie tylko po wysłaniu formularza, więc skrypt otwiera własne połączenie tym samym mysqli_connect (skrypt 1 zamknął swoje albo w ogóle go nie otworzył).
Krok 42: Skrypt 2: 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 id, $row[1] opis przedziału, $row[2] jego początek,
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 samą liczbą porządkową - kolejne kolumny dojdą w następnym kroku.
R.2.9 W bloku głównym umieszczono tabelę o trzech kolumnach i przynajmniej jednym wierszu, użyto znaczniki <table>, <tr>, <td> i ich zamknięcia, generowane skryptem lub HTML
R.5.9 Skrypt 2 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: opis przedziału i jego początek. 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.9).
Po wykonaniu operacji na bazie skrypt zamyka połączenie z serwerem
mysqli_close($connection) po pętli - wszystkie wiersze są już wypisane. Podgląd: cała strona po wysłaniu formularza danymi z obrazu 2 - wynik pod formularzem i tabela przedziałów.
Typowe błędy
mysqli_close przed pętlą zamknie połączenie, zanim wiersze zostaną pobrane.
Kroki 45-47 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 45: Zabezpieczenie: tylko liczby dodatnie z formularza
ok. 4 min
Polecenie z arkusza
Działanie skryptu 1, 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, a tabela przedziałów się nie wyświetla. 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>70</b> nie jest liczbą. Stara linia zostaje w komentarzu; na egzaminie klucz tego nie sprawdza.
Krok 46: Zabezpieczenie: błąd bazy bez szczegółów serwera
ok. 3 min
Polecenie z arkusza
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 po wysłaniu formularza strona urywa się zaraz pod wynikiem BMI, a zamiast reszty pojawia się „Fatal error: Uncaught mysqli_sql_exception: Unknown database 'egzamin'” z pełną ścieżką do pliku na serwerze - tabela i stopka w ogóle się nie wyświetlają.
Oba skrypty trafiają do bloków try. W skrypcie 1 catch (mysqli_sql_exception $exception) wypisuje pod obliczonym BMI zdanie „Nie udało się zapisać wyniku”, w skrypcie 2 - jeden wiersz tabeli z neutralnym komunikatem (colspan="3" - komórka na całą szerokość). Podgląd: strona uruchomiona bez bazy, po wysłaniu formularza - wynik się liczy, reszta strony działa.
Krok 47: 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 2 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 48 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 48: 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ć: import.png, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kwerendy.txt, przeglądarka.txt, przeskalowany rys1.png, styl4.css, waga.php 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.