Przejdź do głównej treści
INF.03-11-24.06-SGCzerwiec 2024 · 41 kroków · ok. 81 min · 40 kryteriów z klucza

Rozwiązanie krok po kroku: Witryna hodowli świnek morskich (Nowoczesny kod (grid, PDO))

To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza hodowla z czterema zapytaniami, wykadrowane zdjęcie i trzy strony (peruwianka.php, american.php, crested.php) z menu, listą ras, danymi miotu i świnkami z tego miotu - i tak samo spełnia każde kryterium klucza. Inna jest droga:

  • siatka CSS na całej stronie: grid-template-areas stawia menu i blok główny po lewej, blok prawy obok obu, a szerokości 80% i 20% stoją w grid-template-columns (klucz R.4.5 przyjmuje je wprost). Kod HTML ma kolejność treści, bez float bloków i bez clear,
  • PHP na PDO: wszystkie dane strona pobiera na górze pliku, przed HTML-em - połączenie, trzy zapytania i zamknięcie połączenia w jednym bloku try, a w HTML-u zostają tylko pętle i wypisywanie,
  • zapytania przygotowane z parametrem :breed i identyfikator rasy w jednej zmiennej - kopie strony różnią się jedną linią i obrazem, nie czterema miejscami,
  • bezpieczne wypisywanie (htmlspecialchars w funkcji e()) i komunikaty dla rasy bez miotu, bez świnek i dla awarii bazy - zamiast pustych nagłówków albo błędu PHP.

Na końcu krótkie porównanie z wersją podstawową (zakładka obok). Baza i zdjęcia pochodzą z prawdziwego archiwum pliki11, a podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 na bazie z arkusza (także dla rasy bez świnek i dla wyłączonej bazy).

