Przejdź do głównej treści
INF.03-12-25.01-SGStyczeń 2025 · 40 kroków · ok. 87 min · 40 kryteriów z klucza

Rozwiązanie krok po kroku: Witryna internetowa piekarni (Wersja podstawowa)

Rozwiązanie buduje stronę piekarni: baza piekarnia z jedną tabelą wyroby i cztery zapytania - filtr po rodzaju, unikalne wartości posortowane malejąco (DISTINCT), wyszukiwanie fragmentu napisu (LIKE) i średnia w grupach zaokrąglona do dwóch miejsc (AVG, ROUND, GROUP BY), potem grafika złożona z dwóch zdjęć (rogal schowany pod preclem, cień, przezroczyste tło), strona piekarnia.php z obrazem na tylnym planie i półprzezroczystym nagłówkiem oraz style w styles.css. Dwa skrypty PHP: pierwszy wypełnia listę rozwijaną rodzajami wypieków z bazy, drugi po wysłaniu formularza pokazuje w tabeli wyroby wybranego rodzaju.

Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypty są najpierw pisane najprościej (mysqli_query, mysqli_fetch_row), a na końcu zostają przerobione na wersję z prawdziwych projektów - z pokazaną na prawdziwym uruchomieniu luką SQL injection i jej naprawą.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (PDO, zapytania przygotowane)” jest drugi sposób rozwiązania tego samego arkusza: kolory w zmiennych CSS i PHP na PDO z zapytaniem przygotowanym, białą listą rodzajów i zapamiętanym wyborem od pierwszej linii - obie wersje są zgodne z kluczem.

