Przejdź do głównej treści
E.14-01-23.06-SGCzerwiec 2023 · 39 kroków · ok. 75 min · 36 kryteriów z klucza

Rozwiązanie krok po kroku: Atlas zwierząt z wyborem gromady (Nowoczesny kod (flex, PDO))

To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza baza z czterema zapytaniami i strona index.php z atlasem zwierząt - i tak samo spełnia każde kryterium klucza. Inna jest droga:

  • flexbox zamiast float: trzy bloki główne stoją we wspólnym znaczniku <main> z display: flex, a stopka nie potrzebuje clear. Szerokości 30%, 40% i 30% zostają na blokach, bo tam klucz je ocenia,
  • zmienne CSS dla kolorów z arkusza, etykieta <label for> przy polu numerycznym i zdjęcie, które nie wychodzi poza swój blok,
  • PHP na PDO na górze pliku index.php, przed HTML-em - w blokach środkowym i prawym zostaje tylko wypisanie gotowych danych,
  • filter_input przyjmuje wyłącznie liczbę całkowitą od 1 do 5, nazwy gromad są w tablicy zamiast w pięciu if, a zapytanie 1 idzie jako zapytanie przygotowane,
  • wpisany numer wraca do pola po wysłaniu formularza, a numer spoza zakresu dostaje komunikat zamiast pustego bloku.

To arkusz E.14 z sesji czerwiec 2023 - kwalifikacji formuły 2012, którą zastąpiła INF.03. Baza i zdjęcie pochodzą z oryginalnego archiwum CKE z sesji styczeń 2019 (załącznik na stronie arkusza), zapytania są policzone na MariaDB 10.4, a podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 8.1.2 - użyte konstrukcje działają w obu wersjach).

