Przejdź do głównej treści
INF.03-10-26.01-SGStyczeń 2026 · 48 kroków · ok. 83 min · 38 kryteriów z klucza

Rozwiązanie krok po kroku: Blog kulinarny z bazą danych (Wersja podstawowa)

Rozwiązanie buduje blog kulinarny: baza przepisy (potrawy, rodzaje potraw, alergeny i tabela pośrednicząca lista_alergenow) i cztery zapytania o jedną potrawę - proste, ze złączeniem n:1, ze złączeniem n:m przez trzy tabele i z polem tekstowym przepisu - potem separator wycięty z większej grafiki, strona przepisy.php z blokiem bocznym, głównym i sekcją, style w styl.css (półprzezroczyste tło nagłówka rgba, kapitaliki, tło dopasowane background-size: cover) oraz cztery skrypty PHP działające na identyfikatorze potrawy z adresu (domyślnie 7): rodzaj potrawy, nazwa z trudnością zamienioną na słowo, alergeny i przepis - a nazwa pliku z bazy trafia do stylu inline tła sekcji.

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, funkcjami z tabeli 1 arkusza (mysqli_query, mysqli_fetch_row, isset), a na końcu zostają przerobione na wersję z prawdziwych projektów: liczba zamiast surowego tekstu z adresu, kontrola istnienia potrawy, tablica zamiast drabinki if, alergeny po przecinku i htmlspecialchars.

Baza i zdjęcia pochodzą z prawdziwego archiwum pliki14 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 na bazie z arkusza - stan początkowy, czyli jagnięcina, jak na ilustracji 2.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: układ na siatce CSS, kolory w zmiennych, odnośniki potraw z tablicy PHP, a baza przez PDO z danymi pobranymi przed HTML-em, walidacją identyfikatora, zapytaniami przygotowanymi i htmlspecialchars od pierwszej linii - obie wersje są zgodne z kluczem.

