INF.03-03-25.06-SGCzerwiec 2025 · 42 kroki · ok. 94 min · 36 kryteriów z klucza
Rozwiązanie krok po kroku: Portal biblioteki szkolnej (Wersja podstawowa)
Rozwiązanie buduje portal biblioteki szkolnej: baza biblioteka z czterema kwerendami (w tym DELETE i losowanie ORDER BY RAND()), trzy okładki JPEG z pasem książek i tekstem, strona biblioteka.php z tabelą wypełnianą przez PHP i trzema artykułami, style w styles.css z zapytaniami @media oraz skrypt PHP, który wpisuje pięć losowych książek do tabeli.
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ą. Kod PHP jest najpierw pisany funkcjami z tabeli 1 arkusza (proceduralne mysqli), a na końcu zostaje przerobiony na wersję z prawdziwych projektów: nazwy kolumn zamiast numerów, escapowanie danych przed wypisaniem i oddzielenie pracy z bazą od HTML. W tym arkuszu nie ma JavaScriptu.
Obok jest druga wersja tego rozwiązania - zakładka Nowoczesny kod (grid, PDO): te same punkty, ale artykuły na siatce CSS, kolory w zmiennych, PHP na PDO z obsługą błędu i wypisywaniem przez htmlspecialchars od pierwszej linijki.
Grafiki, baza i plik teksty.txt pochodzą z prawdziwego archiwum pliki12 (załącznik do pobrania na stronie arkusza, hasło w treści zadania). Okładki są złożone z plików archiwum tak, jak każe arkusz; zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu.
Jak liczą się punkty. Klucz ma 36 kryteriów (R.1.1 - R.5.6), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 27 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.
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Baza danych
Kroki 1-7 · po tym etapie masz 6 z 36 kryteriów (pkt)
Krok 1: Baza danych biblioteka
Kryteria:
R.1.1 Wykonany import tabeli do bazy danych biblioteka , czynność udokumentowana w pliku import.png
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie biblioteka, z zestawem polskich znaków (np. utf8_unicode_ci).
W przeglądarce otwierasz http://localhost/phpmyadmin, klikasz Nowa w lewym panelu, wpisujesz nazwę biblioteka i z listy metod porównywania wybierasz utf8_unicode_ci (arkusz podaje ją jako przykład; utf8_polish_ci też jest poprawne). Tabele z pliku SQL mają jednak zestaw utf8mb4 zapisany we własnej definicji, więc nazwiska i tytuły („Woźniak”, „Ślimak i róża”) zachowają ogonki przy każdym wyborze - ustawienie bazy dziedziczą tylko tabele zakładane później bez własnego ustawienia.
Typowe błędy
Nazwa bazy musi być dokładnie biblioteka - skrypt PHP łączy się z bazą po nazwie, więc literówka odetnie punkty także za skrypt (R.5.2).
Krok 2: Import tabel z pliku baza.sql
Kryteria:
R.1.1 Wykonany import tabeli do bazy danych biblioteka , czynność udokumentowana w pliku import.png
ok. 3 min
Polecenie z arkusza
Z rozpakowanego archiwum zaimportuj tabelę z pliku baza.sql do utworzonej bazy.
Wejdź do bazy biblioteka (musi być zaznaczona w lewym panelu), karta Import, Wybierz plik → baza.sql z rozpakowanego archiwum, Wykonaj. Plik ma prawie 400 kB - import chwilę trwa.
Po imporcie są dwie tabele z ilustracji 1: ksiazki (id, autor, tytul, kod, data_dodania - 5381 wierszy, cały katalog) i uczniowie (id, nazwisko, imie, klasa, data_wypozyczenia, id_ksiazki - 15 wierszy). Kolumna id_ksiazki to klucz obcy do ksiazki.id - uczeń, który nic nie wypożyczył, ma tam NULL i datę 0000-00-00.
Typowe błędy
Import bez wcześniejszego wejścia do bazy biblioteka tworzy tabele w innej bazie (np. test) - skrypt nie znajdzie wtedy tabeli ksiazki.
Krok 3: Zrzut ekranu import.png
Kryteria:
R.1.1 Wykonany import tabeli do bazy danych biblioteka , czynność udokumentowana w pliku 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ń.
Klawisz Print Screen (cały ekran, nie Alt+PrtScr, który łapie tylko aktywne okno), wklejasz do edytora grafiki i zapisujesz jako import.png w folderze z numerem zdającego. Na zrzucie ma być widać komunikat phpMyAdmin o pomyślnym imporcie albo obie tabele w bazie. W tym arkuszu wszystkie zrzuty (import i kwerendy) są w PNG.
Typowe błędy
Wykadrowany zrzut (samo okno przeglądarki, bez paska zadań) nie jest oceniany - klucz mówi to wprost.
Krok 4: Zapytanie 1: wypożyczenia po 2 marca 2020
Kryteria: ,
R.1.2 Zapisany plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonane zapytanie 1 wybierające jedynie nazwisko, imię, klasę i datę wypożyczenia uczniów, dla których data wypożyczenia jest późniejsza niż 2020-03-02. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwisko, imie, klasa, data_wypozyczenia FROM uczniowie WHERE data_wypozyczenia > '2020-03-02'; (data zapisana 02-03-2020 jest błędem) oraz wynik działania zapytania udokumentowany zrzutem, na którym widocznych jest dokładnie 5 rekordów zawierających jedynie pola nazwisko, imie, klasa, data_wypozyczenia (nazwiska: pierwsze Woźniak, ostatnie Kawtan)
ok. 3 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie nazwisko, imię, klasę i datę wypożyczenia dla uczniów, dla których data wypożyczenia jest późniejsza niż 2020-03-02.
Zakładka SQL w phpMyAdmin (przy zaznaczonej bazie biblioteka). Klauzula po klauzuli:
SELECT nazwisko, imie, klasa, data_wypozyczenia - dokładnie cztery kolumny z arkusza; SELECT * dołożyłby id i id_ksiazki.
FROM uczniowie - wszystkie te dane są w jednej tabeli, złączenie nie jest potrzebne.
WHERE data_wypozyczenia > '2020-03-02' - „późniejsza niż” to > (bez =, 2 marca odpada). Datę zapisujesz w apostrofach w formacie RRRR-MM-DD, czyli tak, jak trzyma ją baza - klucz wprost mówi, że 02-03-2020 jest błędem.
Wynik: dokładnie 5 wierszy, od Woźniak (4 marca) do Kawtan (18 marca). Zapytanie kopiujesz do pliku kwerendy.txt i robisz zrzut całego ekranu: kw1.png.
Typowe błędy
>= '2020-03-02' dołoży Krakowiaka i Ordak z 2 marca - 7 wierszy zamiast 5. „Późniejsza niż” wyklucza tę datę.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT nazwisko, imie, klasa, data_wypozyczenia FROM uczniowie WHERE data_wypozyczenia > '2020-03-02';
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: kto co wypożyczył
Kryteria:
R.1.4 Wykonane zapytanie 2 wybierające jedynie nazwisko, imię, datę wypożyczenia oraz odpowiadające im autora i kod książki wypożyczonej przez ucznia. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwisko, imie, data_wypozyczenia, autor, kod FROM uczniowie INNER JOIN ksiazki ON uczniowie.id_ksiazki = ksiazki.id; (możliwe samo JOIN, również z przyrównaniem kluczy po WHERE) oraz wynik działania zapytania udokumentowany zrzutem, na którym widocznych jest dokładnie 7 rekordów dla kodów 2711, 271C, 2719, 277D, 2735, 2739, 2727
ok. 4 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie nazwisko, imię i datę wypożyczenia oraz odpowiadające im pola autor i kod książki wypożyczonej przez ucznia. Należy posłużyć się relacją.
Nazwisko i data są w uczniowie, autor i kod w ksiazki - „posłużyć się relacją” znaczy złączyć tabele po kluczu.
SELECT nazwisko, imie, data_wypozyczenia, autor, kod - trzy kolumny z jednej tabeli, dwie z drugiej.
FROM uczniowie JOIN ksiazki ON ksiazki.id = uczniowie.id_ksiazki - do każdego ucznia dokładasz wiersz książki, której id równa się jego id_ksiazki. Nazwy kolumn poprzedzasz tabelą, bo id jest w obu tabelach. Uczniowie bez książki (id_ksiazki równe NULL) nie mają pary, więc znikają z wyniku - i o to chodzi.
JOIN bez ON daje iloczyn kartezjański: 15 · 5381 wierszy. Klucz przyjmuje też INNER JOIN (to samo co JOIN) i starszy zapis FROM uczniowie, ksiazki WHERE ksiazki.id = id_ksiazki.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT nazwisko, imie, klasa, data_wypozyczenia FROM uczniowie WHERE data_wypozyczenia > '2020-03-02';-- Zapytanie 2SELECT nazwisko, imie, data_wypozyczenia, autor, kod FROM uczniowie JOIN ksiazki ON ksiazki.id = uczniowie.id_ksiazki;
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: usunięcie książek bez autora
Kryteria:
R.1.5 Wykonane zapytanie 3 usuwające wszystkie rekordy tabeli ksiazki, w których autorowi została przypisana wartość ‘0’ . W pliku z kwerendami lub na zrzucie istnieje zapis np.: DELETE FROM ksiazki WHERE autor = '0'; oraz wynik działania zapytania udokumentowany zrzutem, na którym widoczny jest komunikat o poprawnym usunięciu 621 rekordów lub widoczna tabela z usuniętymi rekordami
ok. 3 min
Polecenie z arkusza
Zapytanie 3: usuwające wszystkie rekordy tabeli ksiazki, w których autorowi została przypisana wartość '0'.
DELETE FROM ksiazki WHERE autor = '0' - usuwanie wierszy to DELETE FROM z nazwą tabeli (bez listy kolumn - usuwa się całe wiersze), a WHERE mówi które. Kolumna autor jest tekstowa, więc zero porównujesz jako napis w apostrofach, dokładnie tak jak w arkuszu.
phpMyAdmin zapyta o potwierdzenie - to normalne przy DELETE. Wynik: komunikat o usunięciu 621 rekordów (w tabeli zostaje 4760). Zrzut kw3.png ma pokazać ten komunikat.
Typowe błędy
DELETE FROM ksiazki bez WHERE kasuje cały katalog (5381 wierszy) - i nie ma cofania. Przy DELETE zawsze najpierw uruchom SELECT z tym samym WHERE, żeby zobaczyć, co zniknie.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT nazwisko, imie, klasa, data_wypozyczenia FROM uczniowie WHERE data_wypozyczenia > '2020-03-02';-- Zapytanie 2SELECT nazwisko, imie, data_wypozyczenia, autor, kod FROM uczniowie JOIN ksiazki ON ksiazki.id = uczniowie.id_ksiazki;-- Zapytanie 3DELETE FROM ksiazki WHERE autor = '0';
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: pięć losowych książek
Kryteria:
R.1.6 Wykonane zapytanie 4 wybierające losowo dokładnie pięć rekordów z całej tabeli ksiazki zawierających jedynie pola autor, tytul i kod. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5; oraz wynik działania zapytania udokumentowany zrzutem, na którym widocznych jest dokładnie 5 rekordów zawierających jedynie pola autor, tytul i kod
ok. 3 min
Polecenie z arkusza
Zapytanie 4: wybierające losowo dokładnie pięć rekordów z całej tabeli ksiazki zawierających jedynie pola autor, tytul i kod.
SELECT autor, tytul, kod FROM ksiazki - trzy kolumny z katalogu.
ORDER BY RAND() - funkcja RAND() daje dla każdego wiersza losową liczbę, a sortowanie po niej tasuje wiersze. Każde uruchomienie daje inną kolejność.
LIMIT 5 - pięć pierwszych po potasowaniu, czyli pięć losowych.
Wynik: 5 wierszy, za każdym razem innych. Zrzut: kw4.png. To zapytanie wyśle skrypt PHP - dlatego tabela na stronie zmienia się po każdym odświeżeniu. Plik kwerendy.txt ma komplet czterech zapytań.
Typowe błędy
LIMIT 5 bez ORDER BY RAND() zwraca zawsze te same pięć pierwszych książek - to nie jest losowanie. ORDER BY RAND() na dużej tabeli jest wolne, ale przy 4760 wierszach nie ma to znaczenia.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT nazwisko, imie, klasa, data_wypozyczenia FROM uczniowie WHERE data_wypozyczenia > '2020-03-02';-- Zapytanie 2SELECT nazwisko, imie, data_wypozyczenia, autor, kod FROM uczniowie JOIN ksiazki ON ksiazki.id = uczniowie.id_ksiazki;-- Zapytanie 3DELETE FROM ksiazki WHERE autor = '0';-- Zapytanie 4SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-22 · po tym etapie masz 17 z 36 kryteriów (pkt)
Krok 8: Okładki: pas książek na górze i dole, zapis w JPEG
Kryteria:
R.2.1 Motywy książek z grafiki ksiazki.png umieszczone na dole i górze przynajmniej jednej grafiki JPEG z ksiazka1 , ksiazka2 , ksiazka3 . Motyw w całości mieści się w wymiarach książki
ok. 8 min
Polecenie z arkusza
Grafiki ksiazka1, ksiazka2, ksiazka3 zapisane w formacie JPEG. Grafiki ksiazka1.jpg, ksiazka2.jpg, ksiazka3.jpg przekształcone poprzez wklejenie na pierwszy plan książek z pliku ksiazki.png na dole i górze obrazu, powinny one w całości zmieścić się w wymiarach obrazu, patrz ilustracja 2.
W archiwum są trzy pliki PNG 350 × 480 px z kolorowym polem i szeroki pas książek ksiazki.png (1799 × 314 px). W edytorze grafiki rastrowej (np. GIMP) dla każdej okładki:
otwierasz ksiazka1.png, a pas książek wczytujesz jako nową warstwę (Plik → Otwórz jako warstwy),
skalujesz warstwę do szerokości ok. 330 px (Warstwa → Skaluj warstwę, z zachowaniem proporcji) - musi się w całości zmieścić w 350 px szerokości obrazu,
przesuwasz ją na górę, duplikujesz warstwę i drugą kopię przesuwasz na dół,
eksportujesz jako ksiazka1.jpg (Plik → Wyeksportuj jako, rozszerzenie .jpg).
To samo dla ksiazka2 i ksiazka3. Klucz R.2.1 sprawdza przynajmniej jedną okładkę, ale strona potrzebuje trzech.
Typowe błędy
Pas książek wklejony w pełnej szerokości 1799 px wystaje poza obraz - klucz wymaga, żeby motyw w całości mieścił się w wymiarach okładki. Zapis .png zamiast .jpg to brak pliku, do którego odwoła się strona.
Podgląd strony po tym kroku
Krok 9: Okładki: autor i tytuł czcionką szeryfową
Kryteria:
R.2.2 Na przynajmniej jednej grafice umieszczony autor i tytuł. Zastosowana czcionka szeryfowa, tytuły zostały pogrubione
ok. 6 min
Polecenie z arkusza
W grafice ksiazka1.jpg w niebieskim polu umieszczony tekst „HANS CHRISTIAN ANDERSEN Ropucha”. W grafice ksiazka2.jpg w zielonym polu umieszczony tekst „MARIA KONOPNICKA Przygoda z lalką”. W grafice ksiazka3.jpg w fioletowym polu umieszczony tekst „IGNACY KRASICKI Przyjaciel”. Tekst zapisany jest czcionką szeryfową, tytuł jest dodatkowo pogrubiony.
Narzędzie Tekst w GIMP-ie, klik w kolorowe pole. Czcionka szeryfowa to np. Times New Roman albo Georgia (litery mają „stopki”; Arial i Verdana są bezszeryfowe - to byłby błąd). Autor wielkimi literami, jak w arkuszu; tytuł w osobnej linii z wariantem Bold. Tekst musi mieścić się w polu - na ilustracji 2 autor jest w dwóch liniach.
Po dodaniu tekstu eksportujesz jeszcze raz do .jpg. Klucz R.2.2 sprawdza czcionkę szeryfową i pogrubienie tytułu na przynajmniej jednej okładce.
Typowe błędy
Cały tekst pogrubiony albo cały zwykły - arkusz mówi „tytuł dodatkowo pogrubiony”, więc autor zwykły, tytuł bold. Domyślna czcionka GIMP-a (Sans) jest bezszeryfowa.
Podgląd strony po tym kroku
Krok 10: Plik biblioteka.php w HTML5
Kryteria:
R.2.3 W pliku biblioteka.php zapisana deklaracja HTML5 <!DOCTYPE HTML>, deklaracja języka zawartości: polski np. <html lang="pl">, w sekcji head znajduje się jawnie podany standard kodowania polskich znaków
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie biblioteka.php. Zapisana w języku HTML5.
W edytorze zaznaczającym składnię tworzysz plik biblioteka.php w folderze zdającego, obok okładek. Rozszerzenie .php, bo dojdzie skrypt PHP - na razie to czysty HTML.
Pierwsza linia <!DOCTYPE html> mówi przeglądarce, że dokument jest w HTML5. Dalej szkielet każdej strony: <html>, a w nim <head> (informacje o stronie) i <body> (to, co widać w oknie).
R.2.3 W pliku biblioteka.php zapisana deklaracja HTML5 <!DOCTYPE HTML>, deklaracja języka zawartości: polski np. <html lang="pl">, w sekcji head znajduje się jawnie podany standard kodowania polskich znaków
ok. 1 min
Polecenie z arkusza
Zadeklarowany polski język zawartości witryny.
Atrybut lang="pl" w znaczniku <html>. Czytnik ekranu czyta wtedy tekst polską wymową, a przeglądarka dobiera słownik. Na stronie nic się nie zmienia - to informacja dla programów.
R.2.3 W pliku biblioteka.php zapisana deklaracja HTML5 <!DOCTYPE HTML>, deklaracja języka zawartości: polski np. <html lang="pl">, w sekcji head znajduje się jawnie podany 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 pierwsza rzecz w <head>. „Jawnie” znaczy: wpisane w kodzie, nie zdane na domysł przeglądarki. Bez tej linii tytuły z bazy („Ślimak i róża”) mogłyby wyświetlić się jako krzaki. Plik trzeba też zapisać w UTF-8.
Tytuł strony „BIBLIOTEKA SZKOLNA” widoczny na karcie przeglądarki.
<title> w <head> - napis na karcie przeglądarki, nie nagłówek na stronie. Klucz R.2.4 sprawdza tekst „BIBLIOTEKA SZKOLNA” (wielkość liter klucz toleruje, ale przepisujesz dokładnie).
R.3.2 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styles.css formatowanie CSS pochodzi jedynie z tego arkusza
ok. 1 min
Polecenie z arkusza
Arkusz stylów w pliku o nazwie styles.css prawidłowo połączony z kodem strony.
<link rel="stylesheet" href="styles.css"> w <head>. Uwaga na nazwę: w tym arkuszu to styles.css (z „s” na końcu), nie styl.css jak w wielu innych - klucz R.3.2 sprawdza dokładnie tę nazwę. Plik napiszesz po HTML.
Typowe błędy
href="styl.css" z przyzwyczajenia po innych arkuszach - przeglądarka nie znajdzie pliku i cały rezultat R.4 przepada, bo „formatowanie CSS pochodzi jedynie z tego arkusza”.
R.2.5 W sekcji body zdefiniowany jest podział na bloki za pomocą semantycznych znaczników HTML 5: header, section, main -> article + article + article, footer
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ą 3.
Z ilustracji 3: blok nagłówkowy, pod nim blok sekcji, potem blok główny z trzema blokami artykułu obok siebie, na dole stopka. Klucz R.2.5 wymienia znaczniki wprost: <header>, <section>, <main> z trzema <article> w środku, <footer>.
Artykuły dostają identyfikatory book1, book2, book3, bo każdy będzie miał inny kolor tła. Nazwy identyfikatorów, klas i zmiennych piszesz w tym rozwiązaniu po angielsku (arkusz dopuszcza polski lub angielski, wymaga konsekwencji); wyjątkiem są nazwy narzucone przez arkusz (biblioteka.php, styles.css, kolumny bazy). To, że artykuły staną obok siebie, zrobi CSS.
Typowe błędy
Artykuły poza <main> (np. bezpośrednio w <body>) nie spełniają R.2.5 - klucz mówi „main → article + article + article”, czyli artykuły wewnątrz bloku głównego.
R.2.6 Zapisane w bloku nagłówkowym <h2>: "STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN", w bloku sekcji <h3>: "Nasze dzisiejsze propozycje:" oraz paragraf w przynajmniej jednym bloku artykułu
ok. 1 min
Polecenie z arkusza
Zawartość bloku nagłówkowego: nagłówek drugiego stopnia o treści: „STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN”.
Drugiego stopnia to <h2>. Treść kopiujesz z pierwszej linii teksty.txt - arkusz mówi wprost, że teksty można stamtąd skopiować, więc nie przepisujesz ich ręcznie.
R.2.6 Zapisane w bloku nagłówkowym <h2>: "STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN", w bloku sekcji <h3>: "Nasze dzisiejsze propozycje:" oraz paragraf w przynajmniej jednym bloku artykułu
ok. 1 min
Polecenie z arkusza
Zawartość sekcji: nagłówek trzeciego stopnia o treści: „Nasze dzisiejsze propozycje:”.
<h3> w <section>, z dwukropkiem, jak w arkuszu i w teksty.txt.
R.2.9 W bloku sekcji umieszczono tabelę o 3 kolumnach (w skrypcie lub HTML) zastosowane znaczniki <table>, <tr>, <td>
R.2.10 Pierwszy wiersz tabeli zawiera komórki nagłówkowe, zastosowane znaczniki <tr>, <th>
ok. 2 min
Polecenie z arkusza
Tabela o trzech kolumnach, w której pierwszy wiersz zawiera komórki nagłówkowe o treści: Autor, Tytuł, Katalog. Tabela jest wypełniona przez skrypt.
<table> z jednym wierszem <tr>, w którym są komórki nagłówkowe<th> - nie <td>. To osobne kryterium (R.2.10) i częsta strata punktu. Kolejne wiersze z książkami dopisze skrypt PHP, więc w HTML jest tylko nagłówek.
R.2.7 W przynajmniej jednym bloku artykułu umieszczony obraz ksiazka1 lub ksiazka2 , lub ksiazka3. Obraz ma tekst alternatywny "okładka książki"
ok. 1 min
Polecenie z arkusza
Zawartość bloku głównego: trzy bloki artykułu. W każdym bloku artykułu znajdują się: grafika, kolejno ksiazka1.jpg, ksiazka2.jpg, ksiazka3.jpg z tekstami alternatywnymi o treści „okładka książki”.
<img src="ksiazka1.jpg" alt="okładka książki"> w pierwszym artykule - to plik JPEG złożony w etapie grafiki, leżący obok biblioteka.php. Tekst alternatywny jest ten sam dla wszystkich trzech okładek, dokładnie z arkusza. W podglądzie obraz ma na razie naturalny rozmiar 350 × 480 px - szerokość ustawi CSS.
Typowe błędy
src="ksiazka1.png" wskazuje plik źródłowy z archiwum, nie przerobioną okładkę - strona pokaże pustą okładkę bez książek i tekstu.
R.2.6 Zapisane w bloku nagłówkowym <h2>: "STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN", w bloku sekcji <h3>: "Nasze dzisiejsze propozycje:" oraz paragraf w przynajmniej jednym bloku artykułu
ok. 1 min
Polecenie z arkusza
Paragraf zawierający odpowiedni tekst streszczenia - patrz ilustracja 2 oraz plik teksty.txt.
<p> pod obrazem, z tekstem skopiowanym z teksty.txt - zdanie pod „Hans Christian Andersen - Ropucha”. Kopiuj (Ctrl+C / Ctrl+V), nie przepisuj: wielokropek i przecinki mają się zgadzać. Klucz R.2.6 wymaga paragrafu w przynajmniej jednym artykule.
R.2.6 Zapisane w bloku nagłówkowym <h2>: "STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN", w bloku sekcji <h3>: "Nasze dzisiejsze propozycje:" oraz paragraf w przynajmniej jednym bloku artykułu
R.2.7 W przynajmniej jednym bloku artykułu umieszczony obraz ksiazka1 lub ksiazka2 , lub ksiazka3. Obraz ma tekst alternatywny "okładka książki"
ok. 2 min
Polecenie z arkusza
Grafika, kolejno ksiazka1.jpg, ksiazka2.jpg, ksiazka3.jpg z tekstami alternatywnymi o treści „okładka książki”. Paragraf zawierający odpowiedni tekst streszczenia.
Ten sam wzorzec dla book2 (Konopnicka) i book3 (Krasicki): obraz z kolejnym numerem i paragraf ze streszczeniem z teksty.txt. Kolejność artykułów odpowiada kolejności okładek i tekstów w pliku.
biblioteka.phpPHPzmienione: 4 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> </footer></body></html>
Podgląd strony po tym kroku (biblioteka.php)
Krok 22: Stopka z numerem zdającego
Kryteria:
R.2.8 W bloku stopki wstawiony został numer zdającego
ok. 1 min
Polecenie z arkusza
Zawartość stopki: napis „Stronę wykonał: ”, dalej wstawiony numer zdającego.
Napis w <footer> - dajesz go w paragrafie <p>, choć arkusz nie wymaga tu konkretnego znacznika. W tym rozwiązaniu po dwukropku stoi nazwisko autora - na egzaminie wpisujesz swój numer zdającego (PESEL), bo tego sprawdza klucz R.2.8. Struktura HTML strony jest kompletna - dalej style.
biblioteka.phpPHPzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (biblioteka.php)
Etap 3: Styl CSS
Kroki 23-33 · po tym etapie masz 30 z 36 kryteriów (pkt)
Krok 23: Plik styles.css: krój czcionki i wyrównanie
Kryteria:
R.4.1 Ustawione domyślne formatowanie wszystkich selektorów (*): krój czcionki Roboto, w przypadku jego braku Arial, sans-serif, wyrównanie tekstu do środka
ok. 2 min
Polecenie z arkusza
Domyślnie dla wszystkich selektorów: krój czcionki: Roboto, w przypadku jego braku Arial, sans-serif, wyrównanie tekstu do środka.
Utwórz plik styles.css obok biblioteka.php. „Wszystkie selektory” to selektor uniwersalny *. font-family przyjmuje listę krojów po przecinku: przeglądarka bierze pierwszy, który ma zainstalowany - Roboto, a gdy go brak, Arial, a w ostateczności dowolną czcionkę bezszeryfową (sans-serif). Arkusz podaje tę kolejność wprost. text-align: center wyśrodkowuje cały tekst strony.
Typowe błędy
font-family: Roboto bez zapasowych krojów - na komputerze egzaminatora bez Roboto strona pokaże domyślną czcionkę przeglądarki (szeryfową), a klucz R.4.1 wymienia całą listę.
R.4.2 Ustawiony kolor tła LightCyan dla selektora body
ok. 1 min
Polecenie z arkusza
Dla selektora ciała strony: kolor tła LightCyan.
Selektor znacznika body - arkusz podkreśla na stronie 5, że tło ciała strony ma być ustawione wyłącznie selektorem znacznika, nie klasą ani id. Tło całego okna robi się jasnobłękitne.
Krok 25: Nagłówek i stopka: tło, kolor tekstu, margines wewnętrzny
Kryteria: , ,
R.4.3 Ustawiony kolor tła bloku nagłówkowego i stopki SteelBlue, pierwszy blok artykułu DodgerBlue, drugi - LimeGreen, trzeci - DarkOrchid
R.4.4 Ustawiony dla bloku nagłówkowego i stopki biały kolor czcionki
R.4.7 Ustawione marginesy wewnętrzne (padding) 10px dla bloków nagłówkowego i stopki, 20px dla selektora paragrafu oraz margines górny (padding-top) 40px dla trzech bloków artykułu
ok. 1 min
Polecenie z arkusza
Dla bloku nagłówkowego i stopki: kolor tła SteelBlue, biały kolor czcionki, marginesy wewnętrzne 10 px.
Wspólne cechy dwóch bloków piszesz raz - selektory po przecinku header, footer. Margines wewnętrzny to padding (zewnętrzny byłby margin). Nagłówek i stopka stają się stalowoniebieskimi pasami z białym tekstem, jak na ilustracji 2.
Krok 26: Artykuły: margines górny wewnętrzny i marginesy zewnętrzne
Kryteria: ,
R.4.7 Ustawione marginesy wewnętrzne (padding) 10px dla bloków nagłówkowego i stopki, 20px dla selektora paragrafu oraz margines górny (padding-top) 40px dla trzech bloków artykułu
R.4.8 Ustawione marginesy zewnętrzne (margin) 1% dla trzech bloków artykułu, auto dla tabeli
ok. 1 min
Polecenie z arkusza
Dla wszystkich bloków artykułu: margines wewnętrzny górny 40 px, marginesy zewnętrzne 1%.
Selektor znacznika article obejmuje wszystkie trzy bloki. padding-top: 40px to margines wewnętrzny tylko z góry (miejsce nad okładką), margin: 1% - odstęp zewnętrzny z każdej strony, liczony od szerokości rodzica. Układ obok siebie zrobisz w następnych dwóch krokach.
Krok 27: Szerokie ekrany: trzy artykuły obok siebie
Kryteria: , ,
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 3 w arkuszu egzaminacyjnym dla szerokości powyżej 800 px (prawidłowo zastosowane 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)
R.3.4 Po zwiększeniu szerokości okna przeglądarki jedynie dla 800 px i powyżej bloki w bloku głównym są ustawione obok siebie
R.4.5 Zdefiniowane reguły @media dla trzech bloków artykułu: dla reguły szerokości ekranu 800px i więcej - szerokość bloku 30% w przeciwnym przypadku szerokość bloku 98% (width lub grid-template-columns lub flex)
ok. 3 min
Polecenie z arkusza
Gdy szerokość ekranu wynosi 800 px i więcej, trzy bloki są wyświetlane obok siebie, ich szerokość wynosi 30%.
Zapytanie medialne @media (min-width: 800px) { ... } - reguły w środku działają tylko, gdy okno ma 800 px lub więcej (tabela 2 arkusza opisuje @media). W środku: width: 30% i float: left, żeby artykuły pływały obok siebie. Trzy razy 30% plus marginesy po 1% z każdej strony to 96% - mieszczą się w jednym wierszu. Stopka dostaje clear: both, żeby wróciła pod pływające artykuły.
Klucz R.3.4 sprawdza granicę dokładnie: przy 800 px bloki mają być obok siebie - stąd min-width: 800px, nie 801px. Klucz przyjmuje też display: flex albo grid.
Typowe błędy
@media (min-width: 801px) zostawia dokładnie 800 px w układzie pod sobą - klucz R.3.4 mówi „dla 800 px i powyżej obok siebie”.
R.3.3 Po zmniejszeniu szerokości okna przeglądarki jedynie poniżej 800 px bloki w bloku głównym są ustawione jeden pod drugim
R.4.5 Zdefiniowane reguły @media dla trzech bloków artykułu: dla reguły szerokości ekranu 800px i więcej - szerokość bloku 30% w przeciwnym przypadku szerokość bloku 98% (width lub grid-template-columns lub flex)
ok. 2 min
Polecenie z arkusza
Gdy szerokość ekranu jest mniejsza niż 800 px szerokość każdego z trzech bloków wynosi 98% (są wyświetlane jeden pod drugim) zgodnie z ilustracją 4.
Drugie zapytanie medialne, @media (max-width: 799px) - okno węższe niż 800 px. Artykuły dostają width: 98% (plus 1% marginesu z każdej strony = 100%) i bez float stoją jeden pod drugim, jak na ilustracji 4. Sprawdź w podglądzie, zwężając okno - egzaminator robi to samo (R.3.3).
Typowe błędy
Jedna reguła article { width: 30% } bez @media daje wąskie bloki także na telefonie - R.3.3 i R.4.5 wymagają dwóch szerokości zależnych od okna.
R.4.3 Ustawiony kolor tła bloku nagłówkowego i stopki SteelBlue, pierwszy blok artykułu DodgerBlue, drugi - LimeGreen, trzeci - DarkOrchid
ok. 2 min
Polecenie z arkusza
Dodatkowo dla pierwszego artykułu: kolor tła DodgerBlue. Dodatkowo dla drugiego artykułu: kolor tła LimeGreen. Dodatkowo dla trzeciego artykułu: kolor tła DarkOrchid.
Trzy reguły po identyfikatorach #book1, #book2, #book3 - każdy artykuł inny kolor, dokładnie jak na ilustracji 2 (niebieski, zielony, fioletowy - pasujące do pól na okładkach). Identyfikatory są tu dozwolone, bo każdy artykuł jest jeden. Klucz przyjmuje też article:nth-of-type(1) i podobne.
R.4.6 Ustawiona szerokość dla selektora img oraz selektora table na 70%
ok. 1 min
Polecenie z arkusza
Dla selektora obrazu: szerokość 70%.
Selektor znacznika img (arkusz wymaga selektora znacznika, nie klasy). width: 70% liczy się od szerokości artykułu - okładka zmniejsza się razem z oknem, wysokość przelicza się proporcjonalnie. Dzięki text-align: center z * obraz stoi na środku artykułu.
R.4.7 Ustawione marginesy wewnętrzne (padding) 10px dla bloków nagłówkowego i stopki, 20px dla selektora paragrafu oraz margines górny (padding-top) 40px dla trzech bloków artykułu
ok. 1 min
Polecenie z arkusza
Dla selektora paragrafu: marginesy wewnętrzne 20 px.
Selektor znacznika p, padding: 20px - streszczenia odsuwają się od krawędzi kolorowych artykułów. Reguła obejmie też paragraf w stopce - to zgodne z arkuszem („dla selektora paragrafu”).
R.4.6 Ustawiona szerokość dla selektora img oraz selektora table na 70%
R.4.8 Ustawione marginesy zewnętrzne (margin) 1% dla trzech bloków artykułu, auto dla tabeli
R.4.9 Ustawione obramowanie tabeli linią ciągłą o kolorze SteelBlue i szerokości 1px
ok. 2 min
Polecenie z arkusza
Dla selektora tabeli: wyśrodkowanie tabeli, szerokość 70%, obramowanie linią ciągłą o kolorze SteelBlue i szerokości 1 px.
Selektor znacznika table. „Wyśrodkowanie tabeli” to margin: auto przy ustalonej szerokości (klucz R.4.8 mówi wprost: „auto dla tabeli”) - text-align: center wyśrodkowałby tylko tekst w komórkach, nie samą tabelę. Skrót border: 1px solid SteelBlue łączy grubość, styl (ciągła) i kolor.
Typowe błędy
Styl tabeli przez klasę (.tabela) nie spełnia wymagania - arkusz zastrzega selektor znacznika „ze względu na projekt późniejszej rozbudowy witryny”.
R.4.10 W momencie gdy kursor myszy znajdzie się na wierszu tabeli, jego kolor tła zmienia się na SteelBlue, a kolor czcionki na biały, np. tr:hover
ok. 1 min
Polecenie z arkusza
W momencie gdy kursor myszy znajdzie się na wierszu tabeli, jego kolor tła zmienia się na SteelBlue, a kolor czcionki na biały.
Pseudoklasa :hover na wierszu tr - klucz R.4.10 podaje ten zapis jako przykład. Efekt zobaczysz, gdy skrypt wypełni tabelę (na razie jest tylko wiersz nagłówkowy, on też reaguje). Arkusz stylów jest kompletny.
Kroki 34-38 · po tym etapie masz 36 z 36 kryteriów (pkt)
Krok 34: Połączenie z bazą danych
Kryteria: , ,
R.5.1 Skrypt napisany w języku PHP i zawiera przynajmniej jedną zgodną z treścią zadania instrukcję
R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy biblioteka
R.5.6 W skryptach zastosowana przynajmniej jedna zmienna oraz nazwy wszystkich zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania
ok. 3 min
Polecenie z arkusza
Napisany w języku PHP. Łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie biblioteka.
Kod PHP piszesz między <?php a ?> - serwer wykonuje go, zanim strona trafi do przeglądarki. Połączenie otwierasz na samym początku pliku i trzymasz w zmiennej $connection (znacząca, angielska nazwa - R.5.6). mysqli_connect z tabeli 1 arkusza przyjmuje kolejno: serwer, użytkownika, hasło (puste) i nazwę bazy.
Od tego kroku podgląd to wynik działania strony po stronie serwera (PHP nie wykonuje się w przeglądarce) - na razie wygląda jak wcześniej, bo skrypt niczego nie wypisuje.
Typowe błędy
Kolejność argumentów ma znaczenie: mysqli_connect('localhost', 'root', 'biblioteka') podaje „biblioteka” jako HASŁO. Nazwa bazy jest czwarta. Plik sprawdzaj przez http://localhost/…, nie otwierając go z dysku - inaczej PHP się nie wykona.
biblioteka.phpPHPzmienione: 3 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (biblioteka.php)
Krok 35: Zapytanie 4 do bazy
Kryteria:
R.5.4 Skrypt zawiera instrukcję wysyłającą do bazy danych zapytanie 4
ok. 2 min
Polecenie z arkusza
Wysyła do bazy danych zapytanie 4.
Skrypt piszesz wewnątrz<table>, pod wierszem nagłówkowym - tam mają trafić wiersze. mysqli_query($connection, ...) wysyła zapytanie i zwraca wynik, który zapisujesz w $books. Treść to dokładnie zapytanie 4 z kwerendy.txt: pięć losowych książek. Kolejność kolumn w SELECT zaraz będzie ważna: $row[0] to autor, $row[1] tytuł, $row[2] kod.
biblioteka.phpPHPzmienione: 3 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr><?php$books = mysqli_query($connection, 'SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;');?> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
R.5.5 Skrypt wyświetla w wierszach tabeli dane zwrócone zapytaniem, dane są wpisane do odpowiednich komórek tabeli
ok. 2 min
Polecenie z arkusza
W każdym wierszu tabeli, w odpowiednich komórkach, wyświetlane są zwrócone zapytaniem kolejne wiersze z bazy.
„Kolejne wiersze” to pętla. mysqli_fetch_row($books) (tabela 1) oddaje kolejny wiersz wyniku jako tablicę numerowaną od zera, a gdy wierszy zabraknie - false. Zapis while ($row = mysqli_fetch_row($books)) przypisuje wiersz do $row i od razu sprawdza, czy coś przyszło - pętla wykona się pięć razy. Ciało jest jeszcze puste.
Typowe błędy
Pojedyncze = w warunku while jest tu celowe (przypisanie); == porównałoby zmienną z wynikiem i pętla nie zadziałałaby poprawnie.
biblioteka.phpPHPzmienione: 2 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr><?php$books = mysqli_query($connection, 'SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;');while ($row = mysqli_fetch_row($books)) {}?> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
R.5.5 Skrypt wyświetla w wierszach tabeli dane zwrócone zapytaniem, dane są wpisane do odpowiednich komórek tabeli
R.2.9 W bloku sekcji umieszczono tabelę o 3 kolumnach (w skrypcie lub HTML) zastosowane znaczniki <table>, <tr>, <td>
ok. 3 min
Polecenie z arkusza
W każdym wierszu tabeli, w odpowiednich komórkach, wyświetlane są zwrócone zapytaniem kolejne wiersze z bazy.
echo w pętli dokłada jeden <tr> z trzema <td>: autor ($row[0]), tytuł ($row[1]), kod ($row[2]) - w tej kolejności, bo tak są ułożone kolumny nagłówkowe Autor, Tytuł, Katalog. Napis w cudzysłowie, żeby PHP podstawił wartości. Klucz R.5.5 sprawdza, że dane są „w odpowiednich komórkach”.
Podgląd pokazuje pięć książek z ilustracji 2 arkusza; na żywym serwerze każde odświeżenie losuje inne.
Typowe błędy
echo '<tr><td>$row[0]</td>...' w apostrofach wypisze dosłownie „$row[0]” - PHP nie podstawia zmiennych w apostrofach.
biblioteka.phpPHPzmienione: 1 linia
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr><?php$books = mysqli_query($connection, 'SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;');while ($row = mysqli_fetch_row($books)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>";}?> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Podgląd strony po tym kroku (biblioteka.php)
Krok 38: Zamknięcie połączenia z bazą
Kryteria:
R.5.3 Ostatnią operacją na bazie jest jej zamknięcie
ok. 1 min
Polecenie z arkusza
Na końcu działania skrypt zamyka połączenie z serwerem.
mysqli_close($connection) na końcu pliku, po wszystkich operacjach na bazie. Klucz R.5.3 sprawdza, że zamknięcie jest ostatnią operacją na bazie. Strona spełnia wszystkie kryteria arkusza - dalej trzy kroki „jak w prawdziwym projekcie”.
biblioteka.phpPHPzmienione: 3 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr><?php$books = mysqli_query($connection, 'SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;');while ($row = mysqli_fetch_row($books)) {echo"<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>";}?> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer><?phpmysqli_close($connection);?></body></html>
Kroki 39-41 · po tym etapie masz 36 z 36 kryteriów (pkt)
Krok 39: Refaktor: nazwy kolumn zamiast numerów
Kryteria:
R.5.5 Skrypt wyświetla w wierszach tabeli dane zwrócone zapytaniem, dane są wpisane do odpowiednich komórek tabeli
ok. 3 min
Polecenie z arkusza
W każdym wierszu tabeli, w odpowiednich komórkach, wyświetlane są zwrócone zapytaniem kolejne wiersze z bazy.
$row[0], $row[1], $row[2] działa, ale za miesiąc nikt nie pamięta, co było pod którym numerem - a wystarczy zmienić kolejność kolumn w SELECT, żeby tytuł wylądował w kolumnie „Autor”. mysqli_fetch_assoc (tabela 1 wymienia pokrewne mysqli_fetch_array) oddaje wiersz jako tablicę z nazwami kolumn: $row['autor'], $row['tytul'], $row['kod']. Kod czyta się sam.
W napisie w cudzysłowie element tablicy z kluczem w apostrofach trzeba objąć nawiasami klamrowymi: {$row['autor']}. Stara pętla zostaje w komentarzu // do porównania. Podgląd bez zmian.
Typowe błędy
"$row['autor']" bez klamer to błąd składni PHP wewnątrz cudzysłowu - albo klamry {$row['autor']}, albo prosta składnia "$row[autor]" z kluczem bez apostrofów (poprawna tylko wewnątrz napisu w cudzysłowie).
biblioteka.phpPHPzmienione: 5 linii
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr><?php$books = mysqli_query($connection, 'SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;');// while ($row = mysqli_fetch_row($books)) {// echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>";// }while ($row = mysqli_fetch_assoc($books)) {echo"<tr><td>{$row['autor']}</td><td>{$row['tytul']}</td><td>{$row['kod']}</td></tr>";}?> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer><?phpmysqli_close($connection);?></body></html>
Krok 40: Refaktor: escapowanie danych przed wypisaniem
Kryteria:
R.5.5 Skrypt wyświetla w wierszach tabeli dane zwrócone zapytaniem, dane są wpisane do odpowiednich komórek tabeli
ok. 3 min
Polecenie z arkusza
W każdym wierszu tabeli, w odpowiednich komórkach, wyświetlane są zwrócone zapytaniem kolejne wiersze z bazy.
Skrypt wypisuje do HTML to, co jest w bazie. W tym arkuszu katalog jest zamknięty, ale w prawdziwej bibliotece tytuły dodają ludzie - tytuł <script>alert(1)</script> wykonałby się w przeglądarce każdego odwiedzającego (XSS). htmlspecialchars() zamienia <, >, ", & na encje, więc tekst wyświetla się dosłownie i nie staje się kodem.
Każdą wartość przepuszczasz przez htmlspecialchars do osobnej zmiennej o angielskiej nazwie, a echo używa już tylko tych zmiennych. Podgląd wygląda identycznie, bo tytuły z archiwum nie mają znaków specjalnych.
Typowe błędy
htmlspecialchars przy zapisie do bazy zamiast przy wypisywaniu to częsty błąd: baza dostaje zniekształcone dane (& zamiast &). Escapujesz na wyjściu, tam gdzie HTML.
biblioteka.phpPHPzmienione: 4 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr><?php$books = mysqli_query($connection, 'SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;');// while ($row = mysqli_fetch_row($books)) {// echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>";// }while ($row = mysqli_fetch_assoc($books)) {$author = htmlspecialchars($row['autor']);$title = htmlspecialchars($row['tytul']);$code = htmlspecialchars($row['kod']);echo"<tr><td>$author</td><td>$title</td><td>$code</td></tr>";}?> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer><?phpmysqli_close($connection);?></body></html>
R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy biblioteka
R.5.3 Ostatnią operacją na bazie jest jej zamknięcie
R.5.5 Skrypt wyświetla w wierszach tabeli dane zwrócone zapytaniem, dane są wpisane do odpowiednich komórek tabeli
ok. 4 min
Polecenie z arkusza
Na końcu działania skrypt zamyka połączenie z serwerem.
Dotąd kod bazy był wpleciony w tabelę, a zamknięcie połączenia stało na końcu pliku, daleko od otwarcia. W prawdziwych projektach całą pracę z bazą robi się na górze pliku, a HTML tylko wyświetla gotowe dane:
mysqli_fetch_all($result, MYSQLI_ASSOC) pobiera wszystkie wiersze naraz do tablicy $books,
mysqli_close($connection) zaraz po tym - połączenie żyje tylko tyle, ile trzeba, i nadal jest ostatnią operacją na bazie (R.5.3),
w tabeli zostaje tylko foreach ($books as $row) z echo - zwykła pętla po tablicy, bez funkcji mysqli_*.
Gdyby ktoś chciał zmienić bazę na inną (albo wczytać książki z pliku), zmienia tylko górę pliku - tabela nie wie, skąd są dane. Podgląd bez zmian.
Typowe błędy
mysqli_fetch_all($result) bez MYSQLI_ASSOC oddaje wiersze z numerami kolumn zamiast nazw - wtedy $row['tytul'] w pętli daje ostrzeżenie „Undefined array key” i pustą komórkę (sprawdzone w PHP 8.2).
biblioteka.phpPHPzmienione: 4 linie
<?php$connection = mysqli_connect('localhost', 'root', '', 'biblioteka');$result = mysqli_query($connection, 'SELECT autor, tytul, kod FROM ksiazki ORDER BY RAND() LIMIT 5;');$books = mysqli_fetch_all($result, MYSQLI_ASSOC);mysqli_close($connection);?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>BIBLIOTEKA SZKOLNA</title> <linkrel="stylesheet"href="styles.css"></head><body> <header> <h2>STRONA BIBLIOTEKI SZKOLNEJ WIEDZAMIN</h2> </header> <section> <h3>Nasze dzisiejsze propozycje:</h3> <table> <tr><th>Autor</th><th>Tytuł</th><th>Katalog</th></tr><?phpforeach ($booksas$row) {$author = htmlspecialchars($row['autor']);$title = htmlspecialchars($row['tytul']);$code = htmlspecialchars($row['kod']);echo"<tr><td>$author</td><td>$title</td><td>$code</td></tr>";}?> </table> </section> <main> <articleid="book1"> <imgsrc="ksiazka1.jpg"alt="okładka książki"> <p>Według różnych podań najpaskudniejsza ropucha nosi w głowie piękny, cenny klejnot.</p> </article> <articleid="book2"> <imgsrc="ksiazka2.jpg"alt="okładka książki"> <p>Panna Stefcia i Maryla nie są to zbyt grzeczne damy, nawet nie słuchają mamy...</p> </article> <articleid="book3"> <imgsrc="ksiazka3.jpg"alt="okładka książki"> <p>Ratuj mnie, przyjacielu, w ostatniej potrzebie: Kocham piękną Irenę. Rodzice i ona...</p> </article> </main> <footer> <p>Stronę wykonał: Bartosz Bryniarski</p> </footer></body></html>
Krok 42 · po tym etapie masz 36 z 36 kryteriów (pkt)
Krok 42: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę przez http://localhost/….
W folderze z numerem zdającego muszą być: biblioteka.php, import.png, ksiazka1.jpg, ksiazka2.jpg, ksiazka3.jpg, kw1.png, kw2.png, kw3.png, kw4.png, kwerendy.txt, przeglądarka.txt, styles.css. Nagraj płytę, sprawdź jej odczyt i opisz numerem zdającego. Pusta lub nieczytelna płyta to zero punktów za wszystkie pięć rezultatów.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
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: Bartosz Bryniarski. 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.