Jak liczą się punkty. Klucz ma 36 kryteriów (R.1.1 - R.5.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 27 punktów. Przy każdym kroku jest napisane, które kryteria spełnia; klucz przyjmuje zarówno mysqli, jak i PDO.

  1. Etap 1: Baza danych

    Kroki 1-7 · po tym etapie masz 6 z 36 kryteriów (pkt)

    Krok 1: Folder zdającego i archiwum z materiałami

    ok. 2 min
    Polecenie z arkusza

    Na pulpicie znajdziesz archiwum ZIP o nazwie materialy-03.zip zabezpieczone hasłem: G@tuneK Archiwum należy rozpakować. Na pulpicie konta Egzamin utwórz folder. Jako nazwy folderu użyj swojego numeru PESEL. Rozpakowane pliki umieść w tym folderze. Po skończonej pracy wyniki zapisz w tym folderze.

    Folder na pulpicie nazwany numerem PESEL (w tym rozwiązaniu w jego miejscu stoi Bartosz Bryniarski), do niego archiwum materialy-03.zip rozpakowane 7-Zipem z hasłem G@tuneK. W środku: baza2.sql i zwierzeta.jpg. Do tego folderu trafiają wszystkie rezultaty pracy.

  2. Krok 2: XAMPP i pusta baza o nazwie baza

    ok. 2 min
    Polecenie z arkusza

    Uruchom usługi MySQL i Apache za pomocą XAMPP Control Panel. Za pomocą narzędzia phpMyAdmin wykonaj podane operacje na bazie danych: Utwórz nową bazę danych o nazwie baza

    Start przy Apache i MySQL, potem http://localhost/phpmyadmin, Nowa, nazwa baza, porównywanie utf8mb4_polish_ci - pełny zestaw znaków Unicode i polska kolejność sortowania.

  3. Krok 3: Import pliku baza2.sql i zrzut import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych baza , czynność udokumentowano plikiem o nazwie import w formacie PNG. Zrzut zawiera cały obszar ekranu monitora z widocznym paskiem zadań

    ok. 3 min
    Polecenie z arkusza

    Do bazy zaimportuj tabele z pliku baza2.sql z rozpakowanego archiwum Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z numerem zdającego, 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

    Baza baza, karta Import, plik baza2.sql, Wykonaj. Plik tworzy kilka tabel; zadanie korzysta z trzech z obrazu 1: zwierzeta (9 wierszy), gromady (1 ryby … 5 ssaki) i odzywianie. Pola Gromady_id i Odzywianie_id to klucze obce. Zrzut całego ekranu z komunikatem o sukcesie i listą tabel: import.png.

    Typowe błędy

    Ten zrzut jest w PNG, zrzuty kwerend - w JPG. Zrzut wykadrowany albo bez paska zadań nie jest oceniany.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 3
  4. Krok 4: Zapytanie 1: gatunki i występowanie ryb

    Kryteria: ,

    R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanieami SQL wynikające z treści zadania

    R.1.3 Wykonano zapytanie 1 wybierające jedynie pola gatunek i wystepowanie z tabeli Zwierzeta jedynie dla ryb. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT gatunek, wystepowanie FROM zwierzeta WHERE Gromady_id = 1; oraz wynik działania udokumentowano zrzutem, na którym widoczne są dokładnie 2 rekordy dla suma i jesiotra, wyświetlone jedynie kolumny gatunek, wystepowanie

    ok. 3 min
    Polecenie z arkusza

    Zapisz i wykonaj zapytania SQL działające na bazie danych. 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 gatunek i wystepowanie z tabeli Zwierzeta jedynie dla ryb

    Każda klauzula w osobnej linii - przy dłuższych zapytaniach łatwiej wtedy znaleźć błąd. Ryby to gromada 1, więc warunek idzie po kluczu obcym Gromady_id. Wynik: 2 wiersze, Sum pospolity, Eurazja i Jesiotr zachodni, Europa. Zapytanie trafia do kwerendy.txt, zrzut - do kw1.jpg. Skrypt użyje go z parametrem w miejscu 1.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT gatunek, wystepowanie
    FROM zwierzeta
    WHERE Gromady_id = 1;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: zwierzęta z nazwą gromady (relacja)

    Kryteria:

    R.1.4 Wykonano zapytanie 2 wybierające jedynie pola id i gatunek z tabeli Zwierzeta oraz odpowiadające im pole nazwa z tabeli Gromady. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT zwierzeta.id, gatunek, nazwa FROM zwierzeta JOIN gromady ON zwierzeta.Gromady_id = gromady.id; możliwe również INNER JOIN lub SELECT zwierzeta.id, gatunek, gromady.nazwa FROM zwierzeta, gromady WHERE gromady.id = zwierzeta.gromady_id; oraz wynik działania udokumentowano zrzutem, na którym widoczne jest dokładnie 9 rekordów o id= 1 - 9, jedynie pola id, gatunek, nazwa

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola id i gatunek z tabeli Zwierzeta oraz odpowiadające im pole nazwa z tabeli Gromady. Należy posłużyć się relacją.

    JOIN … ON zwierzeta.Gromady_id = gromady.id - relacja: klucz obcy zwierzęcia równa się kluczowi głównemu gromady. Kolumnę id mają obie tabele, więc trzeba wskazać zwierzeta.id. Wynik: 9 wierszy, od 1, Sum pospolity, ryby do 9, Dingo australijski, ssaki. Zrzut: kw2.jpg.

    kwerendy.txt Tekst zmienione: 5 linii
    -- Zapytanie 1
    SELECT gatunek, wystepowanie
    FROM zwierzeta
    WHERE Gromady_id = 1;
    
    -- Zapytanie 2
    SELECT zwierzeta.id, gatunek, nazwa
    FROM zwierzeta
    JOIN gromady ON zwierzeta.Gromady_id = gromady.id;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: liczba ssaków

    Kryteria:

    R.1.5 Wykonano zapytanie 3 zliczające liczbę rekordów w tabeli Zwierzeta jedynie dla ssaków. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(*) FROM zwierzeta WHERE Gromady_id = 5; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest wynik działania kwerendy - wartość 4

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: zliczające liczbę rekordów w tabeli Zwierzeta jedynie dla ssaków

    COUNT(*) liczy wiersze spełniające warunek Gromady_id = 5. Alias AS liczba_ssakow nadaje kolumnie wyniku czytelną nazwę zamiast COUNT(*) - klucz go nie wymaga, ale nie przeszkadza. Wynik: 4. Zrzut: kw3.jpg.

    kwerendy.txt Tekst zmienione: 5 linii
    -- Zapytanie 1
    SELECT gatunek, wystepowanie
    FROM zwierzeta
    WHERE Gromady_id = 1;
    
    -- Zapytanie 2
    SELECT zwierzeta.id, gatunek, nazwa
    FROM zwierzeta
    JOIN gromady ON zwierzeta.Gromady_id = gromady.id;
    
    -- Zapytanie 3
    SELECT COUNT(*) AS liczba_ssakow
    FROM zwierzeta
    WHERE Gromady_id = 5;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: użytkownik KatarzynaNowak

    Kryteria:

    R.1.6 Wykonano zapytanie 4 tworzące użytkownika KatarzynaNowak o haśle K4tNow. W pliku z kwerendami lub na zrzucie istnieje zapis z jawnie zapisanym hasłem np.: CREATE USER 'KatarzynaNowak'@'localhost' IDENTIFIED BY 'K4tNow'; lub CREATE USER 'KatarzynaNowak'@'%' IDENTIFIED BY 'K4tNow'; oraz wynik działania udokumentowano zrzutem, na którym widoczne jest potwierdzenie utworzenia konta użytkownika. Nie uznajemy automatycznego utworzenia konta

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: tworzące użytkownika KatarzynaNowak o haśle K4tNow

    CREATE USER z hostem 'localhost' - konto może łączyć się tylko z tego komputera, co jest bezpieczniejsze niż '%' (dowolny host), które klucz też przyjmuje. Komunikat „MySQL zwrócił pusty wynik” to sukces. Zrzut: kw4.jpg. Nowe konto nie ma jeszcze żadnych uprawnień - do tego służy osobne polecenie GRANT, którego arkusz nie wymaga.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT gatunek, wystepowanie
    FROM zwierzeta
    WHERE Gromady_id = 1;
    
    -- Zapytanie 2
    SELECT zwierzeta.id, gatunek, nazwa
    FROM zwierzeta
    JOIN gromady ON zwierzeta.Gromady_id = gromady.id;
    
    -- Zapytanie 3
    SELECT COUNT(*) AS liczba_ssakow
    FROM zwierzeta
    WHERE Gromady_id = 5;
    
    -- Zapytanie 4
    CREATE USER 'KatarzynaNowak'@'localhost' IDENTIFIED BY 'K4tNow';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Strona HTML

    Kroki 8-22 · po tym etapie masz 19 z 36 kryteriów (pkt)

    Krok 8: Plik index.php

    ok. 2 min
    Polecenie z arkusza

    Składa się ze strony o nazwie index.php

    Szkielet HTML5 w pliku index.php. Rozszerzenie .php, bo na górze pliku stanie skrypt; dopóki nie ma w nim PHP, serwer odda go jak zwykły HTML.

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

    Kryteria:

    R.2.1 Witrynę internetową zapisano w pliku index.php 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 pierwszy element <head>, a plik zapisany w UTF-8 (R.2.1).

    index.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 (index.php)
  10. Krok 10: Tytuł strony

    Kryteria:

    R.2.2 Nadano tytuł strony: "Dane o zwierzętach”, jest on widoczny na karcie przeglądarki

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Dane o zwierzętach”

    <title>Dane o zwierzętach</title> (R.2.2). Obok znacznik viewport - telefon pokaże stronę w swojej szerokości, zamiast udawać szeroki ekran. Klucz go nie ocenia; w nowej stronie dopisuje się go z nawyku.

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  11. Krok 11: Podpięcie arkusza stylów styl3.css

    Kryteria:

    R.3.6 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl3.css lub style.css , formatowanie pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy źle przypisano 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"> (R.3.6). Całe formatowanie pochodzi z tego pliku - w znacznikach nie ma atrybutów style. W tym wydaniu arkusz w jednym miejscu nazywa plik stylów style.css, a w dwóch innych styl3.css - klucz przyjmuje obie nazwy.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  12. Krok 12: Bloki: baner, formularz, trzy główne i stopka

    Kryteria:

    R.2.3 Wygląd strony zdefiniowano dzieląc ją na bloki: na górze baner, poniżej blok formularza, poniżej trzy bloki główne: lewy, środkowy i prawy, na dole blok stopki. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze baner, poniżej blok formularza, poniżej trzy bloki główne: lewy, środkowy i prawy, na dole blok stopki. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    Baner <header>, blok formularza <section id="form-block">, stopka <footer>, a trzy bloki główne - sekcje left, middle i right - stoją we wspólnym <main> (R.2.3). To główna treść strony (czytnik ekranu pozwala do niej przeskoczyć) i zarazem pojemnik, który CSS zamieni w jeden rząd bloków. Blok formularza zostaje poza <main> - zajmuje całą szerokość.

    index.php PHP zmienione: 14 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
        </header>
        <section id="form-block">
        </section>
        <main>
            <section id="left">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  13. Krok 13: Baner: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: nagłówek pierwszego stopnia „ATLAS ZWIERZĄT”

    <h1> w banerze - jedyny nagłówek pierwszego stopnia na stronie.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
        </section>
        <main>
            <section id="left">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  14. Krok 14: Blok formularza: nagłówek „Gromady:”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku formularza: Nagłówek drugiego stopnia o treści „Gromady:”

    <h2> - nagłówek drugiego stopnia.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
        </section>
        <main>
            <section id="left">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  15. Krok 15: Lista numerowana gromad

    Kryteria:

    R.2.5 W bloku formularza umieszczono listę numerowaną o elementach: „Ryby”, „Płazy”, „Gady”, „Ptaki”, „Ssaki” oraz zastosowano znaczniki <ol>, <li>

    ok. 1 min
    Polecenie z arkusza

    Lista numerowana o elementach: „Ryby”, „Płazy”, „Gady”, „Ptaki”, „Ssaki”

    <ol> z pięcioma <li> (R.2.5). Numery dopisze przeglądarka - i są to te same numery, które gromady mają w tabeli gromady.

    index.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
        </section>
        <main>
            <section id="left">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  16. Krok 16: Formularz wysyłający dane metodą POST

    Kryteria:

    R.3.2 Formularz przesyła dane metodą POST (poprawne również bez atrybutu action)

    ok. 1 min
    Polecenie z arkusza

    Formularz wysyłający dane metodą POST do tej samej strony z elementami

    <form method="post"> bez action - dane wracają do index.php (R.3.2).

    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
            </form>
        </section>
        <main>
            <section id="left">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  17. Krok 17: Etykieta „Wybierz gromadę: ” i pole numeryczne

    ok. 2 min
    Polecenie z arkusza

    Tekst „Wybierz gromadę: ” Pole edycyjne typu numerycznego

    Tekst z arkusza staje się etykietą <label for="gromada">, związaną z polem o id="gromada": kliknięcie napisu ustawia kursor w polu, a czytnik ekranu odczyta „Wybierz gromadę” przy wejściu w pole.

    • type="number" - pole numeryczne ze strzałkami (R.3.3 sprawdzi typ),
    • name="gromada" - klucz, pod którym wartość trafi do PHP,
    • min="1" i max="5" - strzałki nie wyjdą poza numery z listy, a przeglądarka podpowie zakres. To tylko wygoda: dane da się wysłać z pominięciem formularza, więc zakres sprawdzi też skrypt.
    index.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5">
            </form>
        </section>
        <main>
            <section id="left">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  18. Krok 18: Przycisk „Wyświetl”

    Kryteria: ,

    R.2.6 W bloku formularza umieszczono formularz z polem do wprowadzania danych oraz przyciskiem opisanym "Wyświetl"

    R.3.3 Pole formularza jest typu number oraz przycisk jest typu submit

    ok. 1 min
    Polecenie z arkusza

    Przycisk wysyłający dane o nazwie „Wyświetl”

    <button type="submit">Wyświetl</button> - napis jest treścią znacznika, typ submit wysyła formularz. Pole i przycisk dają komplet formularza (R.2.6, R.3.3).

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  19. Krok 19: Blok lewy: zdjęcie z tekstem alternatywnym

    Kryteria:

    R.2.7 W bloku głównym - lewym umieszczono obraz zwierzeta.jpg oraz ma on tekst alternatywny "dzikie zwierzeta"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego – lewego: obraz zwierzeta.jpg z wypakowanego archiwum, z tekstem alternatywnym „dzikie zwierzęta”

    src i alt z arkusza (R.2.7). Atrybutów width i height tu nie ma - całe formatowanie ma pochodzić z arkusza stylów, a rozmiar zdjęcia w bloku ustali CSS.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
            </section>
            <section id="right">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  20. Krok 20: Blok prawy: nagłówek „Wszystkie zwierzęta w bazie”

    Kryteria:

    R.2.4 W bloku banera zapisano nagłówek h1: "ATLAS ZWIERZĄT" oraz w bloku formularza zapisano nagłówek h2: "Gromady:" oraz w bloku głównym - prawym nagłówek h2: „Wszystkie zwierzęta w bazie”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego – prawego: Nagłówek drugiego stopnia o treści „Wszystkie zwierzęta w bazie”

    Drugi <h2> - komplet nagłówków z arkusza (R.2.4). Blok środkowy zostaje pusty: wypełni go wynik skryptu nr 1.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  21. Krok 21: Stopka: odnośnik otwierany w nowej karcie

    Kryteria: ,

    R.3.4 Na stronie znajduje się odnośnik o treści "Poznaj inne strony o zwierzętach", jego kliknięcie inicjuje otwarcie strony "atlas-zwierzat.pl"

    R.3.5 Strona jest otwierana w osobnym oknie / zakładce przeglądarki

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: Odnośnik o treści „Poznaj inne strony o zwierzętach” prowadzący do strony „atlas-zwierzat.pl”, odnośnik otwiera stronę w osobnej karcie

    Adres z protokołem https:// (R.3.4) i target="_blank" - nowa karta (R.3.5). Do tego rel="noopener": otwarta strona nie dostaje dostępu do karty z atlasem (przez window.opener mogłaby ją np. przekierować na fałszywą stronę). Nowe przeglądarki robią to już same, ale atrybut jawnie mówi, że tak ma być.

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  22. Krok 22: Stopka: autor strony

    Kryteria:

    R.2.8 W stopce zapisano tekst "autor Atlasu zwierząt: " oraz wstawiono numer PESEL

    ok. 1 min
    Polecenie z arkusza

    Napis o treści „autor Atlasu zwierząt: ”, dalej wstawiony numer zdającego

    Na egzaminie po dwukropku wpisujesz swój numer zdającego; w tym rozwiązaniu stoi tam imię i nazwisko autora, Bartosz Bryniarski (R.2.8).

    index.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  23. Etap 3: Styl CSS

    Kroki 23-30 · po tym etapie masz 28 z 36 kryteriów (pkt)

    Krok 23: Plik styl3.css: kolory jako zmienne i krój Garamond

    Kryteria:

    R.4.1 Ustawiono domyślny (*) krój czcionki dla całej strony na Garamond

    ok. 2 min
    Polecenie z arkusza

    Styl CSS zdefiniowany w całości w zewnętrznym pliku o nazwie style.css. Styl CSS zawiera formatowanie: Domyślne formatowanie wszystkich selektorów: krój czcionki Garamond

    Na początku pliku zmienne CSS w :root: kolory z arkusza dostają nazwy, a reguły dalej używają var(--banner). Baner i stopka mają ten sam kolor, trzy bloki główne - drugi wspólny; zmiana odcienia to wtedy jedna linia.

    Krój Garamond na selektorze * (R.4.1) - obejmuje też pole i przycisk, które nie dziedziczą kroju po body. Wydanie klucza z czerwca 2023 wymaga wprost tego selektora, inne przyjmują też body i html.

    styl3.css CSS nowy plik
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    Podgląd strony po tym kroku (index.php)
  24. Krok 24: Baner: tło, kolor tekstu, wyśrodkowanie, marginesy wewnętrzne

    ok. 1 min
    Polecenie z arkusza

    Dla bloku banera: kolor tła RosyBrown, biały kolor czcionki, wyrównanie tekstu do środka, marginesy wewnętrzne 10 px

    Cztery właściwości z arkusza na header; „marginesy wewnętrzne” to padding.

    styl3.css CSS zmienione: 7 linii
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    
    header {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 10px;
    }
    Podgląd strony po tym kroku (index.php)
  25. Krok 25: Blok formularza: tło, wyśrodkowanie, marginesy wewnętrzne

    ok. 1 min
    Polecenie z arkusza

    Dla bloku formularza: kolor tła DarkSalmon, wyrównanie tekstu do środka, marginesy wewnętrzne 40 px

    Selektor identyfikatora #form-block. Wyśrodkowanie dziedziczą nagłówek, lista i formularz.

    styl3.css CSS zmienione: 6 linii
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    
    header {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 10px;
    }
    
    #form-block {
        background-color: var(--form);
        text-align: center;
        padding: 40px;
    }
    Podgląd strony po tym kroku (index.php)
  26. Krok 26: Bloki główne lewy i prawy: tło i wymiary

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla bloku głównego lewego oraz prawego: kolor tła LightSalmon, wysokość 300 px, szerokość 30%

    Jedna reguła na dwa selektory. Szerokość zostaje na blokach, bo klucz (R.4.5) ocenia szerokość bloków - w <main> z flexboxem procenty liczą się od szerokości <main>, czyli całej strony.

    styl3.css CSS zmienione: 7 linii
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    
    header {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 10px;
    }
    
    #form-block {
        background-color: var(--form);
        text-align: center;
        padding: 40px;
    }
    
    #left,
    #right {
        background-color: var(--block);
        height: 300px;
        width: 30%;
    }
    Podgląd strony po tym kroku (index.php)
  27. Krok 27: Blok główny środkowy: tło i wymiary

    Kryteria: ,

    R.4.4 Ustawiono wysokość dla trzech bloków głównych 300px

    R.4.5 Ustawiono szerokość bloku głównego prawego i lewego 30% oraz głównego środkowego na 40%

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego – środkowego: kolor tła LightSalmon, wysokość 300 px, szerokość 40%

    30% + 40% + 30% = 100%. Wysokości (R.4.4) i szerokości (R.4.5) trzech bloków głównych są ustawione.

    styl3.css CSS zmienione: 6 linii
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    
    header {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 10px;
    }
    
    #form-block {
        background-color: var(--form);
        text-align: center;
        padding: 40px;
    }
    
    #left,
    #right {
        background-color: var(--block);
        height: 300px;
        width: 30%;
    }
    
    #middle {
        background-color: var(--block);
        height: 300px;
        width: 40%;
    }
    Podgląd strony po tym kroku (index.php)
  28. Krok 28: Stopka: tło, kolor tekstu, wyśrodkowanie, marginesy wewnętrzne

    Kryteria: , , ,

    R.4.2 Ustawiono kolor tła RosyBrown dla bloku banera i stopki oraz DarkSalmon dla bloku formularza oraz LightSalmon dla trzech bloków głównych

    R.4.3 Ustawiono biały kolor czcionki dla banera i stopki

    R.4.6 Ustawiono wyrównanie tekstu do środka dla bloku banera, formularza i stopki

    R.4.7 Ustawiono marginesy wewnętrzne (padding) 10px dla banera oraz 40px dla formularza oraz 30px dla stopki

    ok. 1 min
    Polecenie z arkusza

    Dla stopki: kolor tła RosyBrown, biały kolor czcionki, wyrównanie tekstu do środka, marginesy wewnętrzne 30 px

    Ta sama zmienna co w banerze. Kolory tła wszystkich bloków (R.4.2), biały tekst (R.4.3), wyśrodkowanie (R.4.6) i marginesy wewnętrzne 10, 40 i 30 px (R.4.7) są gotowe. Odnośnik zachowuje kolor przeglądarki - jak na obrazie 2.

    styl3.css CSS zmienione: 7 linii
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    
    header {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 10px;
    }
    
    #form-block {
        background-color: var(--form);
        text-align: center;
        padding: 40px;
    }
    
    #left,
    #right {
        background-color: var(--block);
        height: 300px;
        width: 30%;
    }
    
    #middle {
        background-color: var(--block);
        height: 300px;
        width: 40%;
    }
    
    footer {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 30px;
    }
    Podgląd strony po tym kroku (index.php)
  29. Krok 29: Lista numerowana: obramowanie i rozmiar czcionki

    Kryteria:

    R.4.8 Ustawiono styl listy numerowanej: obramowanie 2px linią ciągłą w kolorze rgb(205, 92, 92) lub #CD5C5C oraz rozmiar czcionki 150%

    ok. 1 min
    Polecenie z arkusza

    Dla listy numerowanej: obramowanie 2 px linią ciągłą w kolorze RGB: 205, 92, 92; rozmiar czcionki 150%

    Skrót border: grubość, styl solid i kolor ze zmiennej --list-border, w której stoi dokładnie rgb(205, 92, 92) z arkusza (R.4.8).

    styl3.css CSS zmienione: 5 linii
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    
    header {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 10px;
    }
    
    #form-block {
        background-color: var(--form);
        text-align: center;
        padding: 40px;
    }
    
    #left,
    #right {
        background-color: var(--block);
        height: 300px;
        width: 30%;
    }
    
    #middle {
        background-color: var(--block);
        height: 300px;
        width: 40%;
    }
    
    footer {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 30px;
    }
    
    ol {
        border: 2px solid var(--list-border);
        font-size: 150%;
    }
    Podgląd strony po tym kroku (index.php)
  30. Krok 30: Układ bloków: flexbox w main

    Kryteria:

    R.3.1 Układ bloków na stronie po uruchomieniu w przeglądarce jest zgodny z Obrazem 2 w arkuszu egzaminacyjnym (prawidłowo zastosowano właściwości CSS układające bloki na stronie, np. float i clear albo display flex albo grid)

    ok. 3 min
    Polecenie z arkusza

    Podział strony na bloki: na górze baner, poniżej blok formularza, poniżej trzy bloki główne: lewy, środkowy i prawy, na dole blok stopki. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    display: flex na <main> ustawia trzy sekcje w jednym rzędzie, w kolejności z HTML-a, z szerokościami 30%, 40% i 30% z ich własnych reguł. Baner, blok formularza i stopka stoją poza <main>, więc zajmują całą szerokość - bez float i bez clear (R.3.1).

    Druga reguła dotyczy zdjęcia: ma 400 px szerokości, a blok lewy przy oknie węższym niż ok. 1350 px ma mniej. max-width: 100% zmniejsza wtedy zdjęcie do szerokości bloku (proporcje zostają, bo wysokość nie jest ustawiona). W wersji podstawowej zdjęcie chowało się pod blokiem środkowym. Arkusz tej reguły nie wymaga - przy szerokim oknie zdjęcie ma swoje 400 px i wygląda jak na obrazie 2.

    Typowe błędy

    Bez max-width zdjęcie, jako najszersza zawartość bloku, potrafi poszerzyć blok lewy we flexboxie (element flex nie zwęża się poniżej szerokości swojej zawartości) - suma szerokości przekroczy 100% i pojawi się poziomy pasek przewijania.

    styl3.css CSS zmienione: 8 linii
    :root {
        --banner: RosyBrown;
        --form: DarkSalmon;
        --block: LightSalmon;
        --list-border: rgb(205, 92, 92);
    }
    
    * {
        font-family: Garamond;
    }
    
    header {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 10px;
    }
    
    #form-block {
        background-color: var(--form);
        text-align: center;
        padding: 40px;
    }
    
    #left,
    #right {
        background-color: var(--block);
        height: 300px;
        width: 30%;
    }
    
    #middle {
        background-color: var(--block);
        height: 300px;
        width: 40%;
    }
    
    footer {
        background-color: var(--banner);
        color: white;
        text-align: center;
        padding: 30px;
    }
    
    ol {
        border: 2px solid var(--list-border);
        font-size: 150%;
    }
    
    main {
        display: flex;
    }
    
    #left img {
        max-width: 100%;
    }
    Podgląd strony po tym kroku (index.php)
  31. Etap 4: Skrypty PHP

    Kroki 31-37 · po tym etapie masz 36 z 36 kryteriów (pkt)

    Krok 31: Skrypt na górze pliku i połączenie z bazą

    Kryteria: ,

    R.5.1 Skrypt napisano w języku PHP i zawiera przynajmniej jedną instrukcję

    R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy baza

    ok. 4 min
    Polecenie z arkusza

    Napisany w języku PHP Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie baza

    Skrypt stoi na samej górze index.php, przed <!DOCTYPE html>: najpierw pobiera dane z bazy, a HTML niżej je tylko wypisuje (R.5.1). W bloku środkowym pojawia się na razie jedno: komunikat, gdy połączenie się nie uda.

    • e() - krótka funkcja z htmlspecialchars: każdy tekst z bazy i z formularza wypisany na stronie ma znaki <, >, & i cudzysłowy zamienione na encje, więc nie stanie się kodem strony,
    • new PDO(...) - serwer localhost, baza baza i kodowanie w jednym napisie, potem użytkownik root i puste hasło (R.5.2),
    • ERRMODE_EXCEPTION - każdy błąd bazy rzuca wyjątek; FETCH_ASSOC - wiersze przychodzą jako tablice z nazwami kolumn ($animal['gatunek'] zamiast $row[0]),
    • try / catch - gdy baza nie działa, użytkownik dostaje zwykłe zdanie, a nie komunikat PHP z danymi serwera.

    Połączenie z nazwą bazy stoi w pliku strony, bo tam klucz je sprawdza, jeśli strona się nie uruchomi (uwaga przy R.5). Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    index.php PHP zmienione: 20 linii
    <?php
    function e(string $text): string
    {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }
    
    $error = null;
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=baza;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    } catch (PDOException $exception) {
        $error = 'Nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
    <?php if ($error !== null): ?>
                <p><?= e($error) ?></p>
    <?php endif; ?>
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  32. Krok 32: Skrypt nr 1: numer gromady z pola edycyjnego

    ok. 3 min
    Polecenie z arkusza

    Zawartość bloku głównego – środkowego: efekt wykonania skryptu nr 1 Działanie skryptu nr 1: Skrypt pobiera dane z pola edycyjnego

    filter_input(INPUT_POST, 'gromada', FILTER_VALIDATE_INT, ...) odczytuje pole z formularza i od razu je sprawdza. Wynik ma trzy możliwe wartości:

    • liczba całkowita od 1 do 5 (min_range, max_range) - poprawny numer gromady,
    • false - pole wysłano, ale to nie jest liczba z zakresu (7, pusty napis, 0 OR 1=1),
    • null - formularza nie wysłano, czyli pierwsze wejście na stronę.

    Obok dwie puste tablice, $animals i $allAnimals - wypełnią je zapytania. Ustawione przed try, istnieją także wtedy, gdy połączenie się nie uda, więc pętle w HTML-u nie zgłoszą ostrzeżenia o nieznanej zmiennej.

    Dla false blok środkowy pokazuje komunikat „Wpisz numer gromady od 1 do 5.” - w wersji podstawowej numer spoza zakresu dawał po prostu pusty blok. Pole formularza dostało value: po wysłaniu wraca do niego wpisany numer (tylko poprawny - is_int). Podgląd: formularz wysłany z wartością 7.

    index.php PHP zmienione: 9 linii
    <?php
    function e(string $text): string
    {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }
    
    $error = null;
    $animals = [];
    $allAnimals = [];
    $classId = filter_input(INPUT_POST, 'gromada', FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 1, 'max_range' => 5],
    ]);
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=baza;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    } catch (PDOException $exception) {
        $error = 'Nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5" value="<?= is_int($classId) ? $classId : '' ?>">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
    <?php if ($error !== null): ?>
                <p><?= e($error) ?></p>
    <?php endif; ?>
    <?php if ($classId === false): ?>
                <p>Wpisz numer gromady od 1 do 5.</p>
    <?php endif; ?>
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  33. Krok 33: Skrypt nr 1: nagłówek z nazwą gromady

    Kryteria:

    R.5.5 Skrypt wypisuje w nagłówku h2 tekst zależny od podanej wartości w polu. Jeśli podano 1 – „RYBY”, 2 – „PŁAZY”, 3 – „GADY”, 4 – „PTAKI”, 5 – „SSAKI”

    ok. 3 min
    Polecenie z arkusza

    W zależności od wartości pola wypisuje w nagłówku drugiego stopnia: dla wartości 1 – „RYBY”, 2 – „PŁAZY”, 3 – „GADY”, 4 – „PTAKI”, 5 – „SSAKI”

    Pięć par „numer - napis” to dane, nie logika - dlatego stoją w stałej tablicy CLASS_NAMES na górze pliku, a nagłówek to jedna linia: <h2><?= CLASS_NAMES[$classId] ?></h2> (R.5.5). Zamiast pięciu gałęzi if / elseif wystarczy odczyt z tablicy po kluczu; filter_input gwarantuje, że klucz istnieje. Zapis <?= … ?> to skrót od <?php echo … ?>.

    Podgląd: wartość 4 - nagłówek PTAKI, a w polu zostaje 4, jak na obrazie 2.

    index.php PHP zmienione: 5 linii
    <?php
    const CLASS_NAMES = [1 => 'RYBY', 2 => 'PŁAZY', 3 => 'GADY', 4 => 'PTAKI', 5 => 'SSAKI'];
    
    function e(string $text): string
    {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }
    
    $error = null;
    $animals = [];
    $allAnimals = [];
    $classId = filter_input(INPUT_POST, 'gromada', FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 1, 'max_range' => 5],
    ]);
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=baza;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    } catch (PDOException $exception) {
        $error = 'Nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5" value="<?= is_int($classId) ? $classId : '' ?>">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
    <?php if ($error !== null): ?>
                <p><?= e($error) ?></p>
    <?php endif; ?>
    <?php if ($classId === false): ?>
                <p>Wpisz numer gromady od 1 do 5.</p>
    <?php endif; ?>
    <?php if (is_int($classId)): ?>
                <h2><?= CLASS_NAMES[$classId] ?></h2>
    <?php endif; ?>
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  34. Krok 34: Skrypt nr 1: zapytanie 1 jako zapytanie przygotowane

    Kryteria:

    R.5.4 Skrypt nr 1 zawiera instrukcję wysyłającą do bazy zmodyfikowane zapytanie nr 1, w ten sposób, że w sekcji warunku sprawdzana gromada jest zgodna z wartością w polu formularza. Jeśli w polu wpisana jest wartość 1 – zapytanie dotyczy ryb, wartość 2 – zapytanie dotyczy płazów itd.

    ok. 3 min
    Polecenie z arkusza

    Wysyła do bazy zmodyfikowane zapytanie nr 1, w ten sposób, że w sekcji warunku sprawdzana gromada jest zgodna z wartością pobraną z pola edycyjnego. Jeśli w polu wpisana jest wartość 1 – zapytanie dotyczy ryb, wartość 2 – zapytanie dotyczy płazów itd.

    Zapytanie 1, w którym liczbę w warunku zastępuje parametr :classId (R.5.4):

    • $pdo->prepare(...) - baza dostaje samą treść zapytania,
    • $statement->execute(['classId' => $classId]) - osobno przychodzi numer gromady,
    • fetchAll() - od razu wszystkie wiersze wyniku jako tablica, bez pętli while.

    Zapytanie wysyła się tylko dla poprawnego numeru (is_int). Dane z formularza nigdy nie staną się częścią kodu SQL - w wersji podstawowej wartość 0 OR 1=1 wypisywała wszystkie zwierzęta, a tutaj odpada już na filter_input, a nawet gdyby przeszła, poszłaby do bazy jako wartość, nie jako kod. Podgląd wygląda jak w poprzednim kroku: wiersze są pobrane, ale jeszcze nie wypisane.

    index.php PHP zmienione: 6 linii
    <?php
    const CLASS_NAMES = [1 => 'RYBY', 2 => 'PŁAZY', 3 => 'GADY', 4 => 'PTAKI', 5 => 'SSAKI'];
    
    function e(string $text): string
    {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }
    
    $error = null;
    $animals = [];
    $allAnimals = [];
    $classId = filter_input(INPUT_POST, 'gromada', FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 1, 'max_range' => 5],
    ]);
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=baza;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        if (is_int($classId)) {
            $statement = $pdo->prepare('SELECT gatunek, wystepowanie FROM zwierzeta WHERE Gromady_id = :classId;');
            $statement->execute(['classId' => $classId]);
            $animals = $statement->fetchAll();
        }
    } catch (PDOException $exception) {
        $error = 'Nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5" value="<?= is_int($classId) ? $classId : '' ?>">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
    <?php if ($error !== null): ?>
                <p><?= e($error) ?></p>
    <?php endif; ?>
    <?php if ($classId === false): ?>
                <p>Wpisz numer gromady od 1 do 5.</p>
    <?php endif; ?>
    <?php if (is_int($classId)): ?>
                <h2><?= CLASS_NAMES[$classId] ?></h2>
    <?php endif; ?>
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>

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

  35. Krok 35: Skrypt nr 1: gatunek i występowanie w osobnych wierszach

    Kryteria:

    R.5.6 Skrypt nr 1 wypisuje zwrócone zapytaniem rekordy w osobnych wierszach, w formacie „<gatunek>, <występowanie>” Dane muszą być pobrane z bazy danych

    ok. 3 min
    Polecenie z arkusza

    Wartości zwrócone zapytaniem są wypisywane w osobnych wierszach, w formacie „<gatunek>, <występowanie>”

    Pętla foreach po gotowej tablicy $animals - każdy element to jeden wiersz z kluczami z nazw kolumn. Format z arkusza: gatunek, przecinek, spacja, występowanie i <br> (R.5.6). Tekst z bazy idzie przez e().

    Pętla stoi w HTML-u w składni alternatywnej (foreach (...): … endforeach;) - przy przeplataniu PHP z HTML-em łatwiej ją czytać niż klamry. Podgląd: Wrona siwa, Europa, Puszczyk zwyczajny, Eurazja, Sroka zwyczajna, Eurazja - jak na obrazie 2.

    index.php PHP zmienione: 3 linie
    <?php
    const CLASS_NAMES = [1 => 'RYBY', 2 => 'PŁAZY', 3 => 'GADY', 4 => 'PTAKI', 5 => 'SSAKI'];
    
    function e(string $text): string
    {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }
    
    $error = null;
    $animals = [];
    $allAnimals = [];
    $classId = filter_input(INPUT_POST, 'gromada', FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 1, 'max_range' => 5],
    ]);
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=baza;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        if (is_int($classId)) {
            $statement = $pdo->prepare('SELECT gatunek, wystepowanie FROM zwierzeta WHERE Gromady_id = :classId;');
            $statement->execute(['classId' => $classId]);
            $animals = $statement->fetchAll();
        }
    } catch (PDOException $exception) {
        $error = 'Nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5" value="<?= is_int($classId) ? $classId : '' ?>">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
    <?php if ($error !== null): ?>
                <p><?= e($error) ?></p>
    <?php endif; ?>
    <?php if ($classId === false): ?>
                <p>Wpisz numer gromady od 1 do 5.</p>
    <?php endif; ?>
    <?php if (is_int($classId)): ?>
                <h2><?= CLASS_NAMES[$classId] ?></h2>
    <?php foreach ($animals as $animal): ?>
                <?= e($animal['gatunek']) ?>, <?= e($animal['wystepowanie']) ?><br>
    <?php endforeach; ?>
    <?php endif; ?>
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  36. Krok 36: Skrypt nr 2: zapytanie 2 i lista wszystkich zwierząt

    Kryteria: ,

    R.5.7 Skrypt nr 2 zawiera instrukcję wysyłającą do bazy zapytanie 2

    R.5.8 Skrypt nr 2 wypisuje w kolejnych wierszach rekordy w formacie: „<id>. <gatunek>, <nazwa gromady>. Dane muszą być pobrane z bazy danych

    ok. 3 min
    Polecenie z arkusza

    Zawartość bloku głównego – prawego: Efekt wykonania skryptu nr 2 Działanie skryptu nr 2: Skrypt wysyła do bazy zapytanie numer 2 W kolejnych wierszach wypisywane są rekordy w formacie: „<id>. <gatunek>, <nazwa gromady>”

    Zapytanie 2 bez zmian (R.5.7) - nie ma w nim danych od użytkownika, więc wystarczy zwykłe $pdo->query(...) i fetchAll(). Wysyła się zawsze, także przed wysłaniem formularza.

    W bloku prawym druga pętla foreach: numer, kropka, spacja, gatunek, przecinek, nazwa gromady (R.5.8). id to liczba z bazy, więc nie potrzebuje e(). Pusta tablica $allAnimals ustawiona na początku skryptu sprawia, że po nieudanym połączeniu pętla po prostu nic nie wypisze. Podgląd: dziewięć zwierząt, od 1. Sum pospolity, ryby do 9. Dingo australijski, ssaki.

    index.php PHP zmienione: 7 linii
    <?php
    const CLASS_NAMES = [1 => 'RYBY', 2 => 'PŁAZY', 3 => 'GADY', 4 => 'PTAKI', 5 => 'SSAKI'];
    
    function e(string $text): string
    {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }
    
    $error = null;
    $animals = [];
    $allAnimals = [];
    $classId = filter_input(INPUT_POST, 'gromada', FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 1, 'max_range' => 5],
    ]);
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=baza;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        if (is_int($classId)) {
            $statement = $pdo->prepare('SELECT gatunek, wystepowanie FROM zwierzeta WHERE Gromady_id = :classId;');
            $statement->execute(['classId' => $classId]);
            $animals = $statement->fetchAll();
        }
    
        $allAnimals = $pdo->query(
            'SELECT zwierzeta.id, gatunek, nazwa FROM zwierzeta JOIN gromady ON zwierzeta.Gromady_id = gromady.id;'
        )->fetchAll();
    } catch (PDOException $exception) {
        $error = 'Nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5" value="<?= is_int($classId) ? $classId : '' ?>">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
    <?php if ($error !== null): ?>
                <p><?= e($error) ?></p>
    <?php endif; ?>
    <?php if ($classId === false): ?>
                <p>Wpisz numer gromady od 1 do 5.</p>
    <?php endif; ?>
    <?php if (is_int($classId)): ?>
                <h2><?= CLASS_NAMES[$classId] ?></h2>
    <?php foreach ($animals as $animal): ?>
                <?= e($animal['gatunek']) ?>, <?= e($animal['wystepowanie']) ?><br>
    <?php endforeach; ?>
    <?php endif; ?>
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
    <?php foreach ($allAnimals as $animal): ?>
                <?= $animal['id'] ?>. <?= e($animal['gatunek']) ?>, <?= e($animal['nazwa']) ?><br>
    <?php endforeach; ?>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.php)
  37. Krok 37: Zamknięcie połączenia z bazą

    Kryteria:

    R.5.3 Po wykonaniu operacji na bazie zastosowano funkcję zamknięcia bazy

    ok. 2 min
    Polecenie z arkusza

    Na końcu działania skrypt zamyka połączenie z serwerem bazodanowym

    PDO nie ma funkcji close - połączenie zamyka się, gdy znika ostatnie odwołanie do obiektu. Dlatego $statement = null i $pdo = null (R.5.3).

    Stoją w bloku finally, który wykonuje się zawsze po try - po udanych zapytaniach i po wyjątku. Oba skrypty pobrały już dane do tablic, więc połączenie zamyka się, zanim przeglądarka dostanie choć linię HTML-a. W wersji podstawowej mysqli_close musiało stać za skryptem nr 2 w bloku prawym; tutaj miejsce zamknięcia nie zależy od układu strony.

    index.php PHP zmienione: 3 linie
    <?php
    const CLASS_NAMES = [1 => 'RYBY', 2 => 'PŁAZY', 3 => 'GADY', 4 => 'PTAKI', 5 => 'SSAKI'];
    
    function e(string $text): string
    {
        return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    }
    
    $error = null;
    $animals = [];
    $allAnimals = [];
    $classId = filter_input(INPUT_POST, 'gromada', FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 1, 'max_range' => 5],
    ]);
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=baza;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        if (is_int($classId)) {
            $statement = $pdo->prepare('SELECT gatunek, wystepowanie FROM zwierzeta WHERE Gromady_id = :classId;');
            $statement->execute(['classId' => $classId]);
            $animals = $statement->fetchAll();
        }
    
        $allAnimals = $pdo->query(
            'SELECT zwierzeta.id, gatunek, nazwa FROM zwierzeta JOIN gromady ON zwierzeta.Gromady_id = gromady.id;'
        )->fetchAll();
    } catch (PDOException $exception) {
        $error = 'Nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę.';
    } finally {
        $statement = null;
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Dane o zwierzętach</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <header>
            <h1>ATLAS ZWIERZĄT</h1>
        </header>
        <section id="form-block">
            <h2>Gromady:</h2>
            <ol>
                <li>Ryby</li>
                <li>Płazy</li>
                <li>Gady</li>
                <li>Ptaki</li>
                <li>Ssaki</li>
            </ol>
            <form method="post">
                <label for="gromada">Wybierz gromadę: </label>
                <input type="number" id="gromada" name="gromada" min="1" max="5" value="<?= is_int($classId) ? $classId : '' ?>">
                <button type="submit">Wyświetl</button>
            </form>
        </section>
        <main>
            <section id="left">
                <img src="zwierzeta.jpg" alt="dzikie zwierzęta">
            </section>
            <section id="middle">
    <?php if ($error !== null): ?>
                <p><?= e($error) ?></p>
    <?php endif; ?>
    <?php if ($classId === false): ?>
                <p>Wpisz numer gromady od 1 do 5.</p>
    <?php endif; ?>
    <?php if (is_int($classId)): ?>
                <h2><?= CLASS_NAMES[$classId] ?></h2>
    <?php foreach ($animals as $animal): ?>
                <?= e($animal['gatunek']) ?>, <?= e($animal['wystepowanie']) ?><br>
    <?php endforeach; ?>
    <?php endif; ?>
            </section>
            <section id="right">
                <h2>Wszystkie zwierzęta w bazie</h2>
    <?php foreach ($allAnimals as $animal): ?>
                <?= $animal['id'] ?>. <?= e($animal['gatunek']) ?>, <?= e($animal['nazwa']) ?><br>
    <?php endforeach; ?>
            </section>
        </main>
        <footer>
            <a href="https://atlas-zwierzat.pl" target="_blank" rel="noopener">Poznaj inne strony o zwierzętach</a>
            autor Atlasu zwierząt: Bartosz Bryniarski
        </footer>
    </body>
    </html>

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

  38. Etap 5: Porównanie z wersją podstawową

    Krok 38 · po tym etapie masz 36 z 36 kryteriów (pkt)

    Krok 38: Co jest inaczej i którą wersję wybrać na egzaminie

    ok. 3 min

    Obie wersje dają komplet 36 punktów. Różnice:

    wersja podstawowawersja nowoczesna
    układfloat: left sekcji, float: none bloku formularza, clear stopkitrzy bloki w <main> z display: flex
    kolorywpisane w każdej regulezmienne w :root
    zdjęcie400 px, przy węższym oknie wchodzi pod blok środkowymax-width: 100% - zawsze w bloku
    formularztekst, pole, przycisk inputlabel for, min/max, numer wraca do pola, button
    bibliotekamysqli (tabela 1 arkusza)PDO z wyjątkami i try / catch
    gdzie jest skryptw blokach środkowym i prawymna górze pliku, w blokach tylko pętle wypisujące
    wartość z pola$_POST wprost do zapytaniafilter_input z zakresem 1-5 i zapytanie przygotowane
    nazwa gromadypięć gałęzi if / elseifstała tablica CLASS_NAMES
    wiersze wynikuwhile + mysqli_fetch_row, $row[0]fetchAll + foreach, $animal['gatunek']
    zamknięcie bazymysqli_close po skrypcie nr 2$pdo = null w finally
    numer spoza 1-5pusty blok (albo wszystkie zwierzęta po wstrzyknięciu)komunikat „Wpisz numer gromady od 1 do 5.”

    W większym serwisie dane logowania do bazy trzyma się w osobnym pliku poza katalogiem strony, a nazwę gromady pobiera z tabeli gromady zamiast z tablicy w kodzie. Tutaj klucz sprawdza połączenie w kodzie strony, a napisy wielkimi literami z polskimi znakami (PŁAZY) nie są zapisane w bazie - tabela ma plazy.

    Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 i łatwiej ją napisać bez dokumentacji. Nowoczesna jest odporna na wstrzyknięcie SQL i błędne dane od pierwszej linii - a klucz przyjmuje obie.

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

  39. Etap 6: Oddanie pracy

    Krok 39 · po tym etapie masz 36 z 36 kryteriów (pkt)

    Krok 39: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    UWAGA: po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny. Umieść go w folderze z numerem zdającego.

    W przeglądarka.txt nazwa przeglądarki, w której sprawdzana była strona przez http://localhost/…. W folderze z numerem zdającego: import.png, index.php, kw1.jpg - kw4.jpg, kwerendy.txt, przeglądarka.txt, styl3.css i zwierzeta.jpg. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

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