Przejdź do głównej treści
INF.03-04-23.06-SGCzerwiec 2023 · 48 kroków · ok. 79 min · 37 kryteriów z klucza

Rozwiązanie krok po kroku: Portal biblioteki publicznej (Wersja podstawowa)

Portal biblioteki w Książkowicach Wielkich to baza biblioteka (autorzy, książki, kategorie, czytelnicy i wypożyczenia), cztery zapytania - sortowanie, INSERT z kluczem nadawanym automatycznie, wybór książek z kategorii „dramat” i złączenie książek z wypożyczeniami - grafika rozszerzona do 300 pikseli ze zdublowanym stosem książek oraz jedna strona biblioteka.php. W panelu lewym Skrypt 1 wypisuje autorów jako elementy listy numerowanej, w prawym górnym jest formularz wysyłany metodą POST, a w prawym dolnym Skrypt 2 potwierdza dodanie czytelnika i zapisuje go w bazie.

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 napisane najprościej, funkcjami z tabeli 1 arkusza (mysqli_query, mysqli_fetch_row), a na końcu sprawdzone na prawdziwych błędach (puste pola, apostrof w nazwisku) i przerobione na wersję z prawdziwych projektów: walidacja, zapytanie przygotowane i htmlspecialchars.

Baza i grafika pochodzą z prawdziwego archiwum materialy4 (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 i z widocznym zapytaniem. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 na bazie z arkusza (klucz każe sprawdzać w XAMPP 8.1.2 - zachowanie tych funkcji jest w obu wersjach takie samo). Od Skryptu 2 podgląd pokazuje stronę po wysłaniu formularza z danymi czytelniczki z obrazu 2, Anny Nowakowskiej; obraz nie pokazuje jej symbolu, więc w podglądzie stoi przykładowy 145322.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, PDO)” jest drugi sposób rozwiązania tego samego arkusza: panele ułożone flexem w kolumny, kolory w zmiennych CSS, dane obsługiwane przez PDO na górze pliku, sprawdzenie danych z formularza, zapytanie przygotowane i przekierowanie po zapisie (odświeżenie nie dodaje czytelnika drugi raz) - obie wersje są zgodne z kluczem.

Ten sam arkusz był też wydany pod numerami 06 i 10 tej sesji - rozwiązanie pasuje do wszystkich trzech.