Jak liczą się punkty. Klucz ma 38 kryteriów (R.1.1 - R.5.10), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 29 punktów - można stracić 9 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 38 kryteriów (pkt)

    Krok 1: Baza danych przepisy

    ok. 2 min
    Polecenie z arkusza

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

    Rozpakuj pliki14.7z z pulpitu (hasło BLog+#KuLinarnY@ - wielkie i małe litery na przemian, ze znakami +, # i @) i załóż folder z numerem zdającego. W archiwum są przepisy.sql, lista.txt, separator.png i dziesięć zdjęć potraw. W phpMyAdmin: Nowa, nazwa przepisy, porównywanie utf8_polish_ci.

    Typowe błędy

    Nazwa bazy musi brzmieć dokładnie przepisy - skrypty łączą się z bazą po nazwie, więc literówka zabiera też punkty za skrypty (R.5.1).

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

    ok. 2 min
    Polecenie z arkusza

    Z rozpakowanego archiwum zaimportuj tabele z pliku przepisy.sql do utworzonej bazy

    Zaznacz bazę przepisy, potem Import → przepisy.sql → Wykonaj. Powstają cztery tabele z ilustracji 1: potrawy (z kluczem obcym idRodzaje), rodzaje, alergeny i lista_alergenow, która łączy potrawy z alergenami - jedna potrawa ma wiele alergenów, jeden alergen występuje w wielu potrawach (relacja n:m).

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonany import tabel do bazy danych przepisy - obraz import.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, wklejasz do edytora grafiki i zapisujesz jako import.png. Import idzie do PNG, a zrzuty zapytań do JPEG - formaty są różne.

    Typowe błędy

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

  4. Krok 4: Zapytanie 1: nazwa, trudność i kalorie potrawy 7

    Kryteria: ,

    R.1.2 W pliku kwerendy.txt zapisane co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Wykonane zapytanie 1 wybierające jedynie nazwę, trudność i kalorie potrawy o identyfikatorze równym 7. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = 7; oraz na zrzucie widoczne są dane: Jagnięcina, 3, 225

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie nazwę, trudność i kalorie potrawy o identyfikatorze równym 7

    Trzy pola z tabeli potrawy, warunek na kluczu głównym idPotrawy. Wynik: jeden wiersz - Jagnięcina, trudność 3, 225 kalorii. Trudność jest liczbą; na stronie zamienisz ją na słowo. Zapytanie zapisujesz w kwerendy.txt, zrzut jako kw1.jpg (cały ekran z paskiem zadań).

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = 7;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: rodzaj potrawy 7

    Kryteria:

    R.1.4 Wykonane zapytanie 2 wybierające jedynie nazwę potrawy i odpowiadające jej pole rodzaj z tabeli rodzaje dla potrawy o identyfikatorze równym 7. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, rodzaj FROM potrawy JOIN rodzaje USING(idRodzaje) WHERE idPotrawy = 7; (lub porównanie kluczy po ON lub WHERE ) oraz na zrzucie widoczne są dane: Jagnięcina, dania mięsne

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie nazwę potrawy i odpowiadające jej pole rodzaj z tabeli rodzaje dla potrawy o identyfikatorze równym 7. Należy posłużyć się relacją

    • SELECT potrawy.nazwa, rodzaje.rodzaj - nazwa potrawy i nazwa jej rodzaju,
    • FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje - relacja n:1: wiele potraw tego samego rodzaju,
    • WHERE potrawy.idPotrawy = 7 - jagnięcina.

    Wynik: Jagnięcina, dania mięsne. Klucz podaje też krótszy zapis JOIN rodzaje USING(idRodzaje) - działa, gdy kolumna łącząca ma w obu tabelach tę samą nazwę. Zrzut: kw2.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = 7;
    
    -- Zapytanie 2
    SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = 7;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: alergeny potrawy 7 przez relację n:m

    Kryteria:

    R.1.5 Wykonane zapytanie 3 wybierające jedynie nazwę potrawy i odpowiadające jej nazwy alergenów dla potrawy o identyfikatorze równym 7. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, alergen FROM potrawy JOIN lista_alergenow USING(idPotrawy) JOIN alergeny USING(idAlergeny) WHERE idPotrawy=7; (lub porównanie kluczy po ON lub WHERE ) oraz na zrzucie widoczne są dane: Jagnięcina, seler

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie nazwę potrawy i odpowiadające jej nazwy alergenów dla potrawy o identyfikatorze równym 7. Zapytanie wykorzystuje relację n:m pomiędzy trzema tabelami

    • SELECT potrawy.nazwa, alergeny.alergen - nazwa potrawy i alergenu,
    • FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy - od potrawy do tabeli pośredniczącej,
    • JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny - od tabeli pośredniczącej do alergenu,
    • WHERE potrawy.idPotrawy = 7.

    Dwa złączenia, trzy tabele. Jagnięcina ma jeden alergen: seler. Inne potrawy mają ich więcej (kociołek: gluten, laktoza, orzechy) - zapytanie zwraca wtedy tyle wierszy, ile alergenów. Zrzut: kw3.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = 7;
    
    -- Zapytanie 2
    SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = 7;
    
    -- Zapytanie 3
    SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = 7;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: przepis i plik zdjęcia

    Kryteria:

    R.1.6 Wykonane zapytanie 4 wybierające jedynie pola przepis i plik dla potrawy o identyfikatorze równym 7. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT przepis, plik FROM potrawy WHERE idPotrawy = 7; oraz na zrzucie widoczne są dane: "Mięso oczyść ...." i jagniecina.jpg

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 4: wybierające jedynie pola przepis i plik dla potrawy o identyfikatorze równym 7

    Dwa pola z tabeli potrawy: długi tekst przepisu (zaczyna się od „Mięso oczyść z błon”) i nazwa pliku jagniecina.jpg. phpMyAdmin skraca długi tekst w podglądzie - na stronie pokażesz go w całości. Zrzut: kw4.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = 7;
    
    -- Zapytanie 2
    SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = 7;
    
    -- Zapytanie 3
    SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = 7;
    
    -- Zapytanie 4
    SELECT przepis, plik FROM potrawy WHERE idPotrawy = 7;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

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

    Krok 8: Grafika separator.png: kadr do pierwszego separatora

    Kryteria:

    R.2.1 Grafika separator.png jest skadrowana tak, że jest widoczny tylko separator zgodny z ilustracją 3. Grafika jest przycięta do krawędzi separatora (sprawdzić bez powiększania)

    ok. 3 min
    Polecenie z arkusza

    Cechy grafiki separator.png: Grafikę należy skadrować tak, aby był widoczny jedynie separator pierwszy od góry, po lewej stronie. Grafikę należy dociąć do krawędzi separatora (ilustracja 3, ramka przedstawia kadr obrazu).

    separator.png ma przezroczyste tło i dziewięć ozdobników. Pierwszy od góry po lewej to linia z ornamentem pośrodku. W GIMP-ie zaznaczasz go prostokątem z zapasem (bez ozdobnika z prawej kolumny i bez separatora poniżej), Obraz → Przytnij do zaznaczenia, a potem Obraz → Przytnij do zawartości - krawędzie dosuną się do linii i ornamentu, jak ramka na ilustracji 3. Wynik: 317 × 57 px. Arkusz nie wymaga skalowania, więc eksportujesz od razu do PNG (przezroczystość zostaje).

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

    ok. 2 min
    Polecenie z arkusza

    Składa się ze strony o nazwie przepisy.php. Zapisana w języku HTML5

    Deklaracja <!DOCTYPE html> i szkielet strony. Rozszerzenie .php, bo dojdą skrypty; na egzaminie plik leży w htdocs XAMPP-a i otwierasz go przez http://localhost/....

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

    Kryteria:

    R.2.2 W pliku przepisy.php znajduje się deklaracja HTML5 <!DOCTYPE HTML> i deklaracja języka zawartości witryny: polski np. <html lang="pl">

    ok. 1 min
    Polecenie z arkusza

    Zadeklarowany polski język zawartości witryny

    Atrybut lang="pl" w znaczniku <html> - razem z deklaracją HTML5 to jedno kryterium klucza.

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

    ok. 1 min
    Polecenie z arkusza

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

    <meta charset="UTF-8"> jako pierwszy element <head> - bez niego „Łosoś” i „Jagnięcina” mogą wyświetlić się krzakami.

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

    Kryteria:

    R.2.3 W sekcji head znajduje się jawnie podany standard kodowania polskich znaków i tytuł strony "Blog kulinarny"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony „Blog kulinarny”

    <title> w <head>. Kodowanie i tytuł to razem jedno kryterium.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.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 styl.css formatowanie CSS pochodzi jedynie z tego arkusza (oprócz stylu inline sekcji)

    ok. 1 min
    Polecenie z arkusza

    Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony

    Nazwa pliku: styl.css (nie style.css). Formatowanie ma pochodzić z tego pliku - jedynym wyjątkiem, którego wymaga arkusz, będzie styl inline tła sekcji.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  14. Krok 14: Bloki: boczny, główny i sekcja

    Kryteria:

    R.2.4 W sekcji body zdefiniowany jest podział na bloki za pomocą semantycznych znaczników HTML5: aside+main+section (dopuszcza się zastosowanie bloków pomocniczych)

    ok. 1 min
    Polecenie z arkusza

    Podział strony na bloki zrealizowany za pomocą semantycznych znaczników bloków języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków na stronie był zgodny z ilustracją 4

    Trzy bloki obok siebie z ilustracji 4: aside, main i section (R.2.4). Kolejność w kodzie jest kolejnością od lewej - obok siebie ustawisz je w CSS.

    przepisy.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
        </aside>
        <main>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  15. Krok 15: Odnośnik „Sernik” z identyfikatorem 1

    ok. 2 min
    Polecenie z arkusza

    Zawartość bloku bocznego: Każdy odnośnik prowadzi do pliku przepisy.php oraz przesyła do niego metodą GET wartość id odpowiadającą wybranej potrawie, są to 1 dla odnośnika Sernik, 2 dla Sałatka itd.

    Parametr GET to dopisek do adresu po znaku zapytania (tabela 3 arkusza): przepisy.php?id=1. Odnośnik prowadzi do tej samej strony - po kliknięciu przeładuje się z innym id. Na końcu <br>, bo odnośniki są elementami liniowymi i bez złamania stanęłyby w jednym wierszu.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
        </aside>
        <main>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  16. Krok 16: Dziesięć odnośników potraw

    Kryteria: ,

    R.2.6 W bloku bocznym znajduje się 10 odnośników o treści: Sernik, Sałatka, Pankejki, Nugetsy, Łosoś, Kociołek, Jagnięcina, Hamburgery, Eklerki, Churros

    R.3.4 Kliknięcie dowolnego odnośnika odświeża stronę przepisy.php oraz przesyła wartość id potrawy, której odnośnik kliknięto, URL jest postaci, np.: przepisy.php?id=1 (sprawdzić dla przynajmniej trzech odnośników)

    ok. 3 min
    Polecenie z arkusza

    10 odnośników z nazwami potraw (można skopiować z pliku lista.txt): Sernik, Sałatka ... Każdy odnośnik umieszczony jest w osobnej linii

    Plik lista.txt z archiwum ma gotowe pary „?id=1 Sernik”, „?id=2 Sałatka” itd. - kopiujesz je i każdą przerabiasz na odnośnik według wzoru z Sernika, z <br> na końcu linii. Identyfikator to numer potrawy w bazie: Jagnięcina ma 7, Churros 10 (R.2.6, R.3.4).

    Typowe błędy

    Przy kopiowaniu linii łatwo zostawić stary numer (np. „Łosoś” z id=4) - wtedy kliknięcie pokazuje inną potrawę. Sprawdź kilka odnośników po napisaniu skryptów.

    przepisy.php PHP zmienione: 9 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
        </aside>
        <main>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  17. Krok 17: Autor pod odnośnikami

    ok. 1 min
    Polecenie z arkusza

    Paragraf o treści „Autor: ”, dalej wstawiony numer zdającego

    Akapit w bloku bocznym, pod listą potraw. Na egzaminie po dwukropku wpisujesz swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  18. Krok 18: Blok główny: nagłówek na rodzaj potrawy

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego: Nagłówek pierwszego stopnia wypełniony skryptem 1. Efekt działania skryptu 2

    Pusty <h1> - jego treść (rodzaj potrawy, np. „dania mięsne”) wypisze skrypt 1. Pod nim stanie wynik skryptu 2.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  19. Krok 19: Separator

    Kryteria:

    R.2.7 W bloku głównym znajduje się obraz separatora z tekstem alternatywnym "przepis"

    ok. 1 min
    Polecenie z arkusza

    Obraz separator.png z tekstem alternatywnym „przepis”

    <img> z grafiką przygotowaną na początku.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
            <img src="separator.png" alt="przepis">
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  20. Krok 20: Akapit na alergeny

    ok. 1 min
    Polecenie z arkusza

    Paragraf o treści „Alergeny: ”, dalej w paragrafie występują nazwy alergenów wypisane skryptem 3

    Skrypt 3 wypisze nazwy wewnątrz tego akapitu, po dwukropku i spacji.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  21. Krok 21: Nagłówek „Składniki”

    ok. 1 min
    Polecenie z arkusza

    Nagłówek drugiego stopnia o treści „Składniki”

    <h2>.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  22. Krok 22: Lista składników

    Kryteria:

    R.2.8 W bloku głównym znajduje się jedna lista punktowana z czterema elementami, znaczniki <ul> i <li>

    ok. 1 min
    Polecenie z arkusza

    Lista punktowana (nieuporządkowana) wypełniona elementami z pliku lista.txt

    Lista punktowana to <ul>, a cztery elementy <li> kopiujesz z drugiej części lista.txt (od „Lorem 1 kg” do „Sit amet”). To tekst zastępczy - ta sama lista stoi przy każdej potrawie (R.2.8).

    przepisy.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  23. Krok 23: Akapit na przepis

    ok. 1 min
    Polecenie z arkusza

    Paragraf wypełniony skryptem 4

    Pusty <p> na końcu bloku głównego - skrypt 4 wypisze w nim tekst przepisu.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p></p>
        </main>
        <section>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  24. Krok 24: Sekcja: tło ze stylu inline

    Kryteria:

    R.3.3 Do bloku sekcji przypisane jest formatowanie inline tła w postaci obrazu

    ok. 2 min
    Polecenie z arkusza

    Zawartość bloku sekcji: Przypisany jak atrybut znacznika bloku styl CSS inline: tło wypełnione obrazem, którego nazwa pliku została pobrana skryptem 4

    Styl inline to atrybut style w samym znaczniku - to jedyny wyjątek od zasady „cały CSS w styl.css” i arkusz go wprost wymaga (R.3.3). Tło z obrazu: background-image: url('jagniecina.jpg'). Na razie wpisujesz nazwę pliku na stałe, żeby zobaczyć efekt; w skrypcie 4 zastąpisz ją nazwą z bazy.

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p></p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  25. Krok 25: Sekcja: nagłówek bloga

    Kryteria:

    R.2.5 W bloku bocznym znajduje się <p> z numerem zdającego, w bloku głównym <h1> i <p> (w HTML lub skrypcie ) oraz <h2> "Składniki", w bloku sekcji <h1>: "Blog Kulinarny"

    ok. 1 min
    Polecenie z arkusza

    Nagłówek pierwszego stopnia o treści „Blog Kulinarny”

    Drugi <h1> na stronie - tym razem w sekcji. Są już wszystkie nagłówki i akapity z klucza: akapit autora, <h1> i akapity w bloku głównym, „Składniki” i „Blog Kulinarny” (R.2.5).

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1></h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p></p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  26. Etap 3: Styl CSS

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

    Krok 26: Plik styl.css: krój i wyrównanie

    Kryteria:

    R.4.1 domyślne formatowanie selektorów (*): krój czcionki Garamond, wyrównanie tekstu do środka

    ok. 1 min
    Polecenie z arkusza

    Domyślnie dla wszystkich selektorów: krój czcionki Garamond, wyrównanie tekstu do środka

    Selektor *. Arkusz nie podaje rodziny zapasowej - można dopisać serif, klucz tego nie wymaga.

    styl.css CSS nowy plik
    * {
        font-family: Garamond;
        text-align: center;
    }
    Podgląd strony po tym kroku (przepisy.php)
  27. Krok 27: Blok boczny

    ok. 1 min
    Polecenie z arkusza

    Dla bloku bocznego: kolor tła #3A3C3E, biały kolor czcionki, szerokość 10%, wysokość 600 px

    Ciemnografitowe tło i biały tekst. Odnośniki mają domyślny kolor przeglądarki (niebieski) - zmienisz go w regule a.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    Podgląd strony po tym kroku (przepisy.php)
  28. Krok 28: Blok główny: wymiary i paski przewijania

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego: szerokość 45%, wysokość 600 px, paski przewijania widoczne jedynie w przypadku przepełnienia bloku

    overflow: auto - pasek przewijania pojawia się tylko wtedy, gdy treść nie mieści się w 600 px. Przepis jagnięciny jest długi, więc na ilustracji 2 widać pasek z prawej strony bloku.

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    Podgląd strony po tym kroku (przepisy.php)
  29. Krok 29: Blok sekcji: dopasowanie tła i wymiary

    Kryteria: ,

    R.4.4 wysokość: blok boczny, główny, sekcji - 600px szerokość: blok boczny - 10%, główny i sekcji - 45% (width lub grid-template-columns lub flex )

    R.4.5 przepełnienie bloku: blok główny auto styl bloku sekcji: background-size: cover;

    ok. 2 min
    Polecenie z arkusza

    Dla bloku sekcji: wymiary obrazu tła są automatycznie dostosowane do wymiaru bloku przez obcięcie lub rozciągnięcie obrazu, biały kolor czcionki, szerokość 45%, wysokość 600 px

    Tabela 2 arkusza: background-size: cover skaluje obraz tak, żeby przykrył cały blok, a to, co wystaje, obcina. Sam obraz sekcji przyszedł ze stylu inline, a jego dopasowanie - z pliku CSS; oba zapisy działają razem. Masz komplet wymiarów (R.4.4) i przepełnienia (R.4.5) z klucza.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    section {
        background-size: cover;
        color: white;
        width: 45%;
        height: 600px;
    }
    Podgląd strony po tym kroku (przepisy.php)
  30. Krok 30: Układ bloków zgodny z ilustracją 4

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki zrealizowany za pomocą semantycznych znaczników bloków języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków na stronie był zgodny z ilustracją 4

    Trzy bloki w jednym rzędzie: display: flex na <body> stawia dzieci obok siebie (10% + 45% + 45% = 100%). Wszystkie mają tę samą wysokość 600 px, więc nic nie wystaje poniżej (R.3.1).

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    section {
        background-size: cover;
        color: white;
        width: 45%;
        height: 600px;
    }
    body {
        display: flex;
    }
    Podgląd strony po tym kroku (przepisy.php)
  31. Krok 31: Nagłówki pierwszego stopnia

    Kryteria: ,

    R.4.2 kolor tła: blok boczny - #3A3C3E, selektor h1 - RGBA(211, 211, 211, 0.3) (lub z opacity )

    R.4.6 styl nagłówka pierwszego stopnia: marginesy wewnętrzne (padding ): 20px góra i dół marginesy zewnętrzne (margin ): 0

    ok. 2 min
    Polecenie z arkusza

    Dla selektora nagłówka pierwszego stopnia: kolor tła RGB 211, 211, 211, przezroczystość 0.3, marginesy wewnętrzne górny i dolny 20 px pozostałe 0, marginesy zewnętrzne 0, rozmiar czcionki 2 em

    Kolor z przezroczystością to rgba(211, 211, 211, 0.3) - czwarta liczba to krycie od 0 do 1. Jasnoszary pasek na zdjęciu w sekcji przepuszcza obraz, a sam tekst zostaje nieprzezroczysty (opacity przezroczyściłaby też napis). padding: 20px 0 to skrót: góra i dół 20 px, lewo i prawo 0. Selektor h1 obejmuje oba nagłówki: rodzaj potrawy i „Blog Kulinarny” (R.4.6).

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    section {
        background-size: cover;
        color: white;
        width: 45%;
        height: 600px;
    }
    body {
        display: flex;
    }
    h1 {
        background-color: rgba(211, 211, 211, 0.3);
        padding: 20px 0;
        margin: 0;
        font-size: 2em;
    }
    Podgląd strony po tym kroku (przepisy.php)
  32. Krok 32: Nagłówki drugiego stopnia: kapitaliki

    ok. 1 min
    Polecenie z arkusza

    Dla selektora nagłówka drugiego stopnia: rozmiar czcionki 2 em, tekst pisany kapitalikami

    Kapitaliki to font-variant: small-caps - małe litery wyglądają jak pomniejszone wielkie, jak „Składniki” na ilustracji 2. To nie to samo co text-transform: uppercase (same wielkie litery jednego rozmiaru).

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    section {
        background-size: cover;
        color: white;
        width: 45%;
        height: 600px;
    }
    body {
        display: flex;
    }
    h1 {
        background-color: rgba(211, 211, 211, 0.3);
        padding: 20px 0;
        margin: 0;
        font-size: 2em;
    }
    h2 {
        font-size: 2em;
        font-variant: small-caps;
    }
    Podgląd strony po tym kroku (przepisy.php)
  33. Krok 33: Elementy listy do lewej

    Kryteria:

    R.4.9 styl selektora li: wyrównanie tekstu do lewej strony

    ok. 1 min
    Polecenie z arkusza

    Dla selektora elementu listy: wyrównanie tekstu do lewej strony

    Selektor li nadpisuje środkowanie z * tylko dla składników.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    section {
        background-size: cover;
        color: white;
        width: 45%;
        height: 600px;
    }
    body {
        display: flex;
    }
    h1 {
        background-color: rgba(211, 211, 211, 0.3);
        padding: 20px 0;
        margin: 0;
        font-size: 2em;
    }
    h2 {
        font-size: 2em;
        font-variant: small-caps;
    }
    li {
        text-align: left;
    }
    Podgląd strony po tym kroku (przepisy.php)
  34. Krok 34: Odnośniki

    Kryteria: , ,

    R.4.3 kolor czcionki: blok boczny i sekcji - biały, selektor a - Gainsboro

    R.4.7 cechy czcionki: selektor h2 font-variant:small-caps; (font-variant-caps) odnośnik: tekst pochylony np. font-style: italic;

    R.4.8 rozmiar czcionki: nagłówek pierwszego i drugiego stopnia - 2em, odnośnik - 120%

    ok. 1 min
    Polecenie z arkusza

    Dla selektora odnośnika: kolor czcionki Gainsboro, rozmiar czcionki 120%, czcionka pochylona

    Jasnoszary kolor Gainsboro na ciemnym tle bloku bocznego, kursywa przez font-style: italic. Ta reguła zamyka kryteria kolorów czcionki, cech czcionki i rozmiarów (R.4.3, R.4.7, R.4.8).

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    section {
        background-size: cover;
        color: white;
        width: 45%;
        height: 600px;
    }
    body {
        display: flex;
    }
    h1 {
        background-color: rgba(211, 211, 211, 0.3);
        padding: 20px 0;
        margin: 0;
        font-size: 2em;
    }
    h2 {
        font-size: 2em;
        font-variant: small-caps;
    }
    li {
        text-align: left;
    }
    a {
        color: Gainsboro;
        font-size: 120%;
        font-style: italic;
    }
    Podgląd strony po tym kroku (przepisy.php)
  35. Krok 35: Odnośnik pod kursorem

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    Pseudoklasa :hover - na ilustracji 2 kursor stoi na „Jagnięcina” i ten odnośnik jest biały.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Garamond;
        text-align: center;
    }
    aside {
        background-color: #3A3C3E;
        color: white;
        width: 10%;
        height: 600px;
    }
    main {
        width: 45%;
        height: 600px;
        overflow: auto;
    }
    section {
        background-size: cover;
        color: white;
        width: 45%;
        height: 600px;
    }
    body {
        display: flex;
    }
    h1 {
        background-color: rgba(211, 211, 211, 0.3);
        padding: 20px 0;
        margin: 0;
        font-size: 2em;
    }
    h2 {
        font-size: 2em;
        font-variant: small-caps;
    }
    li {
        text-align: left;
    }
    a {
        color: Gainsboro;
        font-size: 120%;
        font-style: italic;
    }
    a:hover {
        color: white;
    }
    Podgląd strony po tym kroku (przepisy.php)
  36. Etap 4: Skrypty PHP

    Kroki 36-44 · po tym etapie masz 38 z 38 kryteriów (pkt)

    Krok 36: Połączenie z bazą i zamknięcie na końcu

    Kryteria:

    R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy przepisy oraz ostatnią operacją na bazie jest jej zamknięcie

    ok. 2 min
    Polecenie z arkusza

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

    Pierwszy skrypt na stronie stoi w nagłówku <h1> bloku głównego, więc tam otwierasz połączenie: mysqli_connect z czterema argumentami łączy się z serwerem i od razu wybiera bazę. Ostatni skrypt (4) stoi w akapicie na końcu bloku głównego - na razie tylko zamyka połączenie (R.5.1). Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    przepisy.php PHP zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                ?>
            </h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  37. Krok 37: Identyfikator potrawy: z adresu albo 7

    ok. 2 min
    Polecenie z arkusza

    Jeśli do strony została przesłana wartość metodą GET, zmienna jest inicjowana tą wartością. W przeciwnym wypadku, zmienna jest inicjowana wartością 7. Dalej w opisie skryptów zmienna ta jest nazywana ID

    Po kliknięciu odnośnika adres ma postać przepisy.php?id=5 i wartość czeka w $_GET["id"]. Przy pierwszym wejściu parametru nie ma - isset to sprawdza i wtedy przyjmujesz 7 (jagnięcina, jak na ilustracji 2). Zmienna $id posłuży wszystkim czterem skryptom, więc ustawiasz ją w pierwszym z nich.

    przepisy.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                ?>
            </h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>

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

  38. Krok 38: Skrypt 1: zapytanie 2 dla potrawy ID

    Kryteria:

    R.5.3 Przynajmniej jeden skrypt wysyła zapytanie, zmodyfikowane w ten sposób że sprawdzana jest wartość ze zmiennej zdefiniowanej w R.5.2

    ok. 2 min
    Polecenie z arkusza

    Skrypt 1: Wysyła do bazy danych zapytanie 2, zmodyfikowane tak, że sprawdzana jest zmienna ID

    Zapytanie 2, w którym zamiast 7 stoi $id - PHP wstawi wartość zmiennej do napisu w cudzysłowach. Identyfikator to liczba, więc w SQL bez apostrofów (R.5.3).

    przepisy.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                ?>
            </h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>

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

  39. Krok 39: Skrypt 1: rodzaj potrawy w nagłówku

    Kryteria:

    R.5.4 Na stronie wyświetlany jest rodzaj potrawy zwrócony z bazy danych

    ok. 1 min
    Polecenie z arkusza

    Wyświetla wartość zwróconą polem rodzaj

    Zapytanie zwraca jeden wiersz, więc wystarczy jedno mysqli_fetch_row. Pole rodzaj jest drugie w SELECT, czyli $row[1]. Skrypt stoi wewnątrz <h1>, więc „dania mięsne” wyświetla się jako nagłówek na półprzezroczystym pasku (R.5.4).

    przepisy.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  40. Krok 40: Skrypt 2: zapytanie 1 i nazwa potrawy

    ok. 2 min
    Polecenie z arkusza

    Skrypt 2: Wysyła do bazy danych zapytanie 1, zmodyfikowane tak, że sprawdzana jest zmienna ID. Wyświetla: Nagłówek drugiego stopnia z nazwą potrawy

    Skrypt 2 stoi między nagłówkiem a separatorem. Zapytanie 1 z $id, jeden wiersz, nazwa jest pierwszym polem ($row[0]). Nagłówek <h2> dostaje styl kapitalików z CSS - „Jagnięcina” wygląda jak na ilustracji 2.

    przepisy.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $row = mysqli_fetch_row($result);
                echo "<h2>$row[0]</h2>";
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  41. Krok 41: Skrypt 2: trudność słownie i kalorie

    Kryteria: ,

    R.5.5 Na stronie wyświetlana jest trudność na podstawie pola trudnosc z bazy danych: „łatwe” (trudnosc = 1) lub „średnie” (trudnosc = 2) lub „trudne” (trudnosc = 3)

    R.5.6 Na stronie wyświetlana jest nazwa potrawy i wartość kalorii, które zostały zwrócone zapytaniem

    ok. 3 min
    Polecenie z arkusza

    Paragraf o treści „Trudność: <trudnosc>, Kalorie: <kalorie>”, pola <> są ustalone na podstawie wartości z bazy danych, a <trudnosc> przyjmuje wartości: „łatwe” dla trudnosc=1, „średnie” dla trudnosc=2, „trudne” dla trudnosc=3

    Baza przechowuje trudność jako liczbę 1 - 3, a strona ma pokazać słowo. Instrukcja if / elseif / else wybiera słowo i zapisuje je w zmiennej $level; trzeci przypadek to else, bo innych wartości w bazie nie ma. Kalorie ($row[2]) wstawiasz bez zmian. Dla jagnięciny: „Trudność: trudne, Kalorie: 225” (R.5.5, R.5.6).

    przepisy.php PHP zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $row = mysqli_fetch_row($result);
                echo "<h2>$row[0]</h2>";
                if ($row[1] == 1) {
                    $level = "łatwe";
                } elseif ($row[1] == 2) {
                    $level = "średnie";
                } else {
                    $level = "trudne";
                }
                echo "<p>Trudność: $level, Kalorie: $row[2]</p>";
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: </p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  42. Krok 42: Skrypt 3: alergeny oddzielone spacją

    Kryteria:

    R.5.7 Na stronie wyświetlane są alergeny zwrócone zapytaniem, zastosowano pętlę dla wszystkich zwróconych rekordów

    ok. 2 min
    Polecenie z arkusza

    Skrypt 3: Wysyła do bazy danych zapytanie 3, zmodyfikowane tak, że sprawdzana jest zmienna ID. Wyświetla oddzielone spacją nazwy wszystkich alergenów zwróconych z bazy

    Skrypt 3 stoi w środku akapitu „Alergeny: ”. Potrawa może mieć kilka alergenów, więc tu potrzebna jest pętla while - wypisuje drugie pole każdego wiersza ($row[1], nazwa alergenu) i spację po nim. Dla jagnięciny: „seler”; po kliknięciu „Kociołek” (?id=6): „gluten laktoza orzechy” (R.5.7).

    przepisy.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $row = mysqli_fetch_row($result);
                echo "<h2>$row[0]</h2>";
                if ($row[1] == 1) {
                    $level = "łatwe";
                } elseif ($row[1] == 2) {
                    $level = "średnie";
                } else {
                    $level = "trudne";
                }
                echo "<p>Trudność: $level, Kalorie: $row[2]</p>";
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: <?php
                $query = "SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo $row[1] . " ";
                }
            ?></p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  43. Krok 43: Skrypt 4: przepis i nazwa pliku zdjęcia

    Kryteria:

    R.5.8 Na stronie wyświetlana jest zawartość pola przepis

    ok. 2 min
    Polecenie z arkusza

    Skrypt 4: Wysyła do bazy danych zapytanie 4, zmodyfikowane tak, że sprawdzana jest zmienna ID. Wyświetla wartość pola przepis zwróconą zapytaniem

    Zapytanie 4 z $id. Tekst przepisu ($row[0]) wypisujesz w akapicie, a nazwę pliku ($row[1]) zapamiętujesz w zmiennej $file - przyda się za chwilę w sekcji. Połączenie zamykasz dopiero po tym zapytaniu, bo to ostatnia operacja na bazie (R.5.8). Przepis jest długi - w węższym oknie, jak na ilustracji 2, treść przestaje mieścić się w 600 px i w bloku głównym pojawia się pasek przewijania.

    przepisy.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $row = mysqli_fetch_row($result);
                echo "<h2>$row[0]</h2>";
                if ($row[1] == 1) {
                    $level = "łatwe";
                } elseif ($row[1] == 2) {
                    $level = "średnie";
                } else {
                    $level = "trudne";
                }
                echo "<p>Trudność: $level, Kalorie: $row[2]</p>";
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: <?php
                $query = "SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo $row[1] . " ";
                }
            ?></p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    $query = "SELECT przepis, plik FROM potrawy WHERE idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[0];
                    $file = $row[1];
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('jagniecina.jpg');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  44. Krok 44: Tło sekcji z nazwy pliku z bazy

    Kryteria: , ,

    R.5.2 Zmienna identyfikatora potrawy jest inicjowana wartością 7, następnie wartością przesłaną metodą GET do strony. Wygenerowana zawartość strony (w tym tło sekcji) zawsze dotyczy jednej potrawy - zgodnej z klikniętym odnośnikiem, w stanie początkowym zawartość dotyczy jagnięciny (sprawdzić dla co najmniej trzech odnośników)

    R.5.9 Tło sekcji jest wyświetlane z pliku o nazwie zwróconej zapytaniem w skrypcie 4

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

    ok. 2 min
    Polecenie z arkusza

    Pole plik pobrane zapytaniem w tym skrypcie powinno zostać użyte do ustawienia tła sekcji stylem CSS inline, o czym jest mowa w części „Cechy witryny”, „Zawartość bloku sekcji”

    W stylu inline zamiast stałej nazwy jagniecina.jpg wstawiasz krótki blok PHP: <?php echo $file; ?>. Sekcja stoi za blokiem głównym, więc zmienna jest już ustawiona przez skrypt 4. Teraz cała strona zależy od jednego identyfikatora: rodzaj, nazwa, trudność, alergeny, przepis i zdjęcie w tle (R.5.2, R.5.9). W skryptach są zmienne $connection, $id, $query, $result, $row, $level i $file - nazwy po angielsku mówią, do czego służą (R.5.10).

    przepisy.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    if (isset($_GET["id"])) {
                        $id = $_GET["id"];
                    } else {
                        $id = 7;
                    }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $row = mysqli_fetch_row($result);
                echo "<h2>$row[0]</h2>";
                if ($row[1] == 1) {
                    $level = "łatwe";
                } elseif ($row[1] == 2) {
                    $level = "średnie";
                } else {
                    $level = "trudne";
                }
                echo "<p>Trudność: $level, Kalorie: $row[2]</p>";
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: <?php
                $query = "SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo $row[1] . " ";
                }
            ?></p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    $query = "SELECT przepis, plik FROM potrawy WHERE idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[0];
                    $file = $row[1];
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('<?php echo $file; ?>');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>

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

  45. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 45-47 · po tym etapie masz 38 z 38 kryteriów (pkt)

    Krok 45: Identyfikator z adresu: liczba i istniejąca potrawa

    ok. 4 min
    Polecenie z arkusza

    Jeśli do strony została przesłana wartość metodą GET, zmienna jest inicjowana tą wartością. W przeciwnym wypadku, zmienna jest inicjowana wartością 7

    Wersję z egzaminu sprawdzono dwoma adresami. przepisy.php?id=7 OR 1=1 trafia do wszystkich czterech zapytań: strona pokazuje pierwszą potrawę z bazy, a w akapicie alergenów stoi 17 nazw - alergeny wszystkich potraw. ?id=99 (nie ma takiej potrawy) daje serię ostrzeżeń „Trying to access array offset on value of type null” i pustą stronę. Poprawki: (int) zamienia parametr na liczbę, operator ?? podstawia 7, gdy parametru nie ma (jedna linia zamiast pięciu), a krótkie zapytanie kontrolne z mysqli_num_rows (tabela 1 arkusza) cofa nieistniejący numer do 7. Podgląd pokazuje ?id=99 - wraca jagnięcina. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    przepisy.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    $id = (int) ($_GET["id"] ?? 7);
                    $check = mysqli_query($connection, "SELECT idPotrawy FROM potrawy WHERE idPotrawy = $id;");
                    if (mysqli_num_rows($check) == 0) {
                        $id = 7;
                    }
                    // wersja z egzaminu: if (isset($_GET["id"])) { $id = $_GET["id"]; } else { $id = 7; }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $row = mysqli_fetch_row($result);
                echo "<h2>$row[0]</h2>";
                if ($row[1] == 1) {
                    $level = "łatwe";
                } elseif ($row[1] == 2) {
                    $level = "średnie";
                } else {
                    $level = "trudne";
                }
                echo "<p>Trudność: $level, Kalorie: $row[2]</p>";
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: <?php
                $query = "SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo $row[1] . " ";
                }
            ?></p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    $query = "SELECT przepis, plik FROM potrawy WHERE idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[0];
                    $file = $row[1];
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('<?php echo $file; ?>');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>

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

  46. Krok 46: Trudność z tablicy zamiast drabinki if

    ok. 3 min
    Polecenie z arkusza

    Paragraf o treści „Trudność: <trudnosc>, Kalorie: <kalorie>”, pola <> są ustalone na podstawie wartości z bazy danych

    Zamiana liczby na słowo to zwykłe tłumaczenie według tabelki - w PHP robi to tablica asocjacyjna: $levels[3] to „trudne”. Jedna linia zamiast siedmiu, a nowy poziom trudności dopisuje się w jednym miejscu. mysqli_fetch_assoc oddaje pola po nazwach ($dish["kalorie"] zamiast $row[2]), a nazwę potrawy wypisujesz przez htmlspecialchars. Sprawdzone dla sałatki (łatwe), sernika (średnie) i kociołka (trudne). Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    przepisy.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    $id = (int) ($_GET["id"] ?? 7);
                    $check = mysqli_query($connection, "SELECT idPotrawy FROM potrawy WHERE idPotrawy = $id;");
                    if (mysqli_num_rows($check) == 0) {
                        $id = 7;
                    }
                    // wersja z egzaminu: if (isset($_GET["id"])) { $id = $_GET["id"]; } else { $id = 7; }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $dish = mysqli_fetch_assoc($result);
                $levels = [1 => "łatwe", 2 => "średnie", 3 => "trudne"];
                echo "<h2>" . htmlspecialchars($dish["nazwa"]) . "</h2>";
                echo "<p>Trudność: " . $levels[$dish["trudnosc"]] . ", Kalorie: " . $dish["kalorie"] . "</p>";
                // wersja z egzaminu: mysqli_fetch_row i drabinka if / elseif / else
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: <?php
                $query = "SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo $row[1] . " ";
                }
            ?></p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    $query = "SELECT przepis, plik FROM potrawy WHERE idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[0];
                    $file = $row[1];
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('<?php echo $file; ?>');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>

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

  47. Krok 47: Alergeny po przecinku

    ok. 2 min
    Polecenie z arkusza

    Wyświetla oddzielone spacją nazwy wszystkich alergenów zwróconych z bazy

    Same spacje słabo czytają się przy kilku alergenach („gluten laktoza orzechy”), a pętla dopisuje spację także po ostatnim. Zbierz nazwy do tablicy, a implode(", ", ...) skleja je przecinkiem tylko między elementami: „gluten, laktoza, orzechy”. Podgląd pokazuje kociołek (?id=6). Arkusz wymaga spacji, więc na egzaminie zostaje wersja wcześniejsza.

    przepisy.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Blog kulinarny</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <a href="przepisy.php?id=1">Sernik</a><br>
            <a href="przepisy.php?id=2">Sałatka</a><br>
            <a href="przepisy.php?id=3">Pankejki</a><br>
            <a href="przepisy.php?id=4">Nugetsy</a><br>
            <a href="przepisy.php?id=5">Łosoś</a><br>
            <a href="przepisy.php?id=6">Kociołek</a><br>
            <a href="przepisy.php?id=7">Jagnięcina</a><br>
            <a href="przepisy.php?id=8">Hamburgery</a><br>
            <a href="przepisy.php?id=9">Eklerki</a><br>
            <a href="przepisy.php?id=10">Churros</a><br>
            <p>Autor: Bartosz Bryniarski</p>
        </aside>
        <main>
            <h1>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "przepisy");
                    $id = (int) ($_GET["id"] ?? 7);
                    $check = mysqli_query($connection, "SELECT idPotrawy FROM potrawy WHERE idPotrawy = $id;");
                    if (mysqli_num_rows($check) == 0) {
                        $id = 7;
                    }
                    // wersja z egzaminu: if (isset($_GET["id"])) { $id = $_GET["id"]; } else { $id = 7; }
                    $query = "SELECT potrawy.nazwa, rodzaje.rodzaj FROM potrawy JOIN rodzaje ON potrawy.idRodzaje = rodzaje.idRodzaje WHERE potrawy.idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[1];
                ?>
            </h1>
            <?php
                $query = "SELECT nazwa, trudnosc, kalorie FROM potrawy WHERE idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $dish = mysqli_fetch_assoc($result);
                $levels = [1 => "łatwe", 2 => "średnie", 3 => "trudne"];
                echo "<h2>" . htmlspecialchars($dish["nazwa"]) . "</h2>";
                echo "<p>Trudność: " . $levels[$dish["trudnosc"]] . ", Kalorie: " . $dish["kalorie"] . "</p>";
                // wersja z egzaminu: mysqli_fetch_row i drabinka if / elseif / else
            ?>
            <img src="separator.png" alt="przepis">
            <p>Alergeny: <?php
                $query = "SELECT potrawy.nazwa, alergeny.alergen FROM potrawy JOIN lista_alergenow ON potrawy.idPotrawy = lista_alergenow.idPotrawy JOIN alergeny ON lista_alergenow.idAlergeny = alergeny.idAlergeny WHERE potrawy.idPotrawy = $id;";
                $result = mysqli_query($connection, $query);
                $allergens = [];
                while ($row = mysqli_fetch_row($result)) {
                    $allergens[] = htmlspecialchars($row[1]);
                }
                echo implode(", ", $allergens);
                // wersja z egzaminu: echo $row[1] . " "; w pętli (spacja także po ostatnim)
            ?></p>
            <h2>Składniki</h2>
            <ul>
                <li>Lorem 1 kg</li>
                <li>Ipsum 2 szt.</li>
                <li>Dolor 200 g</li>
                <li>Sit amet (szczypta)</li>
            </ul>
            <p>
                <?php
                    $query = "SELECT przepis, plik FROM potrawy WHERE idPotrawy = $id;";
                    $result = mysqli_query($connection, $query);
                    $row = mysqli_fetch_row($result);
                    echo $row[0];
                    $file = $row[1];
                    mysqli_close($connection);
                ?>
            </p>
        </main>
        <section style="background-image: url('<?php echo $file; ?>');">
            <h1>Blog Kulinarny</h1>
        </section>
    </body>
    </html>
    Podgląd strony po tym kroku (przepisy.php)
  48. Etap 6: Oddanie pracy

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

    Krok 48: 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 wpisujesz nazwę przeglądarki, w której sprawdzasz stronę.

    W folderze z numerem zdającego: dziesięć zdjęć potraw z archiwum, import.png, kw1.jpg - kw4.jpg, kwerendy.txt, przeglądarka.txt, przepisy.php, separator.png, styl.css. Arkusz wymienia na liście plik kociołek.jpg z literą „ł”, ale w archiwum i w bazie jest kociolek.jpg - zostawiasz nazwę z archiwum, bo tej szuka strona. 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 47.

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.