Jak liczą się punkty. Klucz ma 40 kryteriów (R.1.1 - R.5.10), każde za 1 punkt. Próg zdania to 75%, czyli 30 punktów. Przy każdym kroku jest napisane, które kryteria spełnia.

  1. Etap 1: Baza danych

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

    Krok 1: Baza danych hodowla

    ok. 2 min
    Polecenie z arkusza

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

    Archiwum pliki11.zip rozpakuj hasłem @Swinki-MorSkie! (małpa na początku, wielkie S w środku, wykrzyknik na końcu) do folderu z numerem zdającego. W phpMyAdmin Nowa → hodowla, porównywanie utf8_unicode_ci, albo zapytaniem:

    CREATE DATABASE hodowla CHARACTER SET utf8 COLLATE utf8_unicode_ci;
    
    Typowe błędy

    Skrypty łączą się z bazą po nazwie - literówka w nazwie bazy zabiera punkty za część PHP (R.5.1).

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

    ok. 2 min
    Polecenie z arkusza

    Do bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum

    Zaznaczona baza hodowla, Import → baza.sql. Dwie tabele z obrazu 1: rasy (13 ras) i swinki (data urodzenia, miot, opis, imię, cena i klucz obcy rasy_id).

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych hodowla czynność udokumentowano plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu po imporcie. Zrzut zapisz 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.

    Cały ekran z paskiem zadań, w PNG. Zrzuty zapytań idą do JPEG i tym razem muszą pokazywać także treść wykonanego zapytania (phpMyAdmin wyświetla ją nad wynikiem).

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

  4. Krok 4: Zapytanie 1: świnki urodzone w lipcu

    Kryteria: ,

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

    R.1.3 Wykonano zapytanie 1 wybierające jedynie pola imie i miot z tabeli swinki dla świnek morskich urodzonych w lipcu. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, miot FROM swinki WHERE data_ur LIKE "%-07-%"; (różne formy wyrażenia regularnego) oraz wynik działania udokumentowano zrzutem, na którym są widoczne dokładnie 3 wiersze z danymi: Ed C4, Tikka C4, Frania C4

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola imie i miot z tabeli swinki dla świnek morskich urodzonych w lipcu

    MONTH(data_ur) = 7 - funkcja daty wyciąga numer miesiąca, więc warunek działa na dacie, a nie na jej zapisie tekstowym (LIKE "%-07-%" z klucza też zadziała, ale zależy od formatu RRRR-MM-DD). Wynik: 3 wiersze - Ed, Tikka, Frania, wszystkie z miotu C4. Zapytania zapisz w kwerendy.txt, zrzut z treścią zapytania jako kw1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT imie, miot
    FROM swinki
    WHERE MONTH(data_ur) = 7;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: dane miotu rasy peruwianka

    Kryteria:

    R.1.4 Wykonano zapytanie 2 wybierające niepowtarzające się wiersze z datą urodzenia i miotem z tabeli swinki oraz odpowiadającą im nazwą rasy z tabeli rasy dla id rasy równego 1. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT DISTINCT data_ur, miot, rasa FROM swinki JOIN rasy ON rasy_id = rasy.id WHERE rasy_id=1; (lub rasy.id=1; możliwe również INNER JOIN lub bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym jest widoczny dokładnie 1 wiersz: 2022-06-02 I5 peruwianka

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 2: wybierające niepowtarzające się wiersze z datą urodzenia i miotem z tabeli swinki oraz odpowiadającą im nazwą rasy z tabeli rasy dla id rasy równego 1. Należy posłużyć się relacją

    DISTINCT zostawia jeden wiersz z każdego powtórzenia - cztery świnki z jednego miotu dają jeden wiersz. Aliasy s (swinki) i r (rasy), ON r.id = s.rasy_id - para kluczy relacji. Wynik: 1 wiersz - 2022-06-02, I5, peruwianka. Zrzut: kw2.jpg.

    Typowe błędy

    Bez DISTINCT zrzut pokazuje 4 wiersze - klucz wymaga dokładnie jednego.

    kwerendy.txt Tekst zmienione: 6 linii
    -- Zapytanie 1
    SELECT imie, miot
    FROM swinki
    WHERE MONTH(data_ur) = 7;
    
    -- Zapytanie 2
    SELECT DISTINCT s.data_ur, s.miot, r.rasa
    FROM swinki AS s
    JOIN rasy AS r ON r.id = s.rasy_id
    WHERE r.id = 1;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: świnki rasy peruwianka

    Kryteria:

    R.1.5 Wykonano zapytanie 3 wybierające jedynie imię, cenę i opis świnek morskich, których id rasy jest równe 1. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, cena, opis FROM swinki WHERE rasy_id = 1; (lub z zastosowaniem relacji) oraz wynik działania udokumentowano zrzutem, na którym są widoczne dokładnie 4 wiersze, jedynie pola imie, cena, opis dla imion: Cindy, Wendy, Mała, Lola

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie imię, cenę i opis świnek morskich, których id rasy jest równe 1

    Trzy pola i warunek na kluczu obcym rasy_id - złączenie nie jest potrzebne. Wynik: 4 wiersze - Cindy, Wendy, Mała, Lola. Zrzut: kw3.jpg.

    kwerendy.txt Tekst zmienione: 5 linii
    -- Zapytanie 1
    SELECT imie, miot
    FROM swinki
    WHERE MONTH(data_ur) = 7;
    
    -- Zapytanie 2
    SELECT DISTINCT s.data_ur, s.miot, r.rasa
    FROM swinki AS s
    JOIN rasy AS r ON r.id = s.rasy_id
    WHERE r.id = 1;
    
    -- Zapytanie 3
    SELECT imie, cena, opis
    FROM swinki
    WHERE rasy_id = 1;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: wszystkie rasy

    Kryteria:

    R.1.6 Wykonano zapytanie 4 wybierające jedynie rasę z tabeli rasy . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT rasa FROM rasy; oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 13 wierszy, jedynie nazwy ras

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 4: wybierające jedynie rasę z tabeli rasy

    Jedno pole, 13 wierszy. ORDER BY id (dodatek) ustala kolejność listy na stronie: bez niego baza zwraca wiersze w kolejności, która nie jest niczym zagwarantowana. Zrzut: kw4.jpg.

    kwerendy.txt Tekst zmienione: 5 linii
    -- Zapytanie 1
    SELECT imie, miot
    FROM swinki
    WHERE MONTH(data_ur) = 7;
    
    -- Zapytanie 2
    SELECT DISTINCT s.data_ur, s.miot, r.rasa
    FROM swinki AS s
    JOIN rasy AS r ON r.id = s.rasy_id
    WHERE r.id = 1;
    
    -- Zapytanie 3
    SELECT imie, cena, opis
    FROM swinki
    WHERE rasy_id = 1;
    
    -- Zapytanie 4
    SELECT rasa
    FROM rasy
    ORDER BY id;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

    Kroki 8-18 · po tym etapie masz 17 z 40 kryteriów (pkt)

    Krok 8: Kadrowanie crested.jpg do 500 × 330 px

    Kryteria:

    R.2.1 Grafikę crested.jpg skadrowano tak, że widoczny jest pysk zwierzęcia oraz wymiar grafiki to dokładnie 500 px szerokości i 330 px wysokości

    ok. 3 min
    Polecenie z arkusza

    Grafikę crested.jpg, wypakowaną z archiwum, należy skadrować tak, aby rozmiar obrazu po kadrowaniu wynosił dokładnie 500 px szerokości na 330 px wysokości. Na skadrowanym obrazie musi być widoczny pysk zwierzęcia. Przykład kadru zaznaczono czarnym prostokątem na obrazie 3.

    Grafika jest taka sama jak w wersji podstawowej. W GIMP-ie narzędzie Kadrowanie ze stałą wielkością 500 × 330 px, prostokąt na głowie z uszami (jak czarna ramka na obrazie 3), Obraz → Przytnij do zaznaczenia, eksport pod tą samą nazwą. To kadrowanie, nie skalowanie - piksele zostają te same. Po lewej oryginał z ramką, po prawej wynik.

    Typowe błędy

    Przeskalowanie obrazu do 500 × 330 zamiast kadrowania zniekształca proporcje - kryterium wymaga kadru.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik peruwianka.php: HTML5, język, kodowanie

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku peruwianka.php oraz zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> i zadeklarowano język witryny polski np.<HTML lang="pl">. Strona zawiera sekcje head i body

    ok. 2 min
    Polecenie z arkusza

    Składa się ze stron o nazwach peruwianka.php, american.php, crested.php zapisanych w języku HTML5. Ustawiony język zawartości strony na polski. Jawnie zastosowany właściwy standard kodowania polskich znaków

    Najpierw jedna strona, peruwianka.php - dwie pozostałe powstaną na końcu z gotowej, sprawdzonej strony. <!DOCTYPE html>, <html lang="pl"> i <meta charset="UTF-8"> jako pierwszy element <head> - razem R.2.2. Na egzaminie plik leży w htdocs XAMPP-a i otwierasz go przez http://localhost/....

    peruwianka.php PHP nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  10. Krok 10: Tytuł strony

    Kryteria:

    R.2.3 Nadano tytuł stronie: "Hodowla świnek morskich"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Hodowla świnek morskich”

    <title> i viewport - telefon nie pomniejsza strony do rozmiaru ekranu komputera.

    peruwianka.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>Hodowla świnek morskich</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  11. Krok 11: Podpięcie arkusza stylów

    Kryteria:

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

    Całe formatowanie pochodzi ze styl.css - bez atrybutów style w HTML-u (R.3.6).

    Typowe błędy

    Klucz odbiera R.3.6 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast #).

    peruwianka.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>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  12. Krok 12: Bloki semantyczne w kolejności treści

    Kryteria:

    R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: banera, menu, główny, prawy oraz stopkę. Zastosowano semantyczne znaczniki sekcji HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, stopki - footer, dopuszcza się zagnieżdżenie bloków div w znacznikach semantycznych

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: baner, dwa bloki lewe: blok menu i blok główny, jeden blok prawy, na dole blok stopki. Podział zrealizowany wyłącznie 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 obrazem 2

    Baner <header>, menu <nav>, blok główny <main>, blok prawy <aside>, stopka <footer> (R.2.4). Kolejność to kolejność treści: nagłówek, menu, główna treść, dodatki. W wersji podstawowej <aside> musiał stać przed menu, bo blok pływający zaczyna się tam, gdzie stoi w kodzie; siatka CSS postawi go obok menu niezależnie od kolejności.

    peruwianka.php PHP zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
        </header>
        <nav>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  13. Krok 13: Baner: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: nagłówek pierwszego stopnia o treści „Hodowla świnek morskich - zamów świnkowe maluszki”

    <h1> z pełną treścią z arkusza.

    peruwianka.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>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  14. Krok 14: Menu: odnośnik do peruwianka.php

    Kryteria:

    R.3.2 Odnośnik o treści "Rasa Peruwianka" inicjuje otwarcie strony peruwianka.php

    ok. 1 min
    Polecenie z arkusza

    Zawartość lewego bloku menu: Odnośnik do pliku peruwianka.php, o treści „Rasa Peruwianka”

    Odnośnik do tej samej strony, z atrybutem aria-current="page" - czytnik ekranu powie „bieżąca strona”. W kopiach strony atrybut przejdzie na ich własny odnośnik (R.3.2).

    peruwianka.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>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  15. Krok 15: Menu: odnośniki do american.php i crested.php

    Kryteria:

    R.3.3 Odnośnik o treści "Rasa American" inicjuje otwarcie strony american.php lub odnośnik o treści "Rasa Crested" inicjuje otwarcie strony crested.php (kryterium spełnione nawet, gdy pliki nie istnieją)

    ok. 1 min
    Polecenie z arkusza

    Odnośnik do pliku american.php, o treści „Rasa American”. Odnośnik do pliku crested.php, o treści „Rasa Crested”

    Dwa kolejne odnośniki. Plików jeszcze nie ma - klucz uznaje odnośnik i tak (R.3.3), a pliki powstaną na końcu.

    peruwianka.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>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  16. Krok 16: Blok prawy: nagłówek i pusta lista numerowana

    Kryteria:

    R.2.6 W prawym bloku umieszczono jedną listę numerowaną, zastosowano znaczniki ol, li (w skrypcie lub HTML)

    ok. 1 min
    Polecenie z arkusza

    Zawartość prawego bloku: Nagłówek trzeciego stopnia o treści: „Poznaj wszystkie rasy świnek morskich”. Lista numerowana (uporządkowana) wypełniona elementami przez skrypt 1

    <h3> i lista uporządkowana <ol> - numeruje elementy sama. Elementy <li> wypisze Skrypt 1 (R.2.6).

    peruwianka.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
            </ol>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  17. Krok 17: Blok główny: zdjęcie, linia pozioma, nagłówek

    Kryteria: ,

    R.2.7 W bloku głównym umieszczono obraz peruwianka.jpg z tekstem alternatywnym: „Świnka morska rasy peruwianka”

    R.2.8 W bloku głównym umieszczono linię poziomą

    ok. 2 min
    Polecenie z arkusza

    Zawartość lewego bloku głównego: Obraz peruwianka.jpg z tekstem alternatywnym: „Świnka morska rasy peruwianka”. Efekt działania skryptu 2. Linia pozioma. Nagłówek drugiego stopnia o treści: „Świnki w tym miocie”. Efekt działania skryptu 3

    Zdjęcie z tekstem alternatywnym (R.2.7), linia pozioma <hr> (R.2.8) i <h2>. Między zdjęciem a linią stanie wynik Skryptu 2, pod nagłówkiem - Skryptu 3.

    peruwianka.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
            </ol>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  18. Krok 18: Stopka

    Kryteria:

    R.2.5 W banerze zapisano nagłówek h1: "Hodowla świnek morskich - zamów świnkowe maluszki" , w bloku głównym h2: "Świnki w tym miocie" , w bloku prawym h3: "Poznaj wszystkie rasy świnek morskich" oraz w stopce paragraf z numerem zdającego

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: Paragraf (akapit) o treści: „Stronę wykonał: ”, dalej wstawiony numer zdającego

    Akapit w <footer>. Na egzaminie po dwukropku wpisujesz swój numer zdającego (PESEL), tu stoi autor rozwiązania. Z nagłówkami h1, h2, h3 to R.2.5.

    peruwianka.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>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  19. Etap 3: Styl CSS

    Kroki 19-27 · po tym etapie masz 28 z 40 kryteriów (pkt)

    Krok 19: Plik styl.css: zmienne i krój Helvetica

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (dla *): krój czcionki Helvetica

    ok. 2 min
    Polecenie z arkusza

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

    Dwa kolory z arkusza w zmiennych: SaddleBrown (baner, stopka) i Peru (menu, blok prawy). Selektor * z Helvetiką i krojami zapasowymi: Helvetica jest standardem na komputerach Apple, na Windowsie zwykle jej nie ma - wtedy przeglądarka weźmie podobny Arial, a w ostateczności dowolny krój bezszeryfowy (R.4.1).

    styl.css CSS nowy plik
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  20. Krok 20: Układ bloków na siatce

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu (prawidłowo zastosowano właściwości CSS decydujące o układzie strony, np. float i clear albo display flex albo grid)

    ok. 3 min
    Polecenie z arkusza

    Podział strony na bloki: baner, dwa bloki lewe: blok menu i blok główny, jeden blok prawy, na dole blok stopki. Podział zrealizowany wyłącznie 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 obrazem 2

    grid-template-areas rysuje obraz 2 słowami: baner na całą szerokość, w lewej kolumnie menu i pod nim blok główny, w prawej - blok prawy przez oba wiersze, na dole stopka. grid-template-columns: 80% 20% to od razu szerokości z arkusza (klucz R.4.5 przyjmuje je w tej postaci). align-items: start - bloki mają wysokości z arkusza, zamiast rozciągać się do wiersza.

    Każdy blok dostaje nazwę pola (grid-area). Bez float nie ma clear - stopka ma swój wiersz (R.3.1).

    styl.css CSS zmienione: 31 linii
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
    }
    
    main {
        grid-area: main;
    }
    
    aside {
        grid-area: aside;
    }
    
    footer {
        grid-area: footer;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  21. Krok 21: Baner i stopka

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla banera i stopki: kolor tła SaddleBrown, biały kolor czcionki, wyrównanie tekstu do środka, marginesy wewnętrzne 7 px

    Jedna reguła dla dwóch selektorów, kolor ze zmiennej.

    styl.css CSS zmienione: 7 linii
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
    }
    
    main {
        grid-area: main;
    }
    
    aside {
        grid-area: aside;
    }
    
    footer {
        grid-area: footer;
    }
    
    header, footer {
        background-color: var(--brown);
        color: white;
        text-align: center;
        padding: 7px;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  22. Krok 22: Blok menu

    ok. 1 min
    Polecenie z arkusza

    Dla lewego bloku menu: kolor tła Peru, szerokość 80%, wysokość 40 px, margines wewnętrzny górny 20 px

    Szerokość 80% daje kolumna. Blok menu ma 40 px wysokości i 20 px marginesu u góry, razem 60 px - z 700 px bloku głównego to dokładnie 760 px bloku prawego.

    Typowe błędy

    width: 80% dopisane do menu w kolumnie 80% daje blok szeroki na 64% strony - procent szerokości elementu siatki liczy się od jego kolumny.

    styl.css CSS zmienione: 3 linie
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
        background-color: var(--peru);
        height: 40px;
        padding-top: 20px;
    }
    
    main {
        grid-area: main;
    }
    
    aside {
        grid-area: aside;
    }
    
    footer {
        grid-area: footer;
    }
    
    header, footer {
        background-color: var(--brown);
        color: white;
        text-align: center;
        padding: 7px;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  23. Krok 23: Blok główny z paskiem przewijania

    Kryteria:

    R.4.8 Ustawiono paski przewijania dla bloku głównego (overflow:auto lub scroll)

    ok. 1 min
    Polecenie z arkusza

    Dla lewego bloku głównego: szerokość 80%, wysokość 700 px, rozmiar czcionki 120%, paski przewijania pojawiające się tylko, gdy tekst nie mieści się w oknie

    overflow: auto - pasek przewijania tylko wtedy, gdy treść jest wyższa niż 700 px (R.4.8).

    styl.css CSS zmienione: 3 linie
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
        background-color: var(--peru);
        height: 40px;
        padding-top: 20px;
    }
    
    main {
        grid-area: main;
        height: 700px;
        font-size: 120%;
        overflow: auto;
    }
    
    aside {
        grid-area: aside;
    }
    
    footer {
        grid-area: footer;
    }
    
    header, footer {
        background-color: var(--brown);
        color: white;
        text-align: center;
        padding: 7px;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  24. Krok 24: Blok prawy

    Kryteria: , ,

    R.4.2 Ustawiono kolor tła SaddleBrown dla banera i stopki oraz Peru dla bloku menu i bloku prawego

    R.4.4 Ustawiono wysokość bloku menu 40px, bloku głównego 700px oraz 760px dla bloku prawego

    R.4.5 Ustawiono szerokość 80% dla bloku głównego i menu oraz 20% dla bloku prawego (width lub grid-template-columns lub flex)

    ok. 1 min
    Polecenie z arkusza

    Dla bloku prawego: kolor tła Peru, biały kolor czcionki, szerokość 20%, wysokość 760 px

    Szerokość 20% daje druga kolumna. Ta reguła domyka kolory tła (R.4.2), wysokości (R.4.4) i szerokości bloków (R.4.5: kolumny 80% 20%).

    styl.css CSS zmienione: 3 linie
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
        background-color: var(--peru);
        height: 40px;
        padding-top: 20px;
    }
    
    main {
        grid-area: main;
        height: 700px;
        font-size: 120%;
        overflow: auto;
    }
    
    aside {
        grid-area: aside;
        background-color: var(--peru);
        color: white;
        height: 760px;
    }
    
    footer {
        grid-area: footer;
    }
    
    header, footer {
        background-color: var(--brown);
        color: white;
        text-align: center;
        padding: 7px;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  25. Krok 25: Odnośniki

    Kryteria: ,

    R.4.3 Ustawiono biały kolor czcionki dla banera, stopki i bloku prawego oraz #DDD dla selektora odnośnika

    R.4.6 Ustawiono cechy tekstu: wyrównanie do środka dla banera i stopki, rozmiar 120% dla bloku głównego i 140% dla odnośnika oraz brak podkreślenia dla odnośnika (text- decoration:none)

    ok. 2 min
    Polecenie z arkusza

    Dla selektora odnośnika: kolor czcionki #DDD, margines wewnętrzny lewy 90 px, rozmiar czcionki 140%, brak podkreślenia

    Selektor znacznika a - uwaga w arkuszu i w kluczu: wyłącznie selektor znacznika, nie nav a ani klasa (tu projekt arkusza ma pierwszeństwo przed wygodą). Biel bloków i #DDD odnośników to R.4.3, cechy tekstu - R.4.6.

    Typowe błędy

    Reguła nav a albo klasa odnośnika nie spełnia R.4.3 ani R.4.7 - klucz wymaga samego selektora a.

    styl.css CSS zmienione: 7 linii
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
        background-color: var(--peru);
        height: 40px;
        padding-top: 20px;
    }
    
    main {
        grid-area: main;
        height: 700px;
        font-size: 120%;
        overflow: auto;
    }
    
    aside {
        grid-area: aside;
        background-color: var(--peru);
        color: white;
        height: 760px;
    }
    
    footer {
        grid-area: footer;
    }
    
    header, footer {
        background-color: var(--brown);
        color: white;
        text-align: center;
        padding: 7px;
    }
    
    a {
        color: #DDD;
        padding-left: 90px;
        font-size: 140%;
        text-decoration: none;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  26. Krok 26: Kursor na odnośniku

    Kryteria:

    R.4.10 W momencie gdy kursor znajdzie się na odnośniku, jego kolor czcionki zmienia się na biały

    ok. 1 min
    Polecenie z arkusza

    W momencie gdy kursor znajdzie się na odnośniku, jego kolor czcionki zmienia się na biały

    :hover (R.4.10) i :focus-visible - ten sam biały dla odnośnika wybranego klawiszem Tab.

    styl.css CSS zmienione: 5 linii
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
        background-color: var(--peru);
        height: 40px;
        padding-top: 20px;
    }
    
    main {
        grid-area: main;
        height: 700px;
        font-size: 120%;
        overflow: auto;
    }
    
    aside {
        grid-area: aside;
        background-color: var(--peru);
        color: white;
        height: 760px;
    }
    
    footer {
        grid-area: footer;
    }
    
    header, footer {
        background-color: var(--brown);
        color: white;
        text-align: center;
        padding: 7px;
    }
    
    a {
        color: #DDD;
        padding-left: 90px;
        font-size: 140%;
        text-decoration: none;
    }
    
    a:hover,
    a:focus-visible {
        color: white;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  27. Krok 27: Obraz opływany tekstem

    Kryteria: ,

    R.4.7 Ustawiono marginesy wewnętrzne (padding) dla banera i stopki 7px, górny dla bloku menu 20px, lewy dla odnośnika 90px oraz marginesy zewnętrzne (margin) dla selektora img 30px

    R.4.9 Ustawiono dla obrazu opływanie tekstem po prawej stronie (np. float: left;)

    ok. 1 min
    Polecenie z arkusza

    Dla selektora obrazu: opływanie tekstem po prawej stronie (obraz znajduje się po lewej stronie), marginesy zewnętrzne 30 px

    Tu float zostaje, bo robi to, do czego powstał: opływanie obrazu tekstem - arkusz mówi o tym wprost, a klucz R.4.9 podaje float: left. Siatka układa bloki strony, float - obraz w tekście. Selektor znacznika img, jak każe uwaga arkusza (R.4.7, R.4.9).

    styl.css CSS zmienione: 5 linii
    :root {
        --brown: SaddleBrown;
        --peru: Peru;
    }
    
    * {
        font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
        display: grid;
        grid-template-columns: 80% 20%;
        grid-template-areas:
            "header header"
            "nav    aside"
            "main   aside"
            "footer footer";
        align-items: start;
    }
    
    header {
        grid-area: header;
    }
    
    nav {
        grid-area: nav;
        background-color: var(--peru);
        height: 40px;
        padding-top: 20px;
    }
    
    main {
        grid-area: main;
        height: 700px;
        font-size: 120%;
        overflow: auto;
    }
    
    aside {
        grid-area: aside;
        background-color: var(--peru);
        color: white;
        height: 760px;
    }
    
    footer {
        grid-area: footer;
    }
    
    header, footer {
        background-color: var(--brown);
        color: white;
        text-align: center;
        padding: 7px;
    }
    
    a {
        color: #DDD;
        padding-left: 90px;
        font-size: 140%;
        text-decoration: none;
    }
    
    a:hover,
    a:focus-visible {
        color: white;
    }
    
    img {
        float: left;
        margin: 30px;
    }
    Podgląd strony po tym kroku (peruwianka.php)
  28. Etap 4: Skrypty PHP

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

    Krok 28: Połączenie z bazą na górze pliku i zamknięcie

    Kryteria: ,

    R.5.1 Skrypt zawiera instrukcje połączenia z serwerem bazy danych i wyboru bazy hodowla

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

    ok. 4 min
    Polecenie z arkusza

    Skrypty łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie hodowla

    Wszystkie dane strona pobierze przed HTML-em, w jednym bloku PHP na samej górze pliku. W HTML-u zostanie potem tylko wypisywanie - kod rozmawiający z bazą jest w jednym miejscu, a połączenie da się zamknąć, zanim przeglądarka dostanie pierwszy znacznik.

    • $breedId - identyfikator rasy w jednej zmiennej; kopie strony zmienią tylko tę linię,
    • new PDO(...) - połączenie z serwerem localhost, bazą hodowla i kodowaniem utf8mb4, użytkownik root bez hasła (R.5.1). ERRMODE_EXCEPTION - każdy błąd bazy rzuca wyjątek, zamiast zwracać false, którego łatwo nie zauważyć; FETCH_ASSOC - wiersze jako tablice z nazwami kolumn,
    • $pdo = null - PDO nie ma funkcji „zamknij”: połączenie zamyka się, gdy znika ostatnie odwołanie do obiektu. Stoi na końcu bloku, więc jest ostatnią operacją na bazie (R.5.2),
    • try / catch (PDOException ...) - gdy baza nie działa, strona nie pokaże uczniowi komunikatu PHP ze szczegółami serwera, tylko zwykłe zdanie.

    PDO zamiast mysqli - klucz przyjmuje obie biblioteki (uwaga przy R.5). Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    peruwianka.php PHP zmienione: 14 linii
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  29. Krok 29: Skrypt 1: zapytanie 4

    Kryteria:

    R.5.3 Skrypt 1 zawiera instrukcje wysyłające do bazy danych zapytanie 4 lub skrypt 2: zapytanie 2 lub skrypt 3: zapytanie 3

    ok. 2 min
    Polecenie z arkusza

    Skrypt 1: Wysyła do bazy danych zapytanie 4

    Zapytanie bez danych od użytkownika, więc wystarczy query. fetchAll(PDO::FETCH_COLUMN) zwraca od razu prostą listę wartości pierwszej kolumny: ["peruwianka", "angora", ...] - bez tablic w tablicy. W catch lista dostaje wartość pustą, żeby HTML niżej nie trafił na niezdefiniowaną zmienną (R.5.3). Na stronie jeszcze nic nie widać.

    peruwianka.php PHP zmienione: 4 linie
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  30. Krok 30: Skrypt 1: rasy jako elementy listy

    Kryteria: ,

    R.5.4 Skrypt 1 wyświetla w bloku prawym zwrócone zapytaniem rasy świnek morskich

    R.5.9 Skrypt 1 lub 3 zapisano w oparciu o pętlę o liczbie iteracji równej liczbie zwróconych wierszy

    ok. 3 min
    Polecenie z arkusza

    Zwrócone zapytaniem rasy świnek morskich wypisuje jako elementy listy

    • foreach wykonuje się tyle razy, ile ras zwróciło zapytanie - 13 (R.5.9). Zapis z dwukropkiem i endforeach jest czytelniejszy w HTML-u niż klamry rozrzucone między znacznikami,
    • <?= ... ?> to skrót od <?php echo ... ?>,
    • funkcja e() (na górze pliku) przepuszcza każdy tekst z bazy przez htmlspecialchars - znak < albo cudzysłów w danych nie rozbije strony ani nie wstrzyknie do niej kodu. Przy okazji trim usuwa spację z początku rasy „ somali” zapisanej tak w bazie.

    Lista w bloku prawym: 1. peruwianka ... 13. skinny (R.5.4).

    peruwianka.php PHP zmienione: 8 linii
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  31. Krok 31: Skrypt 2: zapytanie 2

    ok. 3 min
    Polecenie z arkusza

    Skrypt 2: Wysyła do bazy danych zapytanie 2

    Zapytanie przygotowane: w miejscu identyfikatora stoi parametr :breed, a wartość podaje execute(["breed" => $breedId]). Baza dostaje treść zapytania i dane osobno, więc dana nigdy nie stanie się częścią kodu SQL - nawet gdyby identyfikator przyszedł kiedyś z adresu strony. Dzięki DISTINCT wynikiem jest jeden wiersz: wystarczy fetch() bez pętli (zwraca false, gdy wiersza nie ma).

    peruwianka.php PHP zmienione: 7 linii
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  32. Krok 32: Skrypt 2: nagłówek z rasą

    Kryteria:

    R.5.5 Skrypt 2 wyświetla w bloku głównym zwróconą zapytaniem rasę świnki morskiej

    ok. 2 min
    Polecenie z arkusza

    Wyświetla dane pobrane z bazy danych, w następujący sposób: W nagłówku drugiego stopnia treść „Rasa: <rasa>”

    Pola po nazwach kolumn ($litter["rasa"]), nie po numerach - kolejność pól w SELECT może się zmienić, a kod dalej działa. if ($litter) - nagłówek tylko wtedy, gdy miot istnieje. Obok zdjęcia: „Rasa: peruwianka” (R.5.5).

    peruwianka.php PHP zmienione: 3 linie
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  33. Krok 33: Skrypt 2: data urodzenia i miot

    Kryteria:

    R.5.6 Skrypt 2 wyświetla zwróconą zapytaniem datę urodzenia i miot

    ok. 1 min
    Polecenie z arkusza

    W paragrafie treść „Data urodzenia: <data-ur>”. W paragrafie treść „Oznaczenie miotu: <miot>”, gdzie dane zapisane w nawiasach <> wybrane zostały z bazy danych

    Dwa akapity z tego samego wiersza: 2022-06-02 (format RRRR-MM-DD, jak na obrazie 2) i I5 (R.5.6).

    peruwianka.php PHP zmienione: 2 linie
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
            <p>Data urodzenia: <?= e($litter['data_ur']) ?></p>
            <p>Oznaczenie miotu: <?= e($litter['miot']) ?></p>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  34. Krok 34: Skrypt 3: zapytanie 3

    ok. 3 min
    Polecenie z arkusza

    Skrypt 3: Wysyła do bazy danych zapytanie 3

    Drugie zapytanie przygotowane z tym samym parametrem :breed - ta sama zmienna $breedId steruje oboma zapytaniami, więc nie da się poprawić jednego i zapomnieć o drugim. fetchAll() - wszystkie wiersze naraz. Przed zamknięciem połączenia $statement = null zwalnia ostatnie zapytanie: połączenie PDO zamyka się dopiero wtedy, gdy nie odwołuje się do niego już żaden obiekt.

    peruwianka.php PHP zmienione: 7 linii
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        // Skrypt 3: zapytanie 3 - świnki z miotu
        $statement = $pdo->prepare('SELECT imie, cena, opis FROM swinki WHERE rasy_id = :breed');
        $statement->execute(['breed' => $breedId]);
        $pigs = $statement->fetchAll();
    
        $statement = null;
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $pigs = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
            <p>Data urodzenia: <?= e($litter['data_ur']) ?></p>
            <p>Oznaczenie miotu: <?= e($litter['miot']) ?></p>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  35. Krok 35: Skrypt 3: imię i cena każdej świnki

    Kryteria:

    R.5.7 Skrypt 3 wyświetla w bloku głównym zwrócone z bazy imię i cenę

    ok. 2 min
    Polecenie z arkusza

    Wyświetla dane pobrane z bazy danych, w następujący sposób: W nagłówku trzeciego stopnia treść „<imie> - <cena> zł”

    Pętla foreach po świnkach: „Cindy - 200 zł”, „Wendy - 200 zł”, „Mała - 250 zł”, „Lola - 200 zł” (R.5.7). Cena przechodzi przez e() jak każda dana z bazy - funkcja przyjmuje też liczbę.

    peruwianka.php PHP zmienione: 3 linie
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        // Skrypt 3: zapytanie 3 - świnki z miotu
        $statement = $pdo->prepare('SELECT imie, cena, opis FROM swinki WHERE rasy_id = :breed');
        $statement->execute(['breed' => $breedId]);
        $pigs = $statement->fetchAll();
    
        $statement = null;
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $pigs = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
            <p>Data urodzenia: <?= e($litter['data_ur']) ?></p>
            <p>Oznaczenie miotu: <?= e($litter['miot']) ?></p>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
    <?php foreach ($pigs as $pig): ?>
            <h3><?= e($pig['imie']) ?> - <?= e($pig['cena']) ?> zł</h3>
    <?php endforeach; ?>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  36. Krok 36: Skrypt 3: opis w akapicie

    Kryteria: ,

    R.5.8 Skrypt 3 wyświetla zwrócony zapytaniem opis

    R.5.10 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych lub funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania

    ok. 2 min
    Polecenie z arkusza

    W paragrafie zwrócony zapytaniem opis. Na końcu jest zamykane połączenie z serwerem.

    Opis pod nagłówkiem; pierwszy układa się obok zdjęcia, dalsze na całej szerokości, a blok główny dostaje pasek przewijania (obraz 2). Połączenie jest już zamknięte - na górze pliku, po ostatnim zapytaniu. Nazwy mówią, co przechowują: $breedId, $breeds, $litter, $pigs, $statement, e() (R.5.8, R.5.10).

    peruwianka.php PHP zmienione: 1 linia
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        // Skrypt 3: zapytanie 3 - świnki z miotu
        $statement = $pdo->prepare('SELECT imie, cena, opis FROM swinki WHERE rasy_id = :breed');
        $statement->execute(['breed' => $breedId]);
        $pigs = $statement->fetchAll();
    
        $statement = null;
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $pigs = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
            <p>Data urodzenia: <?= e($litter['data_ur']) ?></p>
            <p>Oznaczenie miotu: <?= e($litter['miot']) ?></p>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
    <?php foreach ($pigs as $pig): ?>
            <h3><?= e($pig['imie']) ?> - <?= e($pig['cena']) ?> zł</h3>
            <p><?= e($pig['opis']) ?></p>
    <?php endforeach; ?>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (peruwianka.php)
  37. Krok 37: Rasa bez świnek i awaria bazy: komunikaty

    ok. 3 min

    Dodatek spoza arkusza - klucz go nie ocenia. Strona ma teraz odpowiedź na trzy sytuacje, których dane z arkusza nie pokazują:

    • rasa bez miotu (fetch() zwrócił false) - zamiast pustego „Rasa: ” nagłówek „Brak miotu tej rasy” (else przy if),
    • brak świnek (pusta tablica $pigs) - akapit „W tej chwili nie ma świnek tej rasy na sprzedaż.”,
    • awaria bazy (catch) - komunikat z role="alert" (czytnik ekranu przeczyta go od razu), a reszta strony - menu, nagłówki, stopka - działa dalej, bo zmienne mają w catch wartości puste.

    Sprawdzone na prawdziwym PHP: rasa 2 (szetlandzka, w tabeli swinki nie ma żadnej) daje oba komunikaty, a złe hasło do bazy - komunikat bez treści błędu serwera. Przy rasach 1, 6 i 7 strona wygląda tak jak wcześniej.

    peruwianka.php PHP zmienione: 8 linii
    <?php
    $breedId = 1;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        // Skrypt 3: zapytanie 3 - świnki z miotu
        $statement = $pdo->prepare('SELECT imie, cena, opis FROM swinki WHERE rasy_id = :breed');
        $statement->execute(['breed' => $breedId]);
        $pigs = $statement->fetchAll();
    
        $statement = null;
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $pigs = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php" aria-current="page">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
    <?php if (isset($databaseError)): ?>
            <p role="alert"><?= e($databaseError) ?></p>
    <?php endif; ?>
            <img src="peruwianka.jpg" alt="Świnka morska rasy peruwianka">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
            <p>Data urodzenia: <?= e($litter['data_ur']) ?></p>
            <p>Oznaczenie miotu: <?= e($litter['miot']) ?></p>
    <?php else: ?>
            <h2>Brak miotu tej rasy</h2>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
    <?php if (!$pigs): ?>
            <p>W tej chwili nie ma świnek tej rasy na sprzedaż.</p>
    <?php endif; ?>
    <?php foreach ($pigs as $pig): ?>
            <h3><?= e($pig['imie']) ?> - <?= e($pig['cena']) ?> zł</h3>
            <p><?= e($pig['opis']) ?></p>
    <?php endforeach; ?>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  38. Etap 5: Strony american.php i crested.php

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

    Krok 38: Kopia american.php

    Kryteria:

    R.3.4 Na stronie american.php jest widoczny obraz american.jpg z tekstem alternatywnym „Świnka morska rasy american” oraz wyświetlają się informacje dotyczące rasy american

    ok. 2 min
    Polecenie z arkusza

    Należy skopiować dwukrotnie dokument peruwianka.php i zmienić nazwy na american.php i crested.php. Zmiany, których należy dokonać w bloku głównym dokumentu american.php (obraz 4): Obraz: źródło american.jpg, tekst alternatywny „Świnka morska rasy american”. Skrypt 2: w zapytaniu 2 należy zmienić warunek zapytania, id rasy jest równe 6. Skrypt 3: w zapytaniu 3 należy zmienić warunek zapytania, id rasy jest równe 6

    Kopia gotowej strony jako american.php. Warunki obu zapytań zmienia jedna linia: $breedId = 6; - wartość parametru :breed w zapytaniach 2 i 3. Do tego plik obrazu, tekst alternatywny i aria-current przy „Rasa American”. Podgląd (prawdziwe uruchomienie): rasa american, miot H4, świnki Crejzy, Biała i Lucy - jak na obrazie 4 (R.3.4).

    american.php PHP nowy plik
    <?php
    $breedId = 6;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        // Skrypt 3: zapytanie 3 - świnki z miotu
        $statement = $pdo->prepare('SELECT imie, cena, opis FROM swinki WHERE rasy_id = :breed');
        $statement->execute(['breed' => $breedId]);
        $pigs = $statement->fetchAll();
    
        $statement = null;
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $pigs = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php">Rasa Peruwianka</a>
            <a href="american.php" aria-current="page">Rasa American</a>
            <a href="crested.php">Rasa Crested</a>
        </nav>
        <main>
    <?php if (isset($databaseError)): ?>
            <p role="alert"><?= e($databaseError) ?></p>
    <?php endif; ?>
            <img src="american.jpg" alt="Świnka morska rasy american">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
            <p>Data urodzenia: <?= e($litter['data_ur']) ?></p>
            <p>Oznaczenie miotu: <?= e($litter['miot']) ?></p>
    <?php else: ?>
            <h2>Brak miotu tej rasy</h2>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
    <?php if (!$pigs): ?>
            <p>W tej chwili nie ma świnek tej rasy na sprzedaż.</p>
    <?php endif; ?>
    <?php foreach ($pigs as $pig): ?>
            <h3><?= e($pig['imie']) ?> - <?= e($pig['cena']) ?> zł</h3>
            <p><?= e($pig['opis']) ?></p>
    <?php endforeach; ?>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (american.php)
  39. Krok 39: Kopia crested.php

    Kryteria:

    R.3.5 Na stronie crested.php jest widoczny obraz crested.jpg z tekstem alternatywnym „Świnka morska rasy crested” oraz wyświetlają się informacje dotyczące rasy crested

    ok. 2 min
    Polecenie z arkusza

    Zmiany, których należy dokonać w bloku głównym dokumentu crested.php (obraz 5): Obraz: źródło crested.jpg, tekst alternatywny „Świnka morska rasy crested”. Skrypt 2: w zapytaniu 2 należy zmienić warunek zapytania, id rasy jest równe 7. Skrypt 3: w zapytaniu 3 należy zmienić warunek zapytania, id rasy jest równe 7

    Druga kopia, crested.php: $breedId = 7;, wykadrowane zdjęcie crested.jpg z tekstem alternatywnym i aria-current przy „Rasa Crested”. Podgląd: miot G3 z 30 czerwca, Bąbelek i Lulu po 150 zł - jak na obrazie 5 (R.3.5).

    crested.php PHP nowy plik
    <?php
    $breedId = 7;    // jedyna linia, którą różnią się kopie: american.php - 6, crested.php - 7
    
    function e(?string $text): string
    {
        return htmlspecialchars(trim($text ?? ''), ENT_QUOTES);
    }
    
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=hodowla;charset=utf8mb4', 'root', '', [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    
        // Skrypt 1: zapytanie 4 - wszystkie rasy
        $breeds = $pdo->query('SELECT rasa FROM rasy ORDER BY id')->fetchAll(PDO::FETCH_COLUMN);
    
        // Skrypt 2: zapytanie 2 - dane miotu wybranej rasy
        $statement = $pdo->prepare('SELECT DISTINCT s.data_ur, s.miot, r.rasa FROM swinki AS s
            JOIN rasy AS r ON r.id = s.rasy_id WHERE r.id = :breed');
        $statement->execute(['breed' => $breedId]);
        $litter = $statement->fetch();
    
        // Skrypt 3: zapytanie 3 - świnki z miotu
        $statement = $pdo->prepare('SELECT imie, cena, opis FROM swinki WHERE rasy_id = :breed');
        $statement->execute(['breed' => $breedId]);
        $pigs = $statement->fetchAll();
    
        $statement = null;
        $pdo = null;    // zamknięcie połączenia - ostatnia operacja na bazie
    } catch (PDOException $exception) {
        $breeds = [];
        $litter = false;
        $pigs = [];
        $databaseError = 'Nie udało się pobrać danych z bazy. Spróbuj odświeżyć stronę za chwilę.';
    }
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hodowla świnek morskich</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Hodowla świnek morskich - zamów świnkowe maluszki</h1>
        </header>
        <nav>
            <a href="peruwianka.php">Rasa Peruwianka</a>
            <a href="american.php">Rasa American</a>
            <a href="crested.php" aria-current="page">Rasa Crested</a>
        </nav>
        <main>
    <?php if (isset($databaseError)): ?>
            <p role="alert"><?= e($databaseError) ?></p>
    <?php endif; ?>
            <img src="crested.jpg" alt="Świnka morska rasy crested">
    <?php if ($litter): ?>
            <h2>Rasa: <?= e($litter['rasa']) ?></h2>
            <p>Data urodzenia: <?= e($litter['data_ur']) ?></p>
            <p>Oznaczenie miotu: <?= e($litter['miot']) ?></p>
    <?php else: ?>
            <h2>Brak miotu tej rasy</h2>
    <?php endif; ?>
            <hr>
            <h2>Świnki w tym miocie</h2>
    <?php if (!$pigs): ?>
            <p>W tej chwili nie ma świnek tej rasy na sprzedaż.</p>
    <?php endif; ?>
    <?php foreach ($pigs as $pig): ?>
            <h3><?= e($pig['imie']) ?> - <?= e($pig['cena']) ?> zł</h3>
            <p><?= e($pig['opis']) ?></p>
    <?php endforeach; ?>
        </main>
        <aside>
            <h3>Poznaj wszystkie rasy świnek morskich</h3>
            <ol>
    <?php foreach ($breeds as $breed): ?>
                <li><?= e($breed) ?></li>
    <?php endforeach; ?>
            </ol>
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (crested.php)
  40. Etap 6: Porównanie z wersją podstawową

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

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

    ok. 3 min

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

    wersja podstawowawersja nowoczesna
    układfloat bloków, <aside> w kodzie przed menu, clear stopkigrid-template-areas, kolejność treści w HTML-u
    bibliotekamysqli (funkcje z tabeli 1 arkusza)PDO z wyjątkami
    gdzie są zapytaniaw trzech skryptach rozrzuconych po HTML-ujeden blok na górze pliku, w HTML-u tylko pętle
    identyfikator rasywpisany w dwa zapytaniaparametr :breed ze zmiennej $breedId
    odczyt wierszamysqli_fetch_row i $row[2]FETCH_ASSOC i $litter["rasa"]
    wypisywaniedane z bazy wproste() - htmlspecialchars i trim
    zamknięciemysqli_close na końcu Skryptu 3$statement = null; $pdo = null; po ostatnim zapytaniu
    brak danych, awaria bazyostrzeżenia PHP, puste nagłówkikomunikaty

    Trzy prawie jednakowe pliki to w prawdziwym projekcie sygnał do wydzielenia wspólnej części do osobnego pliku (require) - tu arkusz każe kopiować całą stronę, a klucz sprawdza skrypty w plikach stron, więc obie wersje zostają przy kopiach.

    Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 arkusza i łatwiej ją napisać bez dokumentacji pod ręką. Nowoczesna jest bezpieczniejsza i trudniej w niej o pomyłkę przy kopiach - zmienia się jedna linia. Obie biblioteki klucz przyjmuje.

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

  41. Etap 7: Oddanie pracy

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

    Krok 41: 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 weryfikowana była poprawność działania witryny. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt nazwa przeglądarki, w której sprawdzana była strona. W folderze z numerem zdającego: american.jpg, american.php, crested.jpg, crested.php, import.png, kw1.jpg - kw4.jpg, kwerendy.txt, peruwianka.jpg, peruwianka.php, przeglądarka.txt, styl.css. 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.