Jak liczą się punkty. Klucz ma 37 kryteriów (R.1.1 - R.5.7), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 28 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 37 kryteriów (pkt)

    Krok 1: Baza danych biblioteka

    ok. 2 min
    Polecenie z arkusza

    Utwórz nową bazę danych o nazwie biblioteka

    Najpierw archiwum materialy4.7z z pulpitu (hasło 4rch!wum4x - cyfra 4 zamiast „a”, wykrzyknik zamiast „i”) i folder z numerem zdającego, do którego trafiają biblioteka.sql i biblioteka.png. W phpMyAdmin: Nowa, nazwa biblioteka. Arkusz nie podaje porównywania - wybierasz np. utf8_polish_ci. Tabel z biblioteka.sql to nie zmienia: każda ma zestaw znaków zapisany we własnej definicji (część latin1, część utf8), a porównywanie bazy dziedziczą tylko tabele zakładane później bez własnego ustawienia.

    Typowe błędy

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

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

    ok. 2 min
    Polecenie z arkusza

    Do bazy zaimportuj tabele z pliku biblioteka.sql, z wcześniej rozpakowanego archiwum

    Przy zaznaczonej bazie biblioteka: Import → biblioteka.sql → Wykonaj. Powstaje sześć tabel; zadanie używa pięciu z obrazu 1: autorzy (10 autorów), ksiazki (21 tytułów z polem id_kategoria), kategorie (epika, dramat, liryka), czytelnicy (10 osób, pole kod puste) i wypozyczenia - pary czytelnik-książka z datami.

  3. Krok 3: Zrzut ekranu import.jpg

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych o nazwie biblioteka , czynność udokumentowano plikiem o nazwie import w formacie JPEG

    ok. 2 min
    Polecenie z arkusza

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

    Print Screen, wklejenie do edytora grafiki i zapis jako import.jpg - w tym arkuszu wszystkie zrzuty są w JPEG. Na zrzucie widać komunikat o zakończonym imporcie i listę tabel po lewej.

    Typowe błędy

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

  4. Krok 4: Zapytanie 1: autorzy alfabetycznie po nazwisku

    Kryteria: ,

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

    R.1.3 Zapisano zapytanie 1 wybierające jedynie imie i nazwisko dla wszystkich rekordów w tabeli autorzy , alfabetycznie posortowane rosnąco nazwiskami autorów. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko; (opcjonalnie ASC) oraz wynik działania zapytania udokumentowano zrzutem ekranu, na którym jest widocznych dokładnie 10 rekordów z imionami i nazwiskami wszystkich autorów w kolejności alfabetycznej

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola imie i nazwisko dla wszystkich rekordów w tabeli autorzy, posortowane rosnąco nazwiskami autorów

    • SELECT imie, nazwisko - tylko dwa pola, bez id,
    • FROM autorzy,
    • ORDER BY nazwisko - rosnąco to kierunek domyślny, ASC można dopisać.

    Wynik: 10 autorów od Brzechwy do Witkiewicz - w tej samej kolejności co lista na obrazie 2, bo z tego zapytania powstanie Skrypt 1. Zapytania trafiają do kwerendy.txt, zrzut wyniku (z widocznym zapytaniem, jak każe arkusz) do kwerenda1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: nowa czytelniczka Ewa Kowalska

    Kryteria:

    R.1.4 Zapisano zapytanie 2 wstawiające do tabeli czytelnicy rekord Ewa Kowalska z kodem 145321, wartość klucza głównego jest nadawana automatycznie. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO `czytelnicy`(`imie`, `nazwisko`, `kod`) VALUES ('Ewa', 'Kowalska', '145321'); (możliwe również bez struktury tabeli lub przez przypisania SET) oraz wynik działania zapytania udokumentowano zrzutem ekranu z widocznym komunikatem o pomyślnym wykonaniu zapytania lub tabela z wstawionym wierszem

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wstawiające do tabeli czytelnicy nowy rekord z danymi: Ewa Kowalska z kodem 145321. Wartość klucza głównego nadawana automatycznie

    • INSERT INTO czytelnicy (imie, nazwisko, kod) - lista pól bez id: klucz główny ma AUTO_INCREMENT, więc baza sama nada kolejny numer,
    • VALUES ('Ewa', 'Kowalska', '145321') - wartości w tej samej kolejności co pola; kod jest tekstem (varchar(6)), więc też w apostrofach.

    Komunikat: „1 wiersz wstawiony”, nowy rekord dostał id 11. Zrzut kwerenda2.jpg pokazuje komunikat i tabelę z nowym wierszem. Z tego zapytania powstanie Skrypt 2.

    Typowe błędy

    Wpisanie id z własną wartością (np. 11) nie spełnia warunku „nadawana automatycznie”. Zapytanie wykonane dwa razy doda dwie Ewy Kowalskie.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;
    
    -- Zapytanie 2
    INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES ('Ewa', 'Kowalska', '145321');
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: tytuły z kategorii dramat

    Kryteria:

    R.1.5 Zapisano zapytanie 3 wybierające jedynie pole tytul dla wszystkich utworów w tabeli ksiazki z kategorii dramat. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT tytul FROM ksiazki WHERE id_kategoria = 2; (lub wykorzystując połączenie tabel i nazwę kategorii 'dramat') oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne są dokładnie 4 tytuły: Zemsta, Pan Jowialski, Niemcy, Odwiedziny

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pole tytul dla wszystkich utworów w tabeli ksiazki, należących do kategorii dramat

    • SELECT tytul,
    • FROM ksiazki JOIN kategorie - nazwa kategorii jest w osobnej tabeli,
    • ON ksiazki.id_kategoria = kategorie.id - powiązanie z obrazu 1,
    • WHERE kategorie.nazwa = 'dramat'.

    Wynik: 4 tytuły - Zemsta, Pan Jowialski, Niemcy, Odwiedziny - zgodnie z kluczem. Klucz uznaje też krótsze WHERE id_kategoria = 2 (sprawdzone, ten sam wynik), ale warunek na nazwie działa także wtedy, gdy kategorie dostaną inne numery - a uwaga klucza wymaga zapytania „uniwersalnego dla każdego zestawu danych”. Zrzut: kwerenda3.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;
    
    -- Zapytanie 2
    INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES ('Ewa', 'Kowalska', '145321');
    
    -- Zapytanie 3
    SELECT tytul FROM ksiazki JOIN kategorie ON ksiazki.id_kategoria = kategorie.id WHERE kategorie.nazwa = 'dramat';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: książki wypożyczone przez czytelnika 2

    Kryteria:

    R.1.6 Zapisano zapytanie 4 wybierające jedynie pole tytul wszystkich utworów z tabeli ksiazki wypożyczonych przez czytelnika o identyfikatorze 2. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT tytul FROM ksiazki JOIN wypozyczenia ON ksiazki.id = wypozyczenia.id_ksiazka WHERE wypozyczenia.id_czytelnik = 2; (lub INNER JOIN, lub bez JOIN, z porównaniem kuczy w WHERE) oraz wynik działania zapytania udokumentowano zrzutem ekranu, na którym widoczne są jedynie tytuły: Zemsta, Brzechwa dzieciom

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: wybierające jedynie pole tytul wszystkich utworów w tabeli książki, wypożyczonych przez czytelnika o identyfikatorze 2. W zapytaniu 4 należy posłużyć się relacją

    • SELECT tytul,
    • FROM ksiazki JOIN wypozyczenia - „posłużyć się relacją” to złączenie tabel,
    • ON ksiazki.id = wypozyczenia.id_ksiazka - które wypożyczenie dotyczy której książki,
    • WHERE wypozyczenia.id_czytelnik = 2.

    Wynik: Zemsta i Brzechwa dzieciom - jak w kluczu. Czytelnik 2 ma w tabeli trzy wypożyczenia, ale jedno wskazuje książkę o numerze 22, której nie ma w tabeli ksiazki; złączenie wewnętrzne takie wiersze pomija. Zrzut: kwerenda4.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;
    
    -- Zapytanie 2
    INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES ('Ewa', 'Kowalska', '145321');
    
    -- Zapytanie 3
    SELECT tytul FROM ksiazki JOIN kategorie ON ksiazki.id_kategoria = kategorie.id WHERE kategorie.nazwa = 'dramat';
    
    -- Zapytanie 4
    SELECT tytul FROM ksiazki JOIN wypozyczenia ON ksiazki.id = wypozyczenia.id_ksiazka WHERE wypozyczenia.id_czytelnik = 2;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

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

    Krok 8: Grafika: płótno 300 px i drugi stos książek

    Kryteria:

    R.2.1 Grafikę biblioteka.png przekształcono zgodnie z obrazem 3b, są widoczne dwa stosy książek i szerokość wynosi dokładnie 300 px, a wysokość 235 px

    ok. 5 min
    Polecenie z arkusza

    Grafikę biblioteka.png należy rozszerzyć z rozmiaru poziomego 150 px do rozmiaru 300 px, a następnie w pustym obszarze zdublować stos książek zgodnie z obrazem 3b

    W GIMP-ie: Obraz → Rozmiar płótna, szerokość 300, wysokość bez zmian (235), obraz przy lewej krawędzi, Zmień rozmiar warstw: wszystkie warstwy. Prawa połowa jest przezroczysta - tło PNG było przezroczyste już w oryginale. Potem Zaznacz → Wszystko na starym fragmencie (albo prostokąt 150 × 235), Kopiuj, Wklej jako nową warstwę i przesunięcie jej o 150 pikseli w prawo (narzędzie Przesunięcie albo Warstwa → Właściwości, przesunięcie X = 150). Na koniec Plik → Nadpisz biblioteka.png.

    To „rozszerzenie płótna”, a nie skalowanie - stos książek nie może się rozciągnąć. Wynik: 300 × 235 pikseli, dwa takie same stosy obok siebie.

    Typowe błędy

    Skaluj obraz do 300 px rozciąga stos w poziomie zamiast dodać puste miejsce - kryterium R.2.1 wymaga dwóch stosów i wymiarów dokładnie 300 × 235.

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

    ok. 2 min
    Polecenie z arkusza

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

    Deklaracja <!DOCTYPE html> i szkielet strony. Rozszerzenie .php, bo strona będzie miała skrypty; na egzaminie folder z numerem zdającego leży w htdocs XAMPP-a i strona otwiera się przez http://localhost/..., inaczej PHP się nie wykona.

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

    ok. 1 min
    Polecenie z arkusza

    Ustawiony język zawartości strony na polski

    Atrybut lang="pl" w znaczniku <html> - przeglądarka i czytnik ekranu wiedzą, że treść jest po polsku.

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

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku biblioteka .php, zastosowano deklarację języka HTML5 <!DOCTYPE html>, zadeklarowano język witryny polski np. <html lang = "pl"> oraz zastosowano właściwy standard kodowania 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>. Razem z deklaracją HTML5 i językiem to jedno kryterium klucza (R.2.2).

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

    Kryteria:

    R.2.3 Nadano stronie tytuł "Biblioteka publiczna”

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Biblioteka publiczna”

    <title> w <head> - to napis na karcie przeglądarki, nie na stronie.

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

    Kryteria:

    R.3.6 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie style.css , formatowanie pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)

    ok. 1 min
    Polecenie z arkusza

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

    Nazwa pliku: style.css (w tej sesji inne arkusze miały styl.css - tu jest „style”). Całe formatowanie ma pochodzić z tego pliku - żadnych atrybutów style w HTML-u.

    Typowe błędy

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

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  14. Krok 14: Bloki: baner, cztery panele i stopka

    Kryteria:

    R.2.4 Wygląd strony zdefiniowano dzieląc ją na baner, panele lewy, środkowy, prawy górny i dolny, oraz stopkę. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze baner, poniżej bloki: lewy, środkowy i dwa prawe ułożone jeden pod drugim oraz na dole blok stopki. Podział zrealizowany za pomocą znaczników sekcji tak, aby wygląd układu bloków strony po uruchomieniu w przeglądarce, był zgodny z obrazem 2

    Baner to <header>, stopka <footer>, a cztery panele - cztery <section>. Każdy panel ma inny kolor albo wymiary, więc dostaje identyfikator: left, middle, top-right i bottom-right. Kolejność w kodzie: lewy, środkowy, prawy górny, prawy dolny - w tej kolejności ułoży je CSS. Na razie bloki stoją jeden pod drugim i są puste.

    biblioteka.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
        </header>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="top-right">
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  15. Krok 15: Baner: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: nagłówek pierwszego stopnia o treści „Biblioteka w Książkowicach Wielkich”

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

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="top-right">
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  16. Krok 16: Panel lewy: nagłówek trzeciego stopnia

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści „Polecamy dzieła autorów:”

    <h3> z dwukropkiem na końcu, jak w arkuszu. Strona nie ma <h2> - arkusz tak ustawia stopnie.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
        </section>
        <section id="middle">
        </section>
        <section id="top-right">
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  17. Krok 17: Panel lewy: pusta lista numerowana

    ok. 1 min
    Polecenie z arkusza

    Lista numerowana (uporządkowana), której elementy są generowane skryptem 1

    Lista numerowana to <ol> (ordered list). Znaczniki listy są w HTML-u, a elementy <li> dopisze Skrypt 1 - jeden na każdego autora. Pusta lista na razie nic nie pokazuje.

    biblioteka.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
        </section>
        <section id="top-right">
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  18. Krok 18: Panel środkowy: adres ze spacją nierozdzielającą

    Kryteria:

    R.2.9 Zastosowano jedynie znak specjalny &nbsp; w danych adresowych: Książkowice&nbsp;Wielkie (bez zwykłych spacji)

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści: „ul. Czytelnicza 25, Książkowice Wielkie”. Dwa człony nazwy miasta połączone są spacją nierozdzielającą

    Spacja nierozdzielająca to encja &nbsp;: wygląda jak zwykła spacja, ale przeglądarka nie złamie w tym miejscu wiersza, więc „Książkowice Wielkie” zawsze stoją w jednej linii (na obrazie 2 adres zawija się przed nazwą miasta, a nie w jej środku). Klucz wymaga encji tylko między członami nazwy miasta - reszta spacji zwykła.

    Typowe błędy

    Encja musi stać zamiast spacji, a nie obok niej: Książkowice &nbsp;Wielkie to dwie spacje i kryterium R.2.9 nie jest spełnione.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
        </section>
        <section id="top-right">
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  19. Krok 19: Panel środkowy: odsyłacz pocztowy

    Kryteria: ,

    R.3.5 Napis "Napisz do nas" jest odsyłaczem pocztowym do adresu [email protected], w definicji zastosowano "mailto:"

    R.2.5 Zapisano w banerze nagłówek h1 "Biblioteka w Książkowicach Wielkich", w panelach przynajmniej jeden z nagłówków h3: "Polecamy dzieła autorów:”, "ul. Czytelnicza 25, Książkowice Wielkie", "Dodaj czytelnika” oraz zapisano przynajmniej jeden paragraf

    ok. 1 min
    Polecenie z arkusza

    Paragraf (akapit) o treści „Napisz do nas”, który jest odsyłaczem pocztowym do adresu [email protected]

    Odsyłacz pocztowy to <a> z adresem zaczynającym się od mailto: - kliknięcie otwiera program pocztowy z wpisanym odbiorcą. Odnośnik stoi wewnątrz <p>, bo arkusz każe zrobić akapit. To pierwszy akapit strony, więc tym krokiem jest komplet do R.2.5: <h1> w banerze, <h3> w panelach i co najmniej jeden paragraf.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
        </section>
        <section id="top-right">
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  20. Krok 20: Panel środkowy: obraz z tekstem alternatywnym

    Kryteria:

    R.2.8 W bloku środkowym umieszczono obraz z pliku biblioteka.png z tekstem alternatywnym "książki"

    ok. 1 min
    Polecenie z arkusza

    Obraz biblioteka.png z tekstem alternatywnym „książki”

    <img> z przygotowaną wcześniej grafiką. Atrybut alt czyta czytnik ekranu i pokazuje przeglądarka, gdy obraz się nie wczyta. Grafika leży w tym samym folderze co strona, więc w src wystarczy sama nazwa pliku.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  21. Krok 21: Panel prawy górny: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści „Dodaj czytelnika”

    Trzeci <h3> na stronie - wszystkie trzy dostaną to samo wyśrodkowanie jedną regułą CSS.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  22. Krok 22: Formularz wysyłany metodą POST do tej samej strony

    Kryteria:

    R.3.2 Dane z formularza przesyłane są za pomocą metody POST do tego samego pliku (poprawne również bez atrybutu action)

    ok. 1 min
    Polecenie z arkusza

    Formularz wysyłający dane do tego samego pliku metodą bezpieczną.

    „Metoda bezpieczna” w rozumieniu arkusza to post: dane jadą w treści żądania, a nie w adresie strony (jak przy get), więc nie zostają w historii przeglądarki. W specyfikacji HTTP „bezpieczne” są co prawda metody, które niczego nie zmieniają na serwerze (GET i HEAD), ale arkusz używa tego słowa w innym sensie, a klucz wymaga POST. „Do tego samego pliku” - action="biblioteka.php"; klucz uznaje też formularz bez atrybutu action, bo wtedy przeglądarka wysyła dane na bieżący adres.

    Typowe błędy

    Bez method="post" formularz wysyła dane metodą GET i Skrypt 2, który czyta $_POST, niczego nie dostanie.

    biblioteka.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
            </form>
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  23. Krok 23: Pole edycyjne „imię”

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne poprzedzone napisem „imię: ”

    <input type="text"> z nazwą name - pod tą nazwą wartość pola trafi do PHP. Napis i pole są w jednym <label>, więc kliknięcie w napis ustawia kursor w polu. <br> przenosi następne pole do nowej linii, jak na obrazie 2.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
            </form>
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  24. Krok 24: Pole edycyjne „nazwisko”

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne poprzedzone napisem „nazwisko: ”

    To samo co wyżej, nazwa pola surname.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
            </form>
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  25. Krok 25: Pole numeryczne „symbol”

    Kryteria:

    R.3.4 Pole edycyjne do wpisania symbolu jest typu numerycznego

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne typu numerycznego poprzedzone napisem „symbol: ”

    type="number" - przeglądarka przyjmuje tylko cyfry i pokazuje strzałki do zmiany wartości. Symbol trafi do kolumny kod, stąd nazwa pola code.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
            </form>
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  26. Krok 26: Przycisk DODAJ

    Kryteria: ,

    R.3.3 Przycisk w formularzu realizuje wysyłanie danych do skryptu (input lub button z typem submit lub button bez typu)

    R.2.7 W bloku prawym - górnym umieszczono formularz z trzema polami edycyjnymi i przyciskiem DODAJ

    ok. 1 min
    Polecenie z arkusza

    Przycisk DODAJ wysyłający dane z formularza

    <button type="submit"> wysyła formularz (to samo robi <input type="submit" value="DODAJ">). Formularz ma już trzy pola i przycisk - komplet do R.2.7.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  27. Krok 27: Panel prawy dolny: miejsce na Skrypt 2

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku prawego – dolnego: efekt działania skryptu 2

    Panel bottom-right zostaje na razie pusty - napis o dodanym czytelniku wypisze w nim Skrypt 2. Jest w kodzie od kroku z blokami, więc ten krok nie zmienia pliku.

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

  28. Krok 28: Stopka

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: paragraf (akapit) o treści „Projekt strony: ”, dalej wstawiony numer zdającego

    Akapit <p> w <footer>. Na egzaminie w miejscu imienia i nazwiska wpisuje się numer zdającego, czyli PESEL; w tym rozwiązaniu stoi tam „Bartosz Bryniarski”.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  29. Etap 3: Styl CSS

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

    Krok 29: Krój czcionki dla wszystkich elementów

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    Selektor uniwersalny * trafia w każdy element strony, także w pola formularza i przycisk (bez niego mają krój systemowy).

    style.css CSS nowy plik
    * {
        font-family: Verdana;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  30. Krok 30: Baner i stopka

    ok. 1 min
    Polecenie z arkusza

    Dla banera i stopki: kolor tła #004D40, biały kolor czcionki, marginesy wewnętrzne 10 px, wyrównanie tekstu do środka

    Jedna reguła z dwoma selektorami po przecinku - te same cztery właściwości dla header i footer. Marginesy wewnętrzne to padding.

    style.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  31. Krok 31: Panel lewy

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

    Dla panelu lewego: kolor tła #80CBC4, biały kolor czcionki, wysokość 500 px, szerokość 30%

    Selektor identyfikatora #left. Biały kolor czcionki mają już baner, stopka i panel lewy - komplet do R.4.3.

    style.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  32. Krok 32: Panel środkowy

    ok. 1 min
    Polecenie z arkusza

    Dla panelu środkowego: kolor tła #E0F2F1, wysokość 500 px, szerokość 30%, wyrównanie tekstu do środka

    text-align: center wyśrodkowuje też obraz, bo <img> zachowuje się jak słowo w linii tekstu.

    style.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    #middle {
        background-color: #E0F2F1;
        height: 500px;
        width: 30%;
        text-align: center;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  33. Krok 33: Oba panele prawe: wymiary

    Kryteria:

    R.4.5 Ustawiono szerokość panelu lewego i środkowego 30% oraz obu prawych 40%

    ok. 1 min
    Polecenie z arkusza

    Dla obu paneli prawych: wysokość 250 px, szerokość 40%

    Dwa panele po 250 px jeden nad drugim mają razem 500 px - tyle co lewy i środkowy. Szerokości: 30% + 30% + 40% = 100%, więc trzy kolumny zmieszczą się w jednym rzędzie (R.4.5).

    style.css CSS zmienione: 4 linie
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    #middle {
        background-color: #E0F2F1;
        height: 500px;
        width: 30%;
        text-align: center;
    }
    #top-right, #bottom-right {
        height: 250px;
        width: 40%;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  34. Krok 34: Panele prawe: kolory tła

    Kryteria:

    R.4.2 Ustawiono kolor tła dla banera i stopki na #004D40, panelu lewego #80CBC4, środkowego i prawego górnego #E0F2F1, prawego dolnego #B2DFDB

    ok. 1 min
    Polecenie z arkusza

    Kolory tła dla paneli prawych: prawego-górnego: #E0F2F1, prawego-dolnego: #B2DFDB

    Kolory różnią się, więc są dwie osobne reguły. Wszystkie kolory tła z arkusza są już ustawione (R.4.2).

    style.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    #middle {
        background-color: #E0F2F1;
        height: 500px;
        width: 30%;
        text-align: center;
    }
    #top-right, #bottom-right {
        height: 250px;
        width: 40%;
    }
    #top-right {
        background-color: #E0F2F1;
    }
    #bottom-right {
        background-color: #B2DFDB;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  35. Krok 35: Układ bloków zgodny z obrazem 2

    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 układające bloki na stronie, np. float i clear albo display z wartością flex lub grid albo position)

    ok. 3 min
    Polecenie z arkusza

    Podział zrealizowany za pomocą znaczników sekcji tak, aby wygląd układu bloków strony po uruchomieniu w przeglądarce, był zgodny z obrazem 2

    Wszystkie cztery sekcje dostają float: left. Lewy i środkowy stają obok siebie (60%), prawy górny zajmuje pozostałe 40%. Prawy dolny nie mieści się już w pierwszym rzędzie, więc przeglądarka opuszcza go niżej - do pierwszego miejsca, gdzie jest 40% wolnej szerokości, czyli tuż pod prawy górny (lewy i środkowy mają 500 px, prawy górny tylko 250 px). Stopka z clear: both zaczyna się dopiero pod wszystkimi pływającymi blokami. Tak powstaje układ z obrazu 2 bez żadnego dodatkowego pojemnika.

    Typowe błędy

    Panele nie mogą mieć marginesów ani obramowań poszerzających je poza 100% - wtedy prawy górny spadnie pod lewy.

    style.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    #middle {
        background-color: #E0F2F1;
        height: 500px;
        width: 30%;
        text-align: center;
    }
    #top-right, #bottom-right {
        height: 250px;
        width: 40%;
    }
    #top-right {
        background-color: #E0F2F1;
    }
    #bottom-right {
        background-color: #B2DFDB;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  36. Krok 36: Nagłówki trzeciego stopnia wyśrodkowane

    Kryteria:

    R.4.6 Ustawiono wyrównanie tekstu do środka dla banera, stopki, panelu środkowego i selektora h3

    ok. 1 min
    Polecenie z arkusza

    Dla selektora nagłówka trzeciego stopnia: wyrównanie tekstu do środka

    Selektor znacznika h3 - uwaga arkusza zabrania tu klasy i identyfikatora. Wyśrodkowane są już baner, stopka, panel środkowy i nagłówki (R.4.6).

    style.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    #middle {
        background-color: #E0F2F1;
        height: 500px;
        width: 30%;
        text-align: center;
    }
    #top-right, #bottom-right {
        height: 250px;
        width: 40%;
    }
    #top-right {
        background-color: #E0F2F1;
    }
    #bottom-right {
        background-color: #B2DFDB;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    h3 {
        text-align: center;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  37. Krok 37: Obraz: wysokość, kropkowane obramowanie i zaokrąglenie

    Kryteria: , ,

    R.4.4 Ustawiono wysokość panelu lewego i środkowego 500px, obu prawych 250px, selektora img 150px

    R.4.8 Ustawiono obramowanie obrazu 1px linią kropkowaną koloru #004D40

    R.4.9 Ustawiono zaokrąglenie rogów dla obramowania obrazu na 5px (np. border-radius)

    ok. 2 min
    Polecenie z arkusza

    Dla selektora obrazu: marginesy wewnętrzne 5 px, wysokość 150 px, obramowanie linią kropkowaną o grubości 1 px i kolorze #004D40 zaokrągloną na rogach o 5 px

    • height: 150px - szerokość przeliczy się sama w tej samej proporcji (300 × 235 → około 191 × 150),
    • padding: 5px - odstęp między grafiką a obramowaniem,
    • border: 1px dotted #004D40 - grubość, rodzaj linii (dotted = kropkowana) i kolor w jednej właściwości,
    • border-radius: 5px - zaokrąglenie rogów obramowania.

    Wszystkie wysokości z arkusza są ustawione (R.4.4).

    style.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    #middle {
        background-color: #E0F2F1;
        height: 500px;
        width: 30%;
        text-align: center;
    }
    #top-right, #bottom-right {
        height: 250px;
        width: 40%;
    }
    #top-right {
        background-color: #E0F2F1;
    }
    #bottom-right {
        background-color: #B2DFDB;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    h3 {
        text-align: center;
    }
    img {
        padding: 5px;
        height: 150px;
        border: 1px dotted #004D40;
        border-radius: 5px;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  38. Krok 38: Pola edycyjne: marginesy

    Kryteria:

    R.4.7 Ustawiono marginesy wewnętrzne (padding) 10px dla banera i stopki, 5px dla obrazu oraz marginesy zewnętrzne (margin) 10px dla selektora input

    ok. 1 min
    Polecenie z arkusza

    Dla selektora pola edycyjnego: marginesy zewnętrzne 10 px

    Selektor znacznika input - odstęp 10 px wokół każdego pola. Tym krokiem są wszystkie odstępy z arkusza: padding banera, stopki i obrazu oraz margin pól (R.4.7).

    style.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    header, footer {
        background-color: #004D40;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left {
        background-color: #80CBC4;
        color: white;
        height: 500px;
        width: 30%;
    }
    #middle {
        background-color: #E0F2F1;
        height: 500px;
        width: 30%;
        text-align: center;
    }
    #top-right, #bottom-right {
        height: 250px;
        width: 40%;
    }
    #top-right {
        background-color: #E0F2F1;
    }
    #bottom-right {
        background-color: #B2DFDB;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    h3 {
        text-align: center;
    }
    img {
        padding: 5px;
        height: 150px;
        border: 1px dotted #004D40;
        border-radius: 5px;
    }
    input {
        margin: 10px;
    }
    Podgląd strony po tym kroku (biblioteka.php)
  39. Etap 4: Skrypty PHP

    Kroki 39-44 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 39: Połączenie z bazą w Skrypcie 1, zamknięcie w Skrypcie 2

    Kryteria:

    R.5.1 Zastosowano funkcję realizującą połączenie z serwerem bazy danych na localhost, użytkownik root, bez hasła, baza danych biblioteka

    ok. 2 min
    Polecenie z arkusza

    Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie biblioteka

    Na stronie są dwa bloki PHP: Skrypt 1 wewnątrz listy <ol> w panelu lewym (to, co wypisze, znajdzie się między <ol> a </ol>) i Skrypt 2 w panelu prawym dolnym. mysqli_connect z czterema argumentami łączy się z serwerem i od razu wybiera bazę; uchwyt trafia do zmiennej $connection. Zmienne PHP żyją przez całą stronę, więc Skrypt 2 użyje tego samego połączenia i na końcu je zamknie. Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    biblioteka.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  40. Krok 40: Skrypt 1: zapytanie 1

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 1

    Zapytanie 1 bez zmian, w zmiennej $query. mysqli_query wysyła je do bazy, a w $result zostaje wynik do odczytania wiersz po wierszu. Strona jeszcze niczego nie wypisuje.

    biblioteka.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  41. Krok 41: Skrypt 1: autorzy jako elementy listy

    Kryteria: , ,

    R.5.3 Skrypt 1 wyświetla imiona i nazwiska autorów zwrócone zapytaniem 1

    R.5.4 Skrypt 1 generuje rekordy jako elementy listy z wykorzystaniem pętli

    R.2.6 W bloku lewym umieszczono jedną listę numerowaną, w kodzie HTML lub skrypcie, zastosowano znaczniki <ol>, <li>

    ok. 3 min
    Polecenie z arkusza

    Pobrane zapytaniem imiona i nazwiska autorów wypisywane są jako elementy listy numerowanej (uporządkowanej)

    mysqli_fetch_row oddaje kolejny wiersz jako tablicę numerowaną od zera w kolejności pól zapytania: $row[0] - imię, $row[1] - nazwisko. Po ostatnim wierszu zwraca null i pętla while się kończy. Każdy autor to jeden <li> - numery 1-10 dopisuje przeglądarka, bo elementy stoją w <ol>. Podgląd: lista z obrazu 2, od Jana Brzechwy do Magdaleny Witkiewicz.

    biblioteka.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0] $row[1]</li>";
                    }
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  42. Krok 42: Skrypt 2: dane z formularza

    Kryteria:

    R.5.6 Skrypt 2 zawiera instrukcję pobierającą dane z tablicy globalnej odpowiadającej zastosowanej metodzie formularza ($_POST, $_GET, $_REQUEST)

    ok. 2 min
    Polecenie z arkusza

    Pobiera dane z formularza

    Wysłany formularz PHP wkłada do tablicy $_POST: pod kluczem "name" jest imię, "surname" - nazwisko, "code" - symbol (klucze to atrybuty name pól). Przy pierwszym otwarciu strony tablica jest pusta, dlatego odczyt stoi w warunku isset($_POST["name"]) - bez niego PHP wypisałby ostrzeżenie „Undefined array key”. Podgląd: strona po wysłaniu formularza z danymi Anny Nowakowskiej; na razie nic się nie zmienia.

    biblioteka.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0] $row[1]</li>";
                    }
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                if (isset($_POST["name"])) {
                    $name = $_POST["name"];
                    $surname = $_POST["surname"];
                    $code = $_POST["code"];
                }
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  43. Krok 43: Skrypt 2: napis o dodanym czytelniku

    Kryteria:

    R.5.5 Skrypt 2 wyświetla napis: "Czytelnik <imie> <nazwisko> został(a) dodany do bazy danych" (gdzie pola <> są pobrane z formularza)

    ok. 1 min
    Polecenie z arkusza

    Wyświetla napis „Czytelnik <imie> <nazwisko> został(a) dodany do bazy danych” (gdzie pola <> są pobrane z formularza)

    W napisie w cudzysłowach PHP podstawia wartości zmiennych $name i $surname. Podgląd: „Czytelnik Anna Nowakowska został(a) dodany do bazy danych” w panelu prawym dolnym - jak na obrazie 2.

    biblioteka.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0] $row[1]</li>";
                    }
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                if (isset($_POST["name"])) {
                    $name = $_POST["name"];
                    $surname = $_POST["surname"];
                    $code = $_POST["code"];
                    echo "<p>Czytelnik $name $surname został(a) dodany do bazy danych</p>";
                }
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  44. Krok 44: Skrypt 2: zapytanie 2 z danymi z formularza

    Kryteria: ,

    R.5.7 Skrypt 2 dodaje do tabeli czytelnicy nowy rekord, zawierający dane pobrane z formularza. Należy sprawdzić w phpMyAdmin

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

    ok. 2 min
    Polecenie z arkusza

    Wysyła do bazy danych zmodyfikowane zapytanie 2 tak, że wstawia do bazy danych dane z formularza

    Zapytanie 2, w którym w miejsce „Ewa”, „Kowalska” i „145321” stoją zmienne. Apostrofy wokół zmiennych zostają - w SQL-u tekst musi być w apostrofach. INSERT nie zwraca wierszy, więc wyniku mysqli_query nie trzeba zapisywać. mysqli_close stoi za warunkiem, czyli wykonuje się zawsze i jest ostatnią operacją na bazie (R.5.2). Sprawdzenie, jak każe klucz: w phpMyAdmin w tabeli czytelnicy jest nowy wiersz z Anną Nowakowską.

    Typowe błędy

    Tabela czytelnicy z pliku arkusza ma zestaw znaków latin1 - polskie litery z formularza zapisują się jako „?” (sprawdzone: „Łucja Żak” → „?ucja ?ak”), choć napis na stronie jest poprawny. Na egzaminie nie zmieniaj struktury tabel z arkusza; poza egzaminem naprawia to ALTER TABLE czytelnicy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_polish_ci;.

    biblioteka.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0] $row[1]</li>";
                    }
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                if (isset($_POST["name"])) {
                    $name = $_POST["name"];
                    $surname = $_POST["surname"];
                    $code = $_POST["code"];
                    echo "<p>Czytelnik $name $surname został(a) dodany do bazy danych</p>";
                    $query = "INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES ('$name', '$surname', '$code');";
                    mysqli_query($connection, $query);
                }
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </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 37 z 37 kryteriów (pkt)

    Krok 45: Puste pola nie trafiają do bazy

    ok. 3 min
    Polecenie z arkusza

    Pobiera dane z formularza

    Wersja egzaminacyjna sprawdzona na pustym formularzu: kliknięcie DODAJ bez wpisywania czegokolwiek wypisuje „Czytelnik został(a) dodany do bazy danych” i naprawdę dodaje do tabeli czytelnicy wiersz z pustym imieniem, nazwiskiem i kodem - isset sprawdza tylko, czy pole przyszło, a puste pole też przychodzi. Poprawka: trim usuwa spacje z brzegów (sama spacja to też „nic”), a drugi warunek wypisuje „Wypełnij wszystkie pola formularza” i nie wysyła zapytania, gdy któreś pole jest puste. Podgląd: formularz wysłany ze spacją w polu imienia - tabela nadal ma 10 czytelników. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    biblioteka.php PHP zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0] $row[1]</li>";
                    }
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                if (isset($_POST["name"])) {
                    $name = trim($_POST["name"]);         // było: $name = $_POST["name"];
                    $surname = trim($_POST["surname"]);
                    $code = trim($_POST["code"]);
                    if ($name === "" || $surname === "" || $code === "") {
                        echo "<p>Wypełnij wszystkie pola formularza</p>";
                    } else {
                        echo "<p>Czytelnik $name $surname został(a) dodany do bazy danych</p>";
                        $query = "INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES ('$name', '$surname', '$code');";
                        mysqli_query($connection, $query);
                    }
                }
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  46. Krok 46: Zapytanie przygotowane: apostrof w nazwisku

    ok. 3 min
    Polecenie z arkusza

    Wysyła do bazy danych zmodyfikowane zapytanie 2 tak, że wstawia do bazy danych dane z formularza

    Drugi test wersji egzaminacyjnej: czytelniczka Kate O'Hara. Apostrof z nazwiska zamyka napis w SQL-u (VALUES ('Kate', 'O'Hara', '111')), zapytanie jest błędne, a PHP (od wersji 8.1 - także w XAMPP 8.1.2 z klucza) zgłasza wyjątek mysqli_sql_exception i przerywa stronę w połowie: znika reszta panelu i stopka. Ten sam mechanizm pozwala wpisać w pole fragment SQL-a (wstrzyknięcie). Zapytanie przygotowane usuwa przyczynę: mysqli_prepare wysyła zapytanie ze znakami ?, a mysqli_stmt_bind_param z typami "sss" (trzy teksty) dokłada wartości osobno - baza nigdy nie czyta ich jako kodu SQL. Stare linie zostają w komentarzu. Podgląd: O'Hara zapisana poprawnie. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    biblioteka.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0] $row[1]</li>";
                    }
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                if (isset($_POST["name"])) {
                    $name = trim($_POST["name"]);         // było: $name = $_POST["name"];
                    $surname = trim($_POST["surname"]);
                    $code = trim($_POST["code"]);
                    if ($name === "" || $surname === "" || $code === "") {
                        echo "<p>Wypełnij wszystkie pola formularza</p>";
                    } else {
                        echo "<p>Czytelnik $name $surname został(a) dodany do bazy danych</p>";
                        $statement = mysqli_prepare($connection, "INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES (?, ?, ?)");
                        mysqli_stmt_bind_param($statement, "sss", $name, $surname, $code);
                        mysqli_stmt_execute($statement);
                        // $query = "INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES ('$name', '$surname', '$code');";
                        // mysqli_query($connection, $query);
                    }
                }
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  47. Krok 47: htmlspecialchars w napisie z formularza

    ok. 2 min
    Polecenie z arkusza

    Wyświetla napis „Czytelnik <imie> <nazwisko> został(a) dodany do bazy danych” (gdzie pola <> są pobrane z formularza)

    Napis składa się z tego, co ktoś wpisał w formularz. Gdy w polu imienia stanie znacznik HTML (np. <b>Jan</b> albo <script>), wersja egzaminacyjna wklei go do strony jako kod. htmlspecialchars zamienia znaki <, >, & i cudzysłowy na encje, więc przeglądarka pokaże je jako zwykły tekst. Do bazy dane trafiają bez zmian - zamiana dotyczy tylko wypisywania. Podgląd: znów Anna Nowakowska. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    biblioteka.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Biblioteka publiczna</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header>
            <h1>Biblioteka w Książkowicach Wielkich</h1>
        </header>
        <section id="left">
            <h3>Polecamy dzieła autorów:</h3>
            <ol>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biblioteka");
                    $query = "SELECT imie, nazwisko FROM autorzy ORDER BY nazwisko;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0] $row[1]</li>";
                    }
                ?>
            </ol>
        </section>
        <section id="middle">
            <h3>ul. Czytelnicza 25, Książkowice&nbsp;Wielkie</h3>
            <p><a href="mailto:[email protected]">Napisz do nas</a></p>
            <img src="biblioteka.png" alt="książki">
        </section>
        <section id="top-right">
            <h3>Dodaj czytelnika</h3>
            <form method="post" action="biblioteka.php">
                <label>imię: <input type="text" name="name"></label><br>
                <label>nazwisko: <input type="text" name="surname"></label><br>
                <label>symbol: <input type="number" name="code"></label><br>
                <button type="submit">DODAJ</button>
            </form>
        </section>
        <section id="bottom-right">
            <?php
                if (isset($_POST["name"])) {
                    $name = trim($_POST["name"]);         // było: $name = $_POST["name"];
                    $surname = trim($_POST["surname"]);
                    $code = trim($_POST["code"]);
                    if ($name === "" || $surname === "" || $code === "") {
                        echo "<p>Wypełnij wszystkie pola formularza</p>";
                    } else {
                        $reader = htmlspecialchars("$name $surname");
                        echo "<p>Czytelnik $reader został(a) dodany do bazy danych</p>";
                        // echo "<p>Czytelnik $name $surname został(a) dodany do bazy danych</p>";
                        $statement = mysqli_prepare($connection, "INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES (?, ?, ?)");
                        mysqli_stmt_bind_param($statement, "sss", $name, $surname, $code);
                        mysqli_stmt_execute($statement);
                        // $query = "INSERT INTO czytelnicy (imie, nazwisko, kod) VALUES ('$name', '$surname', '$code');";
                        // mysqli_query($connection, $query);
                    }
                }
                mysqli_close($connection);
            ?>
        </section>
        <footer>
            <p>Projekt strony: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (biblioteka.php)
  48. Etap 6: Oddanie pracy

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

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

    ok. 5 min
    Polecenie z arkusza

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

    W przeglądarka.txt wystarczy nazwa przeglądarki, w której była sprawdzana strona.

    W folderze z numerem zdającego: biblioteka.php, biblioteka.png, import.jpg, kwerenda1.jpg - kwerenda4.jpg, kwerendy.txt, przeglądarka.txt i style.css. Po nagraniu płyty trzeba sprawdzić jej odczyt i opisać 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.