Baza i grafiki pochodzą z prawdziwego archiwum pliki1 (załącznik do 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 strony to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2; od kroku ze Skryptem 2 - po wysłaniu formularza z rodzajem „PIECZYWO MIESZANE”, jak na ilustracji 2.

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 - można stracić 10 kryteriów i nadal zdać. 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: Baza danych piekarnia

    Kryteria:

    R.1.1 Wykonany import tabeli do bazy danych piekarnia co jest udokumentowane plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie piekarnia, z zestawem polskich znaków (np. utf8_unicode_ci).

    Rozpakuj pliki1.7z z pulpitu (hasło ULeptnny!) do folderu z numerem zdającego: baza.sql, wypieki.jpg, rogal.jpg i teksty.txt. W phpMyAdmin: Nowa, nazwa piekarnia, porównywanie np. utf8_unicode_ci.

  2. Krok 2: Import tabeli z pliku baza.sql

    Kryteria:

    R.1.1 Wykonany import tabeli do bazy danych piekarnia co jest udokumentowane plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Z rozpakowanego archiwum zaimportuj tabelę z pliku baza.sql do utworzonej bazy.

    Import → baza.sql. Tabela wyroby z ilustracji 1: 93 wyroby z rodzajem, nazwą, gramaturą (w kilogramach) i ceną. Uwaga na nazwy kolumn - zaczynają się wielką literą (Rodzaj, Nazwa, Cena).

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonany import tabeli do bazy danych piekarnia co jest udokumentowane plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie PNG pod nazwą 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.

    Print Screen i zapis jako import.png - na zrzucie komunikat phpMyAdmin o udanym imporcie albo tabela wyroby w drzewku bazy.

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany.

  4. Krok 4: Zapytanie 1: wyroby z rodzaju INNE

    Kryteria: ,

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

    R.1.3 Wykonane zapytanie 1 wybierające jedynie pola z tabeli wyroby : Rodzaj, Nazwa, Gramatura i Cena dla wyrobów z rodzaju „INNE”. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = "INNE"; oraz wynik działania zapytania udokumentowany zrzutem, na którym widoczne są dokładnie 3 rekordy zawierające jedynie pola: Rodzaj, Nazwa, Gramatura, Cena

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola: Rodzaj, Nazwa, Gramatura i Cena dla wyrobów z rodzaju „INNE”.

    Zapytanie czytasz klauzula po klauzuli:

    • SELECT Rodzaj, Nazwa, Gramatura, Cena - cztery kolumny, bez ID,
    • FROM wyroby - z jedynej tabeli bazy,
    • WHERE Rodzaj = "INNE" - tylko wiersze, w których rodzaj to dokładnie napis „INNE”.

    Wynik: 3 wiersze (bułka tarta, pieczywo okolicznościowe i paszteciki z kapustą i grzybami). Zapytanie do kwerendy.txt, zrzut kw1.png. To zapytanie - z rodzajem z formularza zamiast „INNE” - wyśle Skrypt 2.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = "INNE";
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: rodzaje bez powtórzeń, malejąco

    Kryteria:

    R.1.4 Wykonane zapytanie 2 wybierające jedynie posortowane malejąco rodzaje wyrobów. Rodzaje wyrobów nie mogą się powtarzać. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC; (lub GROUP BY wtedy opcjonalnie DISTINCT ) oraz wynik działania zapytania udokumentowany zrzutem, na którym widocznych jest jedynie 11 rekordów z kolumną Rodzaj

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie posortowane malejąco rodzaje wyrobów. Rodzaje wyrobów nie mogą się powtarzać.

    • SELECT DISTINCT Rodzaj - DISTINCT usuwa powtórzenia: bez niego wyszłoby 93 wierszy, po jednym na każdy wyrób, z nim - 11, po jednym na rodzaj,
    • ORDER BY Rodzaj DESC - malejąco, czyli alfabetycznie od końca: pierwszy jest „WYROBY CUKIERNICZE I CIASTKARSKIE”, ostatni „INNE”.

    Zrzut: kw2.png. To zapytanie wyśle Skrypt 1, żeby wypełnić listę rozwijaną.

    Typowe błędy

    GROUP BY Rodzaj też usuwa powtórzenia i klucz to przyjmuje - ale bez ORDER BY ... DESC kolejność będzie rosnąca.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = "INNE";
    
    -- Zapytanie 2
    SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: wyroby ze słowem „Chałka”

    Kryteria:

    R.1.5 Wykonane zapytanie 3 wybierające jedynie pola: ID oraz Nazwa dla wyrobów, których nazwa zawiera słowo „Chałka” . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT ID, Nazwa FROM wyroby WHERE Nazwa LIKE '%Chałka%'; oraz wynik działania zapytania udokumentowany zrzutem, na którym widoczne są dokładnie 4 rekordy, jedynie pola: ID, Nazwa o numerach id: 57, 58, 61, 62

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pola: ID oraz Nazwa dla wyrobów, których nazwa zawiera słowo „Chałka”.

    • LIKE '%Chałka%' - „zawiera”: znak % oznacza dowolny ciąg znaków (także pusty) przed słowem i po nim, więc pasuje i „Chałka duża”, i nazwa ze słowem w środku.

    Wynik: 4 wiersze o ID 57, 58, 61 i 62, jak w kluczu. Zrzut: kw3.png.

    Typowe błędy

    = 'Chałka' szuka nazwy równej dokładnie temu słowu - nie zwróci nic. LIKE 'Chałka%' pominie nazwy, w których słowo nie stoi na początku.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = "INNE";
    
    -- Zapytanie 2
    SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;
    
    -- Zapytanie 3
    SELECT ID, Nazwa FROM wyroby WHERE Nazwa LIKE '%Chałka%';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: średnia cena w każdym rodzaju

    Kryteria:

    R.1.6 Wykonane zapytanie 4 wybierające pole Rodzaj oraz obliczające średnią cenę dla każdej grupy wyrobów z kategorii Rodzaj, zaokrągloną do dwóch miejsc po przecinku. Nazwa (alias) kolumny ze średnią: "Średnia_cena". W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT Rodzaj, ROUND(AVG(Cena), 2) AS "Średnia_cena" FROM wyroby GROUP BY Rodzaj; (AS opcjonalnie ) oraz wynik działania zapytania udokumentowany zrzutem, na którym widocznych jest dokładnie 11 rekordów zawierających jedynie kolumny Rodzaj i alias Średnia_cena oraz pierwszy rekord ma wartości: INNE, 13.88

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: wybierające pole Rodzaj oraz obliczające średnią cenę dla każdej grupy wyrobów z kategorii Rodzaj, zaokrągloną do dwóch miejsc po przecinku. Obliczona średnia cena powinna mieć nadaną nazwę kolumny (alias) „Średnia cena”.

    • GROUP BY Rodzaj - dzieli tabelę na grupy o tym samym rodzaju; dla każdej grupy powstaje jeden wiersz wyniku,
    • AVG(Cena) - średnia cena w grupie, ROUND(..., 2) - zaokrąglenie do dwóch miejsc po przecinku,
    • AS "Średnia cena" - alias ze spacją musi stać w cudzysłowie (albo w odwróconych apostrofach), inaczej baza uzna drugie słowo za błąd składni. Klucz podaje też wariant ze znakiem podkreślenia, Średnia_cena.

    Wynik: 11 wierszy, pierwsze to INNE 13.88, PIECZYWO DLA GASTRONOMII 3.80 - jak w kluczu (INNE 13.88). Zrzut: kw4.png.

    Typowe błędy

    AVG(Cena) bez ROUND daje długie ułamki (cena jest typu float), a bez GROUP BY - jedną średnią dla całej tabeli.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = "INNE";
    
    -- Zapytanie 2
    SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;
    
    -- Zapytanie 3
    SELECT ID, Nazwa FROM wyroby WHERE Nazwa LIKE '%Chałka%';
    
    -- Zapytanie 4
    SELECT Rodzaj, ROUND(AVG(Cena), 2) AS "Średnia cena" FROM wyroby GROUP BY Rodzaj;
    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 21 z 40 kryteriów (pkt)

    Krok 8: Grafika wypieki.png: rogal pod preclem, cień, 1700 × 240 px

    Kryteria: ,

    R.2.1 Obraz wypieki zawiera różne wypieki w tym rogala po prawej stronie. Rogal zachodzi pod precel oraz dodany cień przesunięty w prawo i w dół dla wszystkich wypieków

    R.2.2 Tło obrazu jest przezroczyste oraz szerokość wynosi 1700 px, a wysokość 240 px

    ok. 10 min
    Polecenie z arkusza

    Do grafiki z pliku wypieki.jpg należy dołączyć grafikę z pliku rogal.jpg po prawej stronie. Lewy koniec rogala zachodzi pod precel. Cechy połączonej grafiki: Tło przezroczyste. Cień przesunięty w prawo i w dół. Wymiar: szerokość 1700 px i wysokość 240 px. Nazwa pliku wypieki, format obsługujący przezroczystość.

    W GIMP-ie:

    1. otwierasz wypieki.jpg (1400 × 240), Obraz → Rozmiar płótna: szerokość 1700, wysokość 240, przesunięcie 0 - płótno rośnie w prawo; Warstwa → Warstwa do rozmiaru obrazu,
    2. dodajesz kanał alfa i Różdżką kasujesz białe tło. Precel ma zamknięte otwory - klikasz je osobno (z Shift), bo nie łączą się z tłem; białych kropek soli nie zaznaczasz,
    3. Plik → Otwórz jako warstwy rogal.jpg, kasujesz jego białe tło tak samo,
    4. w oknie Warstwy przeciągasz warstwę rogala pod warstwę wypieków - dzięki temu jego lewy koniec chowa się pod preclem, a narzędziem Przesunięcie ustawiasz go po prawej stronie, jak na ilustracji 2 (tu: rogal w oryginalnej wielkości, przy prawej krawędzi),
    5. Obraz → Spłaszcz obraz nie używasz (zabiera przezroczystość) - zamiast tego Warstwa → Scal w dół, potem Filtry → Światło i cień → Cień z dodatnimi przesunięciami X i Y (np. 8 i 8) - cień dla wszystkich wypieków naraz,
    6. Eksportuj jako wypieki.png - PNG obsługuje przezroczystość, JPG nie.
    Typowe błędy

    Rogal na warstwie nad preclem zasłoni precel zamiast schować się pod nim. Cień dodany przed wklejeniem rogala obejmie tylko część wypieków - klucz wymaga cienia dla wszystkich.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik piekarnia.php w HTML5

    Kryteria:

    R.2.3 Witryna internetowa zapisana w pliku piekarnia.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "PIEKARNIA”. Strona zawiera sekcje head i body

    ok. 1 min
    Polecenie z arkusza

    Cechy witryny: Składa się ze strony o nazwie piekarnia.php. Zapisana w języku HTML5.

    Jedna strona, piekarnia.php, zaczyna się deklaracją <!DOCTYPE html>. Dopóki nie ma w niej kodu PHP, podgląd pokazuje ją wprost.

    piekarnia.php PHP nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  10. Krok 10: Język strony

    Kryteria:

    R.2.3 Witryna internetowa zapisana w pliku piekarnia.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "PIEKARNIA”. Strona zawiera sekcje head i body

    ok. 1 min
    Polecenie z arkusza

    Zadeklarowany polski język zawartości witryny.

    Atrybut lang="pl" w znaczniku <html>.

    piekarnia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  11. Krok 11: Kodowanie polskich znaków

    Kryteria:

    R.2.3 Witryna internetowa zapisana w pliku piekarnia.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "PIEKARNIA”. Strona zawiera sekcje head i body

    ok. 1 min
    Polecenie z arkusza

    Jawnie zastosowany właściwy standard kodowania polskich znaków.

    <meta charset="UTF-8"> - jako pierwszy element <head>.

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

    Kryteria:

    R.2.3 Witryna internetowa zapisana w pliku piekarnia.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE HTML>, zadeklarowany język witryny: polski np. <html lang="pl"> oraz nadany tytuł strony "PIEKARNIA”. Strona zawiera sekcje head i body

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony „PIEKARNIA”, widoczny na karcie przeglądarki.

    <title> w <head>.

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

    Kryteria:

    R.3.2 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styles.css formatowanie CSS 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 styles.css prawidłowo połączony z kodem strony.

    <link rel="stylesheet"> - uwaga na nazwę: styles.css, z „s” na końcu.

    Typowe błędy

    style.css albo styl.css (jak w innych arkuszach) odcina wszystkie style, a razem z nimi kryterium R.3.2.

    piekarnia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  14. Krok 14: Obraz wypieków

    Kryteria:

    R.2.6 Umieszczona grafika z wypiekami z tekstem alternatywnym "Produkty naszej piekarni"

    ok. 1 min
    Polecenie z arkusza

    Obraz wypieki.png z tekstem alternatywnym o treści: „Produkty naszej piekarni” umieszczony jest na tylnym planie strony. Bloki strony zakrywają obraz.

    Obraz stawiasz bezpośrednio w <body>, poza blokami - jest tłem całej strony, a nie częścią któregoś bloku. Na tylny plan przeniesie go dopiero CSS (position: fixed i z-index); na razie stoi w zwykłym miejscu.

    piekarnia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  15. Krok 15: Bloki strony

    Kryteria: ,

    R.2.4 Zdefiniowany układ strony dzielący ją na bloki: nawigacyjny, nagłówkowy, główny i stopki przy pomocy semantycznych znaczników sekcji języka HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, do stopki - footer. Dopuszcza się dodatkowe użycie bloków div lub section

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 2 w arkuszu egzaminacyjnym. Nie należy brać pod uwagę położenia obrazu

    ok. 1 min
    Polecenie z arkusza

    Podział strony na bloki: nawigacyjny, nagłówkowy, główny, stopki. Podział zrealizowany za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z ilustracją 2.

    Cztery znaczniki semantyczne w kolejności z ilustracji: <nav> (nawigacja jest nad nagłówkiem), <header>, <main> na blok główny i <footer>. Wszystkie bloki są jeden pod drugim na całą szerokość, więc układ nie wymaga float ani grid.

    piekarnia.php PHP zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
        </nav>
        <header>
        </header>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  16. Krok 16: Nawigacja: odnośniki do zrzutów

    Kryteria: ,

    R.2.7 W bloku nawigacyjnym umieszczone 4 odnośniki o treści KWERENDA1, KWERENDA2, KWERENDA3, KWERENDA4

    R.3.3 Po wybraniu przynajmniej jednego odnośnika otwiera/pobiera się plik graficzny

    ok. 2 min
    Polecenie z arkusza

    Zawartość bloku nawigacyjnego: Cztery odnośniki o treści: KWERENDA1, KWERENDA2, KWERENDA3, KWERENDA4. Odnośniki prowadzą do kolejnych zrzutów ekranu z kwerendami.

    Cztery <a> do zrzutów kw1.png - kw4.png, które leżą w tym samym folderze co strona - w href wystarczy sama nazwa pliku, a kliknięcie otworzy obraz w przeglądarce. W podglądzie kliknięcia są zablokowane.

    piekarnia.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
        </header>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  17. Krok 17: Nagłówki bloku nagłówkowego

    Kryteria:

    R.2.9 Zapisany nagłówek <h1>: „WITAMY”, <h4>: "NA STRONIE PIEKARNI" oraz <h4>: „Wybierz rodzaj wypieków:"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku nagłówkowego: Nagłówek pierwszego stopnia o treści: „WITAMY”. Nagłówek czwartego stopnia o treści: „NA STRONIE PIEKARNI”.

    <h1> i <h4>.

    piekarnia.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
        </header>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  18. Krok 18: Paragraf z tekstem o piekarni

    Kryteria:

    R.2.9 Zapisany nagłówek <h1>: „WITAMY”, <h4>: "NA STRONIE PIEKARNI" oraz <h4>: „Wybierz rodzaj wypieków:"

    ok. 1 min
    Polecenie z arkusza

    Paragraf (akapit) zawierający tekst. Tekst można skopiować z pliku teksty.txt z wypakowanego archiwum.

    Otwórz teksty.txt w edytorze i skopiuj całość do <p>.

    piekarnia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  19. Krok 19: Blok główny: nagłówek

    Kryteria:

    R.2.9 Zapisany nagłówek <h1>: „WITAMY”, <h4>: "NA STRONIE PIEKARNI" oraz <h4>: „Wybierz rodzaj wypieków:"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego: Nagłówek czwartego stopnia o treści: „Wybierz rodzaj wypieków:”.

    <h4>.

    piekarnia.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  20. Krok 20: Formularz: lista rozwijana i przycisk

    Kryteria: , ,

    R.2.8 W bloku głównym umieszczony formularz z listą rozwijaną oraz przyciskiem „Wybierz”, zastosowane znaczniki <form>, <select>, <option> i przycisku (w skrypcie lub HTML)

    R.3.4 Formularz wysyła dane metodą POST do tego samego pliku (poprawne również bez atrybutu action )

    R.3.5 Przycisk realizuje funkcję wysłania danych z formularza (input lub button z typem submit lub button bez typu )

    ok. 2 min
    Polecenie z arkusza

    Formularz wysyłający dane metodą bezpieczną do tego samego pliku. Pola formularza: Lista rozwijana wypełniona przez skrypt 1. Przycisk „Wybierz” wysyłający dane do skryptu 2 z formularza.

    • „metoda bezpieczna” w arkuszach CKE to POST - dane nie trafiają do paska adresu (w specyfikacji HTTP „bezpieczne” są metody, które niczego nie zmieniają na serwerze, czyli GET i HEAD - arkusz używa tego słowa w innym sensie); action pomijasz, więc formularz wraca do piekarnia.php (R.3.4),
    • <select name="type"> na razie pusty - opcje (rodzaje z bazy) dopisze Skrypt 1; pod nazwą type Skrypt 2 znajdzie wybraną wartość w $_POST,
    • przycisk type="submit" z napisem „Wybierz” (R.3.5).
    piekarnia.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                </select>
                <button type="submit">Wybierz</button>
            </form>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  21. Krok 21: Tabela: wiersz nagłówkowy

    Kryteria:

    R.2.5 W bloku głównym zapisana tabela o 4 kolumnach. Pierwszy wiersz tabeli jest nagłówkowy. Zastosowane znaczniki <table>, <tr>, <th>, <td> (w skrypcie lub HTML)

    ok. 2 min
    Polecenie z arkusza

    Tabela o czterech kolumnach zawierająca: Wiersz z komórkami nagłówkowymi: Rodzaj, Nazwa, Gramatura, Cena. Wiersze z danymi wypełnione skryptem 2.

    Pierwszy wiersz z czterema <th> - w tej samej kolejności co kolumny zapytania 1. Wiersze z danymi dopisze Skrypt 2.

    piekarnia.php PHP zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
            </table>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  22. Krok 22: Stopka: autor i data

    Kryteria:

    R.2.10 W bloku stopki umieszczony paragraf z numerem zdającego oraz paragraf z datą egzaminu

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: Paragraf „AUTOR ”, dalej wstawiony numer zdającego. Paragraf „Data: ”, dalej wpisana data egzaminu.

    Dwa osobne paragrafy. Na egzaminie po słowie „AUTOR” wpisujesz swój numer zdającego (PESEL), a po „Data:” - dzień egzaminu. Tu: autor rozwiązania i data jego przygotowania.

    piekarnia.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  23. Etap 3: Styl CSS

    Kroki 23-32 · po tym etapie masz 31 z 40 kryteriów (pkt)

    Krok 23: Plik styles.css: czcionka dla wszystkich

    Kryteria:

    R.4.1 Ustawione domyślne formatowanie wszystkich selektorów (*) krój czcionki: Verdana oraz dla body lub kontenera całej strony tło np. linear-gradient(Teal, AliceBlue), biały kolor czcionki, wyrównanie tekstu do środka, marginesy zewnętrzne (margin) lewy i prawy 20px

    ok. 1 min
    Polecenie z arkusza

    Domyślne formatowanie wszystkich selektorów: krój czcionki Verdana.

    „Wszystkie selektory” to selektor uniwersalny *.

    styles.css CSS nowy plik
    * {
        font-family: Verdana;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  24. Krok 24: Ciało strony: gradient i marginesy

    Kryteria:

    R.4.1 Ustawione domyślne formatowanie wszystkich selektorów (*) krój czcionki: Verdana oraz dla body lub kontenera całej strony tło np. linear-gradient(Teal, AliceBlue), biały kolor czcionki, wyrównanie tekstu do środka, marginesy zewnętrzne (margin) lewy i prawy 20px

    ok. 2 min
    Polecenie z arkusza

    Dla ciała strony: tło jako gradient liniowy pionowy od koloru Teal do AliceBlue, biały kolor czcionki, wyrównanie tekstu do środka, jedynie marginesy zewnętrzne lewy i prawy 20 px.

    linear-gradient(Teal, AliceBlue) bez kierunku biegnie z góry na dół, czyli pionowo. Gradient to obraz, więc we właściwości background, nie background-color. „Jedynie lewy i prawy” - margin: 0 20px: góra i dół 0, boki 20 px.

    styles.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  25. Krok 25: Obraz na tylnym planie

    Kryteria: , ,

    R.4.4 Ustawione cechy obrazu: blokowy sposób wyświetlania, stałe położenie na stronie z odstępem od góry 70px, np.: display: block; position: fixed; (lub absolute; ) top: 70px; dopuszcza się też margin-top: 70px;

    R.4.5 Obraz jest pod spodem innych elementów strony np. z-index = -1

    R.4.6 Ustawiona szerokość 100% dla obrazu i 70% dla tabeli

    ok. 3 min
    Polecenie z arkusza

    Dla obrazu: szerokość 100%, blokowy sposób wyświetlania, stałe położenie na stronie z odstępem od góry 70 px. Obraz jest zawsze pod spodem treści strony.

    • display: block - obraz jako blok, a nie element w linii tekstu,
    • position: fixed i top: 70px - „stałe położenie”: obraz jest przypięty do okna 70 px od góry i nie przewija się razem ze stroną,
    • z-index: -1 - kolejność warstw: ujemna wartość stawia obraz pod blokami strony, więc nagłówek i blok główny go zakrywają (R.4.5).

    Element z position: fixed wypada z normalnego układu - bloki strony zachowują się tak, jakby obrazu nie było, i zaczynają się od góry.

    Typowe błędy

    Bez z-index: -1 obraz przykrywa nagłówek. Selektor obrazu musi być img - przy klasie albo identyfikatorze sprawdź, czy pasuje do znacznika w HTML.

    styles.css CSS zmienione: 7 linii
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  26. Krok 26: Odnośniki

    Kryteria: , ,

    R.4.3 Ustawiony biały kolor czcionki dla odnośnika oraz cień zewnętrzny dla selektora h1: np. text-shadow: 2px 2px 5px black

    R.4.7 Ustawiony rozmiar czcionki 130% dla odnośnika

    R.4.8 Ustawione marginesy wewnętrzne (padding) 30px dla odnośnika, bloku głównego i stopki, 10px dla bloku nagłówkowego oraz margines zewnętrzny górny 100px dla bloku nagłówkowego i auto dla tabeli

    ok. 1 min
    Polecenie z arkusza

    Dla odnośnika: rozmiar czcionki 130%, marginesy wewnętrzne 30 px, biały kolor czcionki.

    Odnośnik jest elementem w linii, więc padding rozsuwa odnośniki na boki - stąd odstępy między nimi na ilustracji 2.

    styles.css CSS zmienione: 5 linii
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    a {
        font-size: 130%;
        padding: 30px;
        color: white;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  27. Krok 27: Blok nagłówkowy: półprzezroczyste tło i zaokrąglone górne rogi

    Kryteria: , ,

    R.4.2 Ustawiony kolor tła RGBA(160, 82, 45, 0.6) dla bloku nagłówkowego (poprawnie również gdy zdefiniowano opacity: 0.6 ), SandyBrown dla bloku głównego, Sienna dla stopki i dla selektora table

    R.4.8 Ustawione marginesy wewnętrzne (padding) 30px dla odnośnika, bloku głównego i stopki, 10px dla bloku nagłówkowego oraz margines zewnętrzny górny 100px dla bloku nagłówkowego i auto dla tabeli

    R.4.9 Ustawione zaokrąglenie górnych rogów bloku nagłówkowego np. border-radius: 15px 15px 0 0; oraz dolnych rogów bloku stopki, np. border-radius: 0 0 15px 15px;

    ok. 3 min
    Polecenie z arkusza

    Dla bloku nagłówkowego: kolor tła RGB 160, 82, 45 z przezroczystością 0.6, marginesy wewnętrzne 10 px, jedynie margines zewnętrzny górny 100 px, jedynie górne rogi zaokrąglone o 15 px.

    • rgba(160, 82, 45, 0.6) - kolor RGB z czwartą wartością: krycie 0.6, więc przez tło prześwituje obraz wypieków. opacity: 0.6 też przechodzi w kluczu, ale robi przezroczystym cały blok razem z tekstem,
    • margin-top: 100px - tylko górny margines; odsłania wypieki nad nagłówkiem,
    • border-radius: 15px 15px 0 0 - cztery wartości zgodnie z ruchem wskazówek zegara od lewego górnego rogu: górne dwa zaokrąglone, dolne proste.
    styles.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    a {
        font-size: 130%;
        padding: 30px;
        color: white;
    }
    header {
        background-color: rgba(160, 82, 45, 0.6);
        padding: 10px;
        margin-top: 100px;
        border-radius: 15px 15px 0 0;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  28. Krok 28: Blok główny

    Kryteria: ,

    R.4.2 Ustawiony kolor tła RGBA(160, 82, 45, 0.6) dla bloku nagłówkowego (poprawnie również gdy zdefiniowano opacity: 0.6 ), SandyBrown dla bloku głównego, Sienna dla stopki i dla selektora table

    R.4.8 Ustawione marginesy wewnętrzne (padding) 30px dla odnośnika, bloku głównego i stopki, 10px dla bloku nagłówkowego oraz margines zewnętrzny górny 100px dla bloku nagłówkowego i auto dla tabeli

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego: kolor tła SandyBrown, marginesy wewnętrzne 30 px.

    Selektor main.

    styles.css CSS zmienione: 4 linie
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    a {
        font-size: 130%;
        padding: 30px;
        color: white;
    }
    header {
        background-color: rgba(160, 82, 45, 0.6);
        padding: 10px;
        margin-top: 100px;
        border-radius: 15px 15px 0 0;
    }
    main {
        background-color: SandyBrown;
        padding: 30px;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  29. Krok 29: Stopka: zaokrąglone dolne rogi

    Kryteria: , ,

    R.4.2 Ustawiony kolor tła RGBA(160, 82, 45, 0.6) dla bloku nagłówkowego (poprawnie również gdy zdefiniowano opacity: 0.6 ), SandyBrown dla bloku głównego, Sienna dla stopki i dla selektora table

    R.4.8 Ustawione marginesy wewnętrzne (padding) 30px dla odnośnika, bloku głównego i stopki, 10px dla bloku nagłówkowego oraz margines zewnętrzny górny 100px dla bloku nagłówkowego i auto dla tabeli

    R.4.9 Ustawione zaokrąglenie górnych rogów bloku nagłówkowego np. border-radius: 15px 15px 0 0; oraz dolnych rogów bloku stopki, np. border-radius: 0 0 15px 15px;

    ok. 1 min
    Polecenie z arkusza

    Dla bloku stopki: kolor tła Sienna, marginesy wewnętrzne 30 px, jedynie dolne rogi zaokrąglone o 15 px.

    border-radius: 0 0 15px 15px - górne rogi proste, dolne (prawy dolny i lewy dolny) zaokrąglone. Nagłówek i stopka razem tworzą jedną kartę z zaokrąglonymi rogami.

    styles.css CSS zmienione: 5 linii
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    a {
        font-size: 130%;
        padding: 30px;
        color: white;
    }
    header {
        background-color: rgba(160, 82, 45, 0.6);
        padding: 10px;
        margin-top: 100px;
        border-radius: 15px 15px 0 0;
    }
    main {
        background-color: SandyBrown;
        padding: 30px;
    }
    footer {
        background-color: Sienna;
        padding: 30px;
        border-radius: 0 0 15px 15px;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  30. Krok 30: Cień nagłówka pierwszego stopnia

    Kryteria:

    R.4.3 Ustawiony biały kolor czcionki dla odnośnika oraz cień zewnętrzny dla selektora h1: np. text-shadow: 2px 2px 5px black

    ok. 1 min
    Polecenie z arkusza

    Dla selektora nagłówka pierwszego stopnia: zewnętrzny cień tekstu przesunięty w poziomie i pionie o 2 px, promień rozmycia 5 px, kolor cienia czarny.

    text-shadow: przesunięcie poziome, pionowe, rozmycie, kolor.

    styles.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    a {
        font-size: 130%;
        padding: 30px;
        color: white;
    }
    header {
        background-color: rgba(160, 82, 45, 0.6);
        padding: 10px;
        margin-top: 100px;
        border-radius: 15px 15px 0 0;
    }
    main {
        background-color: SandyBrown;
        padding: 30px;
    }
    footer {
        background-color: Sienna;
        padding: 30px;
        border-radius: 0 0 15px 15px;
    }
    h1 {
        text-shadow: 2px 2px 5px black;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  31. Krok 31: Tabela: wyśrodkowanie, szerokość, tło

    Kryteria: , ,

    R.4.2 Ustawiony kolor tła RGBA(160, 82, 45, 0.6) dla bloku nagłówkowego (poprawnie również gdy zdefiniowano opacity: 0.6 ), SandyBrown dla bloku głównego, Sienna dla stopki i dla selektora table

    R.4.6 Ustawiona szerokość 100% dla obrazu i 70% dla tabeli

    R.4.8 Ustawione marginesy wewnętrzne (padding) 30px dla odnośnika, bloku głównego i stopki, 10px dla bloku nagłówkowego oraz margines zewnętrzny górny 100px dla bloku nagłówkowego i auto dla tabeli

    ok. 1 min
    Polecenie z arkusza

    Dla selektora tabeli: marginesy zewnętrzne automatycznie wyliczane przez przeglądarkę, szerokość 70%, kolor tła Sienna.

    margin: auto wyśrodkowuje tabelę w bloku głównym. Selektor znacznika table, jak wymaga arkusz.

    styles.css CSS zmienione: 5 linii
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    a {
        font-size: 130%;
        padding: 30px;
        color: white;
    }
    header {
        background-color: rgba(160, 82, 45, 0.6);
        padding: 10px;
        margin-top: 100px;
        border-radius: 15px 15px 0 0;
    }
    main {
        background-color: SandyBrown;
        padding: 30px;
    }
    footer {
        background-color: Sienna;
        padding: 30px;
        border-radius: 0 0 15px 15px;
    }
    h1 {
        text-shadow: 2px 2px 5px black;
    }
    table {
        margin: auto;
        width: 70%;
        background-color: Sienna;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  32. Krok 32: Tabela: obramowanie połączone

    Kryteria:

    R.4.10 Ustawione dla tabeli i komórek tabeli obramowanie linią ciągłą o grubości 1px i kolorze SandyBrown, dla tabeli obramowanie połączone (border-collapse: collapse)

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla selektora tabeli i komórek tabeli: obramowanie linią ciągłą o grubości 1 px i kolorze SandyBrown, obramowanie połączone.

    border-collapse: collapse łączy sąsiednie ramki komórek w jedną linię. Ramka w kolorze tła bloku głównego wygląda jak jasne odstępy między komórkami.

    styles.css CSS zmienione: 4 linie
    * {
        font-family: Verdana;
    }
    body {
        background: linear-gradient(Teal, AliceBlue);
        color: white;
        text-align: center;
        margin: 0 20px;
    }
    img {
        width: 100%;
        display: block;
        position: fixed;
        top: 70px;
        z-index: -1;
    }
    a {
        font-size: 130%;
        padding: 30px;
        color: white;
    }
    header {
        background-color: rgba(160, 82, 45, 0.6);
        padding: 10px;
        margin-top: 100px;
        border-radius: 15px 15px 0 0;
    }
    main {
        background-color: SandyBrown;
        padding: 30px;
    }
    footer {
        background-color: Sienna;
        padding: 30px;
        border-radius: 0 0 15px 15px;
    }
    h1 {
        text-shadow: 2px 2px 5px black;
    }
    table {
        margin: auto;
        width: 70%;
        background-color: Sienna;
    }
    table, td, th {
        border: 1px solid SandyBrown;
        border-collapse: collapse;
    }
    Podgląd strony po tym kroku (piekarnia.php)
  33. Etap 4: Skrypty PHP

    Kroki 33-37 · po tym etapie masz 40 z 40 kryteriów (pkt)

    Krok 33: Połączenie w liście, zamknięcie w tabeli

    Kryteria: , ,

    R.5.1 Skrypt jest napisany w języku PHP i zawiera przynajmniej jedną instrukcję zgodną z treścią zadania

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

    R.5.3 Ostatnią operacją na bazie jest jej zamknięcie

    ok. 3 min
    Polecenie z arkusza

    Łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie piekarnia. Na końcu jest zamykane połączenie z serwerem.

    Skrypt 1 stoi wewnątrz <select>, bo wypisuje elementy listy, a Skrypt 2 - w tabeli, pod wierszem nagłówkowym. Połączenie otwierasz w pierwszym bloku (Skrypt 1 jest wyżej na stronie, więc wykona się pierwszy), a zamknięcie mysqli_close stawiasz w drugim - to będzie ostatnia operacja na bazie (R.5.3). Zmienna $connection z pierwszego bloku jest dostępna w drugim - to ten sam plik PHP.

    piekarnia.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                    <?php
                        $connection = mysqli_connect("localhost", "root", "", "piekarnia");
                    ?>
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
                <?php
                    mysqli_close($connection);
                ?>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  34. Krok 34: Skrypt 1: wysłanie zapytania 2

    Kryteria:

    R.5.4 Skrypt 1 zawiera instrukcję wysyłającą do bazy danych zapytanie 2 lub skrypt 2 zawiera instrukcję wysyłającą do bazy danych zmodyfikowane zapytanie 1 w ten sposób, że wartość pola Rodzaj w warunku jest pobrana z formularza

    ok. 2 min
    Polecenie z arkusza

    Skrypt 1: Wysyła do bazy danych zapytanie 2.

    Zapytanie 2 w zmiennej $query i mysqli_query - wynik trafia do $result. Lista jest jeszcze pusta: wiersze trzeba pobrać i wypisać.

    piekarnia.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                    <?php
                        $connection = mysqli_connect("localhost", "root", "", "piekarnia");
                        $query = "SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;";
                        $result = mysqli_query($connection, $query);
                    ?>
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
                <?php
                    mysqli_close($connection);
                ?>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>

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

  35. Krok 35: Skrypt 1: rodzaje w elementach listy

    Kryteria: ,

    R.5.5 Skrypt 1 wyświetla zwrócone zapytaniem wiersze w kolejnych elementach listy rozwijanej

    R.5.6 Działanie skryptu 1 oraz skryptu 2 jest uniwersalne dla dowolnej liczby zwróconych rekordów i jest zrealizowane z wykorzystaniem pętli

    ok. 3 min
    Polecenie z arkusza

    Dane zwrócone zapytaniem wyświetla w kolejnych elementach listy rozwijanej.

    Pętla while z mysqli_fetch_row - dla każdego z 11 rodzajów jeden <option>. Bez atrybutu value przeglądarka wyśle w formularzu sam tekst opcji, czyli nazwę rodzaju - dokładnie to, czego potrzebuje Skrypt 2. Pętla działa dla dowolnej liczby rodzajów (R.5.6). Podgląd: lista rozwijana z rodzajami, od „WYROBY CUKIERNICZE I CIASTKARSKIE”.

    piekarnia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                    <?php
                        $connection = mysqli_connect("localhost", "root", "", "piekarnia");
                        $query = "SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<option>$row[0]</option>";
                        }
                    ?>
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
                <?php
                    mysqli_close($connection);
                ?>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  36. Krok 36: Skrypt 2: zapytanie 1 z rodzajem z formularza

    Kryteria: ,

    R.5.4 Skrypt 1 zawiera instrukcję wysyłającą do bazy danych zapytanie 2 lub skrypt 2 zawiera instrukcję wysyłającą do bazy danych zmodyfikowane zapytanie 1 w ten sposób, że wartość pola Rodzaj w warunku jest pobrana z formularza

    R.5.8 Skrypt 2 jest zabezpieczony na wypadek braku danych wysyłanych z formularza

    ok. 4 min
    Polecenie z arkusza

    Skrypt 2: Wysyła do bazy danych zapytanie 1 zmodyfikowane w ten sposób, że wartość pola Rodzaj w warunku jest pobrana z formularza. W stanie początkowym, gdy nie wybrano opcji listy rozwijanej, w tabeli nie są wyświetlane wiersze z danymi.

    • !empty($_POST["type"]) - przy pierwszym wejściu na stronę formularz nie był wysłany, $_POST["type"] nie istnieje i warunek jest fałszywy: tabela zostaje z samym nagłówkiem (R.5.8),
    • po wysłaniu wybrany rodzaj trafia do zmiennej $type i zastępuje „INNE” w zapytaniu 1. Wartość stoi w apostrofach '$type', bo to napis; całe zapytanie jest w cudzysłowie, więc PHP wstawi w nie wartość zmiennej,
    • mysqli_close stoi pod blokiem if, poza nim - połączenie zamykasz zawsze.

    Podgląd: stan po wysłaniu formularza z „PIECZYWO MIESZANE” - zapytanie już poszło, ale wyniku jeszcze nie wypisujesz.

    piekarnia.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                    <?php
                        $connection = mysqli_connect("localhost", "root", "", "piekarnia");
                        $query = "SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<option>$row[0]</option>";
                        }
                    ?>
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
                <?php
                    if (!empty($_POST["type"])) {
                        $type = $_POST["type"];
                        $query = "SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = '$type';";
                        $result = mysqli_query($connection, $query);
                    }
                    mysqli_close($connection);
                ?>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>

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

  37. Krok 37: Skrypt 2: wyroby w wierszach tabeli

    Kryteria: , ,

    R.5.6 Działanie skryptu 1 oraz skryptu 2 jest uniwersalne dla dowolnej liczby zwróconych rekordów i jest zrealizowane z wykorzystaniem pętli

    R.5.7 Skrypt 2 wyświetla zwrócone zapytaniem rekordy w kolejnych wierszach tabeli, w przeznaczonych do tego komórkach

    R.5.9 W skryptach zastosowana przynajmniej jedna zmienna lub funkcja oraz nazwy wszystkich funkcji i zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania

    ok. 3 min
    Polecenie z arkusza

    Zwrócone zapytaniem wiersze wyświetla w kolejnych wierszach tabeli, w przeznaczonych do tego komórkach.

    Dla każdego wyrobu wiersz <tr> z czterema <td> w kolejności kolumn zapytania: rodzaj, nazwa, gramatura, cena. Podgląd: 7 wyrobów z rodzaju PIECZYWO MIESZANE - jak na ilustracji 2. Lista po wysłaniu wraca do pierwszej opcji, bo strona ładuje się od nowa (ilustracja pokazuje to samo).

    piekarnia.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                    <?php
                        $connection = mysqli_connect("localhost", "root", "", "piekarnia");
                        $query = "SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<option>$row[0]</option>";
                        }
                    ?>
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
                <?php
                    if (!empty($_POST["type"])) {
                        $type = $_POST["type"];
                        $query = "SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = '$type';";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td></tr>";
                        }
                    }
                    mysqli_close($connection);
                ?>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  38. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 38-39 · po tym etapie masz 40 z 40 kryteriów (pkt)

    Krok 38: SQL injection: luka pokazana i zamknięta

    ok. 6 min
    Polecenie z arkusza

    Skrypt 2: Wysyła do bazy danych zapytanie 1 zmodyfikowane w ten sposób, że wartość pola Rodzaj w warunku jest pobrana z formularza.

    Lista rozwijana daje złudzenie, że użytkownik może wybrać tylko jeden z 11 rodzajów. To nieprawda - formularz da się wysłać z dowolną wartością (narzędzia programisty w przeglądarce, curl). Sprawdzone na prawdziwym uruchomieniu: wartość x' OR '1'='1 zamienia warunek w WHERE Rodzaj = 'x' OR '1'='1', który jest prawdziwy dla każdego wiersza - tabela pokazała wszystkie 93 wyroby. Tak samo da się wyciągać dane z innych tabel.

    Naprawa: zapytanie przygotowane. Znak ? to miejsce na wartość, mysqli_stmt_bind_param z typem "s" (napis) przekazuje ją osobno - baza nigdy nie potraktuje jej jak kodu SQL. Po zmianie ta sama próba zwraca 0 wierszy, a zwykły wybór z listy działa bez zmian. Stare linie zostają w komentarzu do porównania.

    Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    piekarnia.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                    <?php
                        $connection = mysqli_connect("localhost", "root", "", "piekarnia");
                        $query = "SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<option>$row[0]</option>";
                        }
                    ?>
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
                <?php
                    if (!empty($_POST["type"])) {
                        $type = $_POST["type"];
                        // $query = "SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = '$type';";
                        // $result = mysqli_query($connection, $query);
                        $statement = mysqli_prepare($connection, "SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = ?");
                        mysqli_stmt_bind_param($statement, "s", $type);
                        mysqli_stmt_execute($statement);
                        $result = mysqli_stmt_get_result($statement);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td></tr>";
                        }
                    }
                    mysqli_close($connection);
                ?>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>

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

  39. Krok 39: Zapamiętany wybór i bezpieczne wypisywanie

    ok. 4 min
    Polecenie z arkusza

    Dane zwrócone zapytaniem wyświetla w kolejnych elementach listy rozwijanej.

    Dwie drobne poprawki:

    • zapamiętany wybór - po wysłaniu lista wracała do pierwszej opcji i nie było widać, którego rodzaju dotyczy tabela. Opcja równa wysłanej wartości dostaje atrybut selected; ?? "" chroni przed ostrzeżeniem przy pierwszym wejściu, gdy $_POST["type"] nie istnieje,
    • htmlspecialchars przy wypisywaniu - nazwy wyrobów zawierają cudzysłowy (Chleb wieloziarnisty "Słońce"). W komórce tabeli to jeszcze nie szkodzi, ale ten sam tekst w atrybucie (value="...") urwałby go w połowie. Funkcja zamienia znaki specjalne HTML na encje i tekst zawsze wyświetla się dosłownie.

    Podgląd: po wysłaniu „PIECZYWO MIESZANE” lista pokazuje wybrany rodzaj. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    piekarnia.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>PIEKARNIA</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <img src="wypieki.png" alt="Produkty naszej piekarni">
        <nav>
            <a href="kw1.png">KWERENDA1</a>
            <a href="kw2.png">KWERENDA2</a>
            <a href="kw3.png">KWERENDA3</a>
            <a href="kw4.png">KWERENDA4</a>
        </nav>
        <header>
            <h1>WITAMY</h1>
            <h4>NA STRONIE PIEKARNI</h4>
            <p>Od 31 lat oferujemy najwyższej jakości pieczywo. Naturalnie świeże, naturalnie smaczne. Pieczemy wyłącznie wypieki na naturalnym zakwasie bez polepszaczy i zagęstników. Korzystamy wyłącznie z najlepszych ziaren pochodzących z ekologicznych upraw położonych w rejonach zgierskim i ozorkowskim.</p>
        </header>
        <main>
            <h4>Wybierz rodzaj wypieków:</h4>
            <form method="post">
                <select name="type">
                    <?php
                        $connection = mysqli_connect("localhost", "root", "", "piekarnia");
                        $query = "SELECT DISTINCT Rodzaj FROM wyroby ORDER BY Rodzaj DESC;";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            $selected = (($_POST["type"] ?? "") === $row[0]) ? " selected" : "";
                            echo "<option$selected>" . htmlspecialchars($row[0]) . "</option>";
                        }
                    ?>
                </select>
                <button type="submit">Wybierz</button>
            </form>
            <table>
                <tr>
                    <th>Rodzaj</th>
                    <th>Nazwa</th>
                    <th>Gramatura</th>
                    <th>Cena</th>
                </tr>
                <?php
                    if (!empty($_POST["type"])) {
                        $type = $_POST["type"];
                        // $query = "SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = '$type';";
                        // $result = mysqli_query($connection, $query);
                        $statement = mysqli_prepare($connection, "SELECT Rodzaj, Nazwa, Gramatura, Cena FROM wyroby WHERE Rodzaj = ?");
                        mysqli_stmt_bind_param($statement, "s", $type);
                        mysqli_stmt_execute($statement);
                        $result = mysqli_stmt_get_result($statement);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr>";
                            foreach ($row as $value) {
                                echo "<td>" . htmlspecialchars($value) . "</td>";
                            }
                            echo "</tr>";
                        }
                    }
                    mysqli_close($connection);
                ?>
            </table>
        </main>
        <footer>
            <p>AUTOR: Bartosz Bryniarski</p>
            <p>Data: 02.10.2026</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (piekarnia.php)
  40. Etap 6: Oddanie pracy

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

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

    ok. 5 min
    Polecenie z arkusza

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

    W przeglądarka.txt wpisujesz nazwę przeglądarki.

    W folderze: piekarnia.php, styles.css, kwerendy.txt, import.png, kw1.png - kw4.png (do nich prowadzą odnośniki w nawigacji), wypieki.png i przeglądarka.txt. 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 39.

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.