Przejdź do głównej treści
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.

  1. 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.

  2. 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 Panel Start 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).

  3. 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
    Podgląd strony po kroku 3
  4. 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.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT informacja, wart_min, wart_max FROM bmi;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. 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.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT informacja, wart_min, wart_max FROM bmi;
    
    -- Zapytanie 2
    INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (3, '2020-05-10', 27);
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. 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.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT informacja, wart_min, wart_max FROM bmi;
    
    -- Zapytanie 2
    INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (3, '2020-05-10', 27);
    
    -- Zapytanie 3
    SELECT wynik, data_pomiaru, informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. 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.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT informacja, wart_min, wart_max FROM bmi;
    
    -- Zapytanie 2
    INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES (3, '2020-05-10', 27);
    
    -- Zapytanie 3
    SELECT wynik, data_pomiaru, informacja FROM wynik JOIN bmi ON wynik.bmi_id = bmi.id;
    
    -- Zapytanie 4
    SELECT wart_min, wart_max FROM bmi WHERE informacja = 'nadwaga';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. 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
    Podgląd strony po kroku 8
  9. 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).

    bmi.php PHP nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  10. Krok 10: Kodowanie polskich znaków

    Kryteria:

    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.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  11. Krok 11: Tytuł strony

    Kryteria:

    R.2.3 Nadano tytuł strony: "Twoje BMI”

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Twoje BMI”

    <title> w <head> - napis na karcie przeglądarki.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  12. Krok 12: Podpięcie arkusza stylów styl3.css

    Kryteria:

    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.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  13. Krok 13: Sześć bloków strony

    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

    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.

    bmi.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
        </section>
        <section id="banner">
        </section>
        <section id="main">
        </section>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  14. Krok 14: Blok logo: wzór BMI

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku logo: obraz wzor.png z tekstem alternatywnym „wzór BMI”

    <img> z plikiem z archiwum (bez skalowania - ma 100 px wysokości, tyle co blok) i atrybutem alt: ten tekst zobaczy gość, gdy obraz się nie wczyta.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
        </section>
        <section id="main">
        </section>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  15. Krok 15: Blok banera: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku banera: nagłówek pierwszego stopnia o treści „Oblicz swoje BMI”

    Pierwszego stopnia to <h1>.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
        </section>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  16. 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>.

    bmi.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
            </table>
        </section>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  17. Krok 17: Blok lewy: nagłówek drugiego stopnia

    Kryteria:

    R.2.5 W bloku banera zapisano nagłówek h1: "Oblicz swoje BMI", w bloku lewym nagłówek h2: "Podaj wagę i wzrost"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: Nagłówek drugiego stopnia o treści: „Podaj wagę i wzrost”

    Drugiego stopnia to <h2>. Oba nagłówki strony są już gotowe: <h1> w banerze i <h2> tutaj (R.2.5).

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  18. Krok 18: Formularz POST i pole wagi

    Kryteria: ,

    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.

    bmi.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
            </form>
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  19. Krok 19: Pole wzrostu

    ok. 1 min
    Polecenie z arkusza

    Napis „Wzrost w cm:”, następnie pole edycyjne typu numerycznego o wartości minimalnej 1

    Drugie pole liczbowe, tym razem z nazwą wzrost - w PHP $_POST['wzrost'].

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
            </form>
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  20. Krok 20: Przycisk wysyłający formularz

    Kryteria: ,

    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.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  21. 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.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  22. Krok 22: Stopka: autor i odsyłacz do kwerend

    Kryteria:

    R.3.4 Kliknięcie odsyłacza otwiera plik tekstowy zawierający kwerendy

    ok. 1 min
    Polecenie z arkusza

    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).

    bmi.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  23. Etap 3: Styl CSS

    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).

    styl3.css CSS nowy plik
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    Podgląd strony po tym kroku (bmi.php)
  24. Krok 24: Baner

    Kryteria:

    R.4.10 Ustawiono rozmiar czcionki 130% dla banera

    ok. 1 min
    Polecenie z arkusza

    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).

    styl3.css CSS zmienione: 7 linii
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    Podgląd strony po tym kroku (bmi.php)
  25. Krok 25: Blok główny

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego: tło koloru #FF7F50, marginesy wewnętrzne 70 px

    padding: 70px - margines wewnętrzny z każdej strony, między krawędzią koralowego bloku a tabelą.

    styl3.css CSS zmienione: 4 linie
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    Podgląd strony po tym kroku (bmi.php)
  26. Krok 26: Blok lewy

    ok. 1 min
    Polecenie z arkusza

    Dla bloku lewego: szerokość 40%, wysokość 400 px

    Blok z formularzem. Wysokość 400 px - tyle co ilustracja w bloku obok.

    styl3.css CSS zmienione: 4 linie
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    Podgląd strony po tym kroku (bmi.php)
  27. Krok 27: Blok prawy

    Kryteria:

    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).

    styl3.css CSS zmienione: 5 linii
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    #right {
        width: 60%;
        height: 400px;
        text-align: right;
    }
    Podgląd strony po tym kroku (bmi.php)
  28. Krok 28: Stopka

    ok. 1 min
    Polecenie z arkusza

    Dla stopki: tło koloru #FF7F50, marginesy wewnętrzne 20 px

    Czwarty koralowy blok: logo, baner, główny i stopka mają to samo tło.

    styl3.css CSS zmienione: 4 linie
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    #right {
        width: 60%;
        height: 400px;
        text-align: right;
    }
    #footer {
        background-color: #FF7F50;
        padding: 20px;
    }
    Podgląd strony po tym kroku (bmi.php)
  29. Krok 29: Selektor body

    Kryteria: ,

    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).

    styl3.css CSS zmienione: 4 linie
    body {
        font-family: Georgia;
        background-color: #FFFAFA;
    }
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    #right {
        width: 60%;
        height: 400px;
        text-align: right;
    }
    #footer {
        background-color: #FF7F50;
        padding: 20px;
    }
    Podgląd strony po tym kroku (bmi.php)
  30. Krok 30: Formularz: marginesy zewnętrzne

    Kryteria:

    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).

    styl3.css CSS zmienione: 3 linie
    body {
        font-family: Georgia;
        background-color: #FFFAFA;
    }
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    #right {
        width: 60%;
        height: 400px;
        text-align: right;
    }
    #footer {
        background-color: #FF7F50;
        padding: 20px;
    }
    form {
        margin: 80px;
    }
    Podgląd strony po tym kroku (bmi.php)
  31. Krok 31: Tabela: kolor, wyrównanie, szerokość, obramowanie

    Kryteria: , , ,

    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).

    styl3.css CSS zmienione: 6 linii
    body {
        font-family: Georgia;
        background-color: #FFFAFA;
    }
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    #right {
        width: 60%;
        height: 400px;
        text-align: right;
    }
    #footer {
        background-color: #FF7F50;
        padding: 20px;
    }
    form {
        margin: 80px;
    }
    table {
        color: white;
        text-align: center;
        width: 80%;
        border: 1px dotted white;
    }
    Podgląd strony po tym kroku (bmi.php)
  32. Krok 32: Wiersz tabeli po najechaniu kursorem

    Kryteria:

    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.

    styl3.css CSS zmienione: 4 linie
    body {
        font-family: Georgia;
        background-color: #FFFAFA;
    }
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    #right {
        width: 60%;
        height: 400px;
        text-align: right;
    }
    #footer {
        background-color: #FF7F50;
        padding: 20px;
    }
    form {
        margin: 80px;
    }
    table {
        color: white;
        text-align: center;
        width: 80%;
        border: 1px dotted white;
    }
    tr:hover {
        background-color: #D3D3D3;
        color: black;
    }
    Podgląd strony po tym kroku (bmi.php)
  33. Krok 33: Układ bloków zgodny z obrazem 2

    Kryteria:

    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.

    styl3.css CSS zmienione: 6 linii
    body {
        font-family: Georgia;
        background-color: #FFFAFA;
    }
    #logo {
        background-color: #FF7F50;
        width: 25%;
        height: 100px;
    }
    #banner {
        background-color: #FF7F50;
        text-align: center;
        width: 75%;
        height: 100px;
        font-size: 130%;
    }
    #main {
        background-color: #FF7F50;
        padding: 70px;
    }
    #left {
        width: 40%;
        height: 400px;
    }
    #right {
        width: 60%;
        height: 400px;
        text-align: right;
    }
    #footer {
        background-color: #FF7F50;
        padding: 20px;
    }
    form {
        margin: 80px;
    }
    table {
        color: white;
        text-align: center;
        width: 80%;
        border: 1px dotted white;
    }
    tr:hover {
        background-color: #D3D3D3;
        color: black;
    }
    #logo, #banner, #left, #right {
        float: left;
    }
    #main, #footer {
        clear: both;
    }
    Podgląd strony po tym kroku (bmi.php)
  34. Etap 4: Skrypt 1: tabela przedziałów

    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.

    bmi.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  35. Krok 35: Skrypt 1: zapytanie 1

    Kryteria:

    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ć.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 34.

  36. 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.

    bmi.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td></tr>\n";
    }
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  37. Krok 37: Skrypt 1: komplet komórek w wierszu

    Kryteria: ,

    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).

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  38. Krok 38: Skrypt 1: zamknięcie połączenia

    Kryteria:

    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.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 37.

  39. Etap 5: Skrypt 2: obliczenie i zapis BMI

    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.

    bmi.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 37.

  40. Krok 40: Skrypt 2: obliczenie wskaźnika

    Kryteria:

    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.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
        $bmi = $waga / ($wzrost * $wzrost) * 10000;
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 37.

  41. Krok 41: Skrypt 2: wypisanie danych i wyniku

    Kryteria:

    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.

    bmi.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
        $bmi = $waga / ($wzrost * $wzrost) * 10000;
        echo "Twoja waga: $waga; Twój wzrost: $wzrost<br>BMI wynosi: $bmi";
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  42. Krok 42: Skrypt 2: przedział BMI

    Kryteria:

    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.

    bmi.php PHP zmienione: 9 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
        $bmi = $waga / ($wzrost * $wzrost) * 10000;
        echo "Twoja waga: $waga; Twój wzrost: $wzrost<br>BMI wynosi: $bmi";
        if ($bmi < 19) {
            $przedzial = 1;
        } elseif ($bmi < 26) {
            $przedzial = 2;
        } elseif ($bmi < 31) {
            $przedzial = 3;
        } else {
            $przedzial = 4;
        }
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 41.

  43. Krok 43: Skrypt 2: zapis pomiaru w bazie

    ok. 3 min
    Polecenie z arkusza

    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.

    bmi.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
        $bmi = $waga / ($wzrost * $wzrost) * 10000;
        echo "Twoja waga: $waga; Twój wzrost: $wzrost<br>BMI wynosi: $bmi";
        if ($bmi < 19) {
            $przedzial = 1;
        } elseif ($bmi < 26) {
            $przedzial = 2;
        } elseif ($bmi < 31) {
            $przedzial = 3;
        } else {
            $przedzial = 4;
        }
        $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
        $data = date('Y-m-d');
        mysqli_query($connection, "INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES ($przedzial, '$data', $bmi);");
        mysqli_close($connection);
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 41.

  44. Etap 6: Dobre praktyki (poza kluczem)

    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:

    • waga „sześćdziesiąt” - „Fatal error: Uncaught TypeError: Unsupported operand types” (dzielenie tekstu),
    • 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.

    bmi.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
    $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
    while ($row = mysqli_fetch_row($result)) {
        echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
    }
    mysqli_close($connection);
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    // if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
    if (is_numeric($_POST['waga'] ?? '') && is_numeric($_POST['wzrost'] ?? '') && $_POST['waga'] > 0 && $_POST['wzrost'] > 0) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
        $bmi = $waga / ($wzrost * $wzrost) * 10000;
        echo "Twoja waga: $waga; Twój wzrost: $wzrost<br>BMI wynosi: $bmi";
        if ($bmi < 19) {
            $przedzial = 1;
        } elseif ($bmi < 26) {
            $przedzial = 2;
        } elseif ($bmi < 31) {
            $przedzial = 3;
        } else {
            $przedzial = 4;
        }
        $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
        $data = date('Y-m-d');
        mysqli_query($connection, "INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES ($przedzial, '$data', $bmi);");
        mysqli_close($connection);
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 41.

  45. 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.

    bmi.php PHP zmienione: 17 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    try {
        $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
        $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
        while ($row = mysqli_fetch_row($result)) {
            echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
        }
        mysqli_close($connection);
    } catch (mysqli_sql_exception $exception) {
        echo '            <tr><td colspan="3">Tabela przedziałów jest chwilowo niedostępna</td></tr>' . "\n";
    }
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    // if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
    if (is_numeric($_POST['waga'] ?? '') && is_numeric($_POST['wzrost'] ?? '') && $_POST['waga'] > 0 && $_POST['wzrost'] > 0) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
        $bmi = $waga / ($wzrost * $wzrost) * 10000;
        echo "Twoja waga: $waga; Twój wzrost: $wzrost<br>BMI wynosi: $bmi";
        if ($bmi < 19) {
            $przedzial = 1;
        } elseif ($bmi < 26) {
            $przedzial = 2;
        } elseif ($bmi < 31) {
            $przedzial = 3;
        } else {
            $przedzial = 4;
        }
        try {
            $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
            $data = date('Y-m-d');
            mysqli_query($connection, "INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES ($przedzial, '$data', $bmi);");
            mysqli_close($connection);
        } catch (mysqli_sql_exception $exception) {
            echo '<br>Nie udało się zapisać wyniku';
        }
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  46. 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.

    bmi.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Twoje BMI</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="logo">
            <img src="wzor.png" alt="wzór BMI">
        </section>
        <section id="banner">
            <h1>Oblicz swoje BMI</h1>
        </section>
        <section id="main">
            <table>
                <tr>
                    <th>Interpretacja BMI</th>
                    <th>Wartość minimalna</th>
                    <th>Wartość maksymalna</th>
                </tr>
    <?php
    try {
        $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
        $result = mysqli_query($connection, 'SELECT informacja, wart_min, wart_max FROM bmi;');
        while ($row = mysqli_fetch_row($result)) {
            // echo "            <tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>\n";
            $cells = array_map('htmlspecialchars', $row);
            echo "            <tr><td>$cells[0]</td><td>$cells[1]</td><td>$cells[2]</td></tr>\n";
        }
        mysqli_close($connection);
    } catch (mysqli_sql_exception $exception) {
        echo '            <tr><td colspan="3">Tabela przedziałów jest chwilowo niedostępna</td></tr>' . "\n";
    }
    ?>
            </table>
        </section>
        <section id="left">
            <h2>Podaj wagę i wzrost</h2>
            <form method="post" action="bmi.php">
                Waga: <input type="number" name="waga" min="1"><br>
                Wzrost w cm: <input type="number" name="wzrost" min="1"><br>
                <input type="submit" value="Oblicz i zapamiętaj wynik">
            </form>
    <?php
    // if (!empty($_POST['waga']) && !empty($_POST['wzrost'])) {
    if (is_numeric($_POST['waga'] ?? '') && is_numeric($_POST['wzrost'] ?? '') && $_POST['waga'] > 0 && $_POST['wzrost'] > 0) {
        $waga = $_POST['waga'];
        $wzrost = $_POST['wzrost'];
        $bmi = $waga / ($wzrost * $wzrost) * 10000;
        echo "Twoja waga: $waga; Twój wzrost: $wzrost<br>BMI wynosi: $bmi";
        if ($bmi < 19) {
            $przedzial = 1;
        } elseif ($bmi < 26) {
            $przedzial = 2;
        } elseif ($bmi < 31) {
            $przedzial = 3;
        } else {
            $przedzial = 4;
        }
        try {
            $connection = mysqli_connect('localhost', 'root', '', 'egzamin');
            $data = date('Y-m-d');
            mysqli_query($connection, "INSERT INTO wynik (bmi_id, data_pomiaru, wynik) VALUES ($przedzial, '$data', $bmi);");
            mysqli_close($connection);
        } catch (mysqli_sql_exception $exception) {
            echo '<br>Nie udało się zapisać wyniku';
        }
    }
    ?>
        </section>
        <section id="right">
            <img src="rys1.png" alt="ćwiczenia">
        </section>
        <section id="footer">
            Autor: Bartosz Bryniarski
            <a href="kwerendy.txt">Zobacz kwerendy</a>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (bmi.php)
  47. Etap 7: Oddanie pracy

    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.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

    Podgląd strony bez zmian - taki jak po kroku 46.

Podgląd

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: . 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.

Potwierdzenie

Informacja