INF.03-04-25.01-SGStyczeń 2025 · 44 kroki · ok. 82 min · 40 kryteriów z klucza
Rozwiązanie krok po kroku: Aplikacja internetowa hurtowni obuwia (Wersja podstawowa)
Rozwiązanie buduje aplikację hurtowni obuwia męskiego: baza obuwie z kategoriami, butami i produktami (kolor, materiał, plik ze zdjęciem) i cztery zapytania - pojedyncza kolumna, dwa złączenia tabelJOIN ... USING (drugie z warunkiem na model) i wstawienie rekorduINSERT z kluczem nadawanym automatycznie, potem dwie strony PHP: index.php z formularzem zamówienia i blokami produktów generowanymi z bazy oraz zamow.php, która pokazuje wybrany but i liczy koszt zamówienia, i style w style.css - z blokami o zaokrąglonych rogach, zmieniającymi kolor pod kursorem.
Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypty są najpierw pisane najprościej, funkcjami mysqli_query i mysqli_fetch_row, a na końcu zostają przerobione na wersję z prawdziwych projektów: zapytanie przygotowane, sprawdzenie danych z formularza, mysqli_fetch_assoc i htmlspecialchars.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (PDO)” jest drugi sposób rozwiązania tego samego arkusza: kolory w zmiennych CSS, bloki produktów jako <article>, PDO z zapytaniami przygotowanymi, sprawdzenie danych z formularza i htmlspecialchars przy każdym wypisaniu od pierwszej linii - obie wersje są zgodne z kluczem.
Baza i zdjęcia butów pochodzą z prawdziwego archiwum pliki9 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu. Podgląd stron PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 (tej samej wersji, w której sprawdza się egzamin) na bazie z arkusza; strona zamówienia pokazuje wynik dla modelu T-02-44, rozmiaru 42 i 4 par - jak na ilustracji 3.
Jak liczą się punkty. Klucz ma 40 kryteriów (R.1.1 - R.5.10), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 30 punktów - można stracić 10 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.
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 40 kryteriów (pkt)
Krok 1: Baza danych obuwie
Kryteria:
R.1.1 Wykonany import tabel do bazy danych obuwie , co jest udokumentowane w pliku import w formacie JPEG
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie obuwie, z zestawem polskich znaków (np. utf8_unicode_ci).
Rozpakuj pliki9.7z z pulpitu (hasło *HurTowni@Buty$ - z gwiazdką na początku i dolarem na końcu) do folderu z numerem zdającego: obuwie.sql i cztery zdjęcia but1.png - but4.png. W phpMyAdmin: Nowa, nazwa obuwie, porównywanie z polskimi znakami, np. utf8_unicode_ci.
Krok 2: Import tabel z pliku obuwie.sql
Kryteria:
R.1.1 Wykonany import tabel do bazy danych obuwie , co jest udokumentowane w pliku import w formacie JPEG
ok. 2 min
Polecenie z arkusza
Do utworzonej bazy zaimportuj tabele z pliku obuwie.sql z rozpakowanego archiwum.
Wybierz bazę obuwie, potem Import → obuwie.sql → Wykonaj. Powstają trzy tabele z ilustracji 1: kategorie, buty (model, kategoria, nazwa, cena) i produkt (kod produktu, kolor, materiał, wysokość, plik ze zdjęciem). Tabele buty i produkt łączy pole model - ma tę samą nazwę w obu, co przyda się w zapytaniach 2 i 3.
Krok 3: Zrzut ekranu import.jpg
Kryteria:
R.1.1 Wykonany import tabel do bazy danych obuwie , co jest udokumentowane w pliku import w formacie JPEG
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie JPEG pod nazwą import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel.
Print Screen, wklejasz do edytora grafiki i zapisujesz jako import.jpg - import w JPEG, zrzuty zapytań w PNG.
Typowe błędy
Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).
Krok 4: Zapytanie 1: modele z tabeli produkt
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 pole model z tabeli produkt . W pliku z kwerendami lub na zrzucie istnieje zapis np. SELECT model FROM produkt; oraz wynik działania udokumentowany zrzutem, na którym widoczne są jedynie dane: O-23- 45, P-59-03, T-02-44, T-03-32
ok. 1 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie pole model z tabeli produkt.
Jedna kolumna, bez warunku. Wynik: O-23-45, P-59-03, T-02-44, T-03-32 - jak w kluczu. To zapytanie wypełni listę modeli w formularzu (Skrypt 1). Zapytanie zapisujesz w kwerendy.txt, zrzut jako kw1.png.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT model FROM produkt;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: buty ze zdjęciami
Kryteria:
R.1.4 Wykonane zapytanie 2 wybierające jedynie pola model, nazwa, cena z tabeli buty oraz odpowiadające im pole nazwa_pliku z tabeli produkt . W pliku z kwerendami lub na zrzucie istnieje zapis np. SELECT model, nazwa, cena, nazwa_pliku FROM buty JOIN produkt USING(model); (możliwe też porównanie kluczy po ON lub WHERE ) oraz wynik działania udokumentowany zrzutem, na którym widoczne są dokładnie 4 rekordy dla wymienionych w kryterium 1.3 modeli
ok. 3 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola model, nazwa, cena z tabeli buty oraz odpowiadające im pole nazwa_pliku z tabeli produkt. Należy posłużyć się relacją.
SELECT model, nazwa, cena, nazwa_pliku - trzy pola z buty i jedno z produkt,
FROM buty JOIN produkt - złączenie tabel,
USING(model) - pole łączące ma tę samą nazwę w obu tabelach; równoważnie ON buty.model = produkt.model. Przy USING kolumnę model można wypisać bez nazwy tabeli, bo w wyniku jest tylko raz.
Wynik: cztery wiersze, po jednym dla każdego modelu. Zrzut: kw2.png. To zapytanie zbuduje bloki produktów (Skrypt 2).
Typowe błędy
ON model = model bez nazw tabel kończy się błędem „Column 'model' in on clause is ambiguous” - przy ON trzeba napisać buty.model = produkt.model.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT model FROM produkt;-- Zapytanie 2SELECT model, nazwa, cena, nazwa_pliku FROM buty JOIN produkt USING(model);
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: szczegóły modelu P-59-03
Kryteria:
R.1.5 Wykonane zapytanie 3 wybierające jedynie pola nazwa, cena z tabeli buty i odpowiadające mu pola kolor, kod_produktu, material, nazwa_pliku z tabeli produkt dla modelu „P-59-03”. W pliku z kwerendami lub na zrzucie istnieje zapis np. SELECT nazwa, cena, kolor, kod_produktu, material, nazwa_pliku FROM buty JOIN produkt USING(model) WHERE model = "P-59-03"; (możliwe też porównanie kluczy po ON lub WHERE ) oraz wynik działania udokumentowany zrzutem, na którym jest widoczny jedynie rekord z danymi o nazwie PÓŁBUTY WIZYTOWE
ok. 2 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie pola nazwa, cena z tabeli buty i odpowiadające mu pola kolor, kod_produktu, material, nazwa_pliku z tabeli produkt dla modelu „P-59-03”. Należy posłużyć się relacją.
To samo złączenie, sześć pól i warunek WHERE model = "P-59-03". Wynik: jeden wiersz - PÓŁBUTY WIZYTOWE, 188.00, czarny, skóra naturalna. Zrzut: kw3.png. W Skrypcie 3 w miejscu P-59-03 stanie model wybrany w formularzu.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT model FROM produkt;-- Zapytanie 2SELECT model, nazwa, cena, nazwa_pliku FROM buty JOIN produkt USING(model);-- Zapytanie 3SELECT nazwa, cena, kolor, kod_produktu, material, nazwa_pliku FROM buty JOIN produkt USING(model) WHERE model = "P-59-03";
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: nowa kategoria Sandały
Kryteria:
R.1.6 Wykonane zapytanie 4 wstawiające rekord z nazwą kategorii „Sandały” do tabeli kategorie . Klucz główny generowany automatycznie - pominięty lub wartość NULL. W pliku z kwerendami lub na zrzucie istnieje zapis np. INSERT INTO kategorie VALUES (NULL, 'Sandały'); (możliwe inne warianty zapytania, klucz musi być dodany automatycznie ) oraz wynikiem działania jest widoczny komunikat o poprawnym wstawieniu rekordu lub tabela ze wstawionym rekordem
ok. 2 min
Polecenie z arkusza
Zapytanie 4: wstawiające rekord z nazwą kategorii „Sandały” do tabeli kategorie. Klucz główny generowany automatycznie.
INSERT INTO kategorie VALUES (NULL, 'Sandały') - wartości w kolejności kolumn: NULL w miejscu klucza oznacza „nadaj sam” (pole ma AUTO_INCREMENT). Równoważnie: INSERT INTO kategorie (nazwa_kat) VALUES ('Sandały'). Ciekawostka z tej bazy: nowy rekord dostaje id_kat = 6, a nie 5 - plik obuwie.sql ustawia licznik AUTO_INCREMENT=6, więc baza pamięta, że numer 5 był już kiedyś użyty. Zrzut: kw4.png.
Typowe błędy
Wpisanie klucza ręcznie (VALUES (5, 'Sandały')) przeczy wymaganiu „klucz generowany automatycznie” - klucz musi zostać pominięty albo równy NULL.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT model FROM produkt;-- Zapytanie 2SELECT model, nazwa, cena, nazwa_pliku FROM buty JOIN produkt USING(model);-- Zapytanie 3SELECT nazwa, cena, kolor, kod_produktu, material, nazwa_pliku FROM buty JOIN produkt USING(model) WHERE model = "P-59-03";-- Zapytanie 4INSERT INTO kategorie VALUES (NULL, 'Sandały');
Podgląd strony po tym kroku
Etap 2: Strony HTML
Kroki 8-21 · po tym etapie masz 17 z 40 kryteriów (pkt)
Krok 8: Plik index.php w HTML5
Kryteria:
R.2.1 Witryna internetowa zapisana w plikach index.php i zamow.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE html>, zadeklarowany język witryny: polski np. <html lang="pl">. Strona zawiera sekcje head i body
ok. 2 min
Polecenie z arkusza
Składa się z dwóch stron o nazwach index.php, zamow.php. Cechy wspólne dla obu stron: Zapisane w języku HTML5.
Zbuduj index.php, a zamow.php powstanie z jej kopii - różnią się tylko blokiem głównym. Rozszerzenie .php, bo dojdą skrypty; na egzaminie pliki leżą w htdocs XAMPP-a i otwierasz je przez http://localhost/....
R.2.1 Witryna internetowa zapisana w plikach index.php i zamow.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE html>, zadeklarowany język witryny: polski np. <html lang="pl">. Strona zawiera sekcje head i body
R.2.1 Witryna internetowa zapisana w plikach index.php i zamow.php oraz zapisany jawnie standard kodowania polskich znaków, deklaracja HTML5 <!DOCTYPE html>, zadeklarowany język witryny: polski np. <html lang="pl">. Strona zawiera sekcje head i body
ok. 1 min
Polecenie z arkusza
Jawnie zastosowany właściwy standard kodowania polskich znaków.
<meta charset="UTF-8"> jako pierwszy element <head>.
R.3.6 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie style.css formatowanie CSS pochodzi jedynie z tego arkusza. Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)
ok. 1 min
Polecenie z arkusza
Arkusz stylów w pliku o nazwie style.css prawidłowo połączony z kodem strony.
R.2.3 Zdefiniowany układ strony dzielący ją na bloki: nagłówkowy, główny i stopki przy pomocy semantycznych znaczników sekcji języka HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, do stopki - footer. Dopuszcza się dodatkowe uzycie bloków div lub section
ok. 1 min
Polecenie z arkusza
Podział strony na bloki: nagłówkowy, poniżej główny, na dole stopka. Podział zrealizowany za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z ilustracją 2.
<header>, <main> i <footer> - klucz wymaga wprost header i footer (R.2.3). Bloki stoją jeden pod drugim.
R.2.4 W bloku nagłówkowym umieszczony <h1>: "Obuwie męskie", w stopce umieszczony paragraf z numerem zdającego oraz na stronie zamówień umieszczony w bloku głównym <h2>: "Zamówienie"
ok. 1 min
Polecenie z arkusza
Zawartość bloku nagłówkowego: nagłówek pierwszego stopnia o treści „Obuwie męskie”.
R.2.4 W bloku nagłówkowym umieszczony <h1>: "Obuwie męskie", w stopce umieszczony paragraf z numerem zdającego oraz na stronie zamówień umieszczony w bloku głównym <h2>: "Zamówienie"
ok. 1 min
Polecenie z arkusza
Zawartość stopki: paragraf o treści: „Autor strony: ”, dalej wstawiony numer zdającego.
Akapit w <footer>. Na egzaminie po dwukropku wpisujesz swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania.
Krok 16: Formularz wysyłany metodą POST do zamow.php
Kryteria: ,
R.2.5 Na stronie głównej w bloku głównym umieszczony formularz. Zastosowany znacznik <form>
R.3.2 Dane z formularza przesyłane są za pomocą metody POST do strony zamow.php
ok. 2 min
Polecenie z arkusza
Zawartość bloku głównego strony index.php: Formularz wysyłający dane metodą bezpieczną do pliku zamow.php.
method="post" - „metoda bezpieczna” w rozumieniu arkusza: dane w treści żądania, nie w adresie. 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. action="zamow.php" - tym razem dane trafiają do innej strony, która je odczyta w Skrypcie 3 (R.2.5, R.3.2).
R.2.6 W formularzu umieszczona przynajmniej jedna lista rozwijalna - znaczniki <select> i <option>, pole edycyjne oraz przycisk "Zamów" oraz przynajmniej z jednym polem powiązana etykieta <label>
R.3.4 Wszystkie elementy formularza mają przypisaną klasę kontrolki oraz przynajmniej jeden blok produktu ma przypisaną klasę buty
ok. 2 min
Polecenie z arkusza
Listy rozwijanej, poprzedzonej etykietą „Model: ”, wypełnionej przez skrypt 1.
Etykieta <label for> powiązana z listą <select> po id. name="model" - pod tą nazwą wybrany model trafi do $_POST na stronie zamow.php. Klasę kontrolki dajesz od razu (R.3.4). Opcji na razie nie ma - wygeneruje je Skrypt 1 z bazy.
R.2.6 W formularzu umieszczona przynajmniej jedna lista rozwijalna - znaczniki <select> i <option>, pole edycyjne oraz przycisk "Zamów" oraz przynajmniej z jednym polem powiązana etykieta <label>
R.3.4 Wszystkie elementy formularza mają przypisaną klasę kontrolki oraz przynajmniej jeden blok produktu ma przypisaną klasę buty
ok. 2 min
Polecenie z arkusza
Listy rozwijanej, poprzedzonej etykietą: „Rozmiar: ”, wypełnionej liczbami od 40 do 43.
Cztery opcje wpisane ręcznie w HTML-u. Bez atrybutu value wartością opcji jest jej tekst, więc do formularza trafi np. 42 (R.2.6).
R.2.6 W formularzu umieszczona przynajmniej jedna lista rozwijalna - znaczniki <select> i <option>, pole edycyjne oraz przycisk "Zamów" oraz przynajmniej z jednym polem powiązana etykieta <label>
R.3.3 Przycisk realizuje funkcję wysłania danych z formularza (input lub button z typem submit lub button bez typu) oraz przynajmniej jedno pole edycyjne jest typu number
R.3.4 Wszystkie elementy formularza mają przypisaną klasę kontrolki oraz przynajmniej jeden blok produktu ma przypisaną klasę buty
ok. 1 min
Polecenie z arkusza
Pola edycyjnego przeznaczonego do wpisywania wartości liczbowych, poprzedzonego etykietą: „Liczba par: ”.
R.2.6 W formularzu umieszczona przynajmniej jedna lista rozwijalna - znaczniki <select> i <option>, pole edycyjne oraz przycisk "Zamów" oraz przynajmniej z jednym polem powiązana etykieta <label>
R.3.3 Przycisk realizuje funkcję wysłania danych z formularza (input lub button z typem submit lub button bez typu) oraz przynajmniej jedno pole edycyjne jest typu number
R.3.4 Wszystkie elementy formularza mają przypisaną klasę kontrolki oraz przynajmniej jeden blok produktu ma przypisaną klasę buty
ok. 1 min
Polecenie z arkusza
Przycisku o treści „Zamów”, który wysyła dane z formularza.
<button type="submit"> wysyła formularz do zamow.php (R.3.3). Klasa kontrolki - jak wszystkie elementy formularza (R.3.4).
R.2.4 W bloku nagłówkowym umieszczony <h1>: "Obuwie męskie", w stopce umieszczony paragraf z numerem zdającego oraz na stronie zamówień umieszczony w bloku głównym <h2>: "Zamówienie"
R.3.5 Na stronie zamówień jest umieszczony odsyłacz "Strona główna", którego wybranie otwiera stronę główną
ok. 2 min
Polecenie z arkusza
Zawartość bloku głównego strony zamow.php: Nagłówek drugiego stopnia o treści „Zamówienie”. Odnośnik „Strona główna” prowadzący do strony index.php.
Zapisz index.php jako zamow.php i w bloku głównym zostaw <h2> i odnośnik do strony głównej (R.2.4, R.3.5). Między nimi stanie Skrypt 3.
Kroki 22-28 · po tym etapie masz 28 z 40 kryteriów (pkt)
Krok 22: Plik style.css: krój czcionki
Kryteria:
R.4.1 Ustawiony styl domyślny dla wszystkich selektorów (*): krój czcionki Cambria
ok. 1 min
Polecenie z arkusza
Domyślnie, dla wszystkich selektorów: krój czcionki Cambria.
Selektor * (R.4.1).
style.cssCSSnowy plik
* {font-family: Cambria;}
Podgląd strony po tym kroku (index.php)
Krok 23: Nagłówek i stopka
Kryteria: , , ,
R.4.2 Ustawiony kolor tła Sienna dla bloku nagłówkowego, stopki i selektora h4, AntiqueWhite dla bloku głównego
R.4.3 Ustawiony biały kolor czcionki dla bloku nagłówkowego, stopki i nagłówka czwartego stopnia
R.4.6 Ustawione marginesy wewnętrzne (padding) 5px dla bloku nagłówkowego i stopki oraz margines zewnętrzny prawy (margin-right) 30px dla selektora img
R.4.7 Ustawione wyrównanie tekstu do środka dla bloku nagłówkowego i stopki oraz do prawej dla nagłówka czwartego stopnia
ok. 1 min
Polecenie z arkusza
Wspólne dla bloku nagłówkowego i stopki: kolor tła Sienna, biały kolor czcionki, marginesy wewnętrzne 5 px, wyrównanie tekstu do środka.
Krok 24: Blok główny: wysokość i paski przewijania
Kryteria: , ,
R.4.2 Ustawiony kolor tła Sienna dla bloku nagłówkowego, stopki i selektora h4, AntiqueWhite dla bloku głównego
R.4.4 Ustawiony dla bloku głównego rozmiar czcionki 120% oraz paski przewijania na auto
R.4.5 Ustawiona wysokość 700px dla bloku głównego
ok. 2 min
Polecenie z arkusza
Dla bloku głównego: kolor tła AntiqueWhite, wysokość 700 px, rozmiar czcionki 120%, paski przewijania pojawiające się w przypadku gdy zawartość nie mieści się w bloku.
overflow: auto - pasek przewijania pojawia się tylko wtedy, gdy zawartość jest wyższa niż 700 px; przy krótkiej treści go nie ma (scroll pokazywałby go zawsze). Cztery bloki produktów nie zmieszczą się w 700 px, więc na ilustracji 2 widać pasek z prawej (R.4.2, R.4.4, R.4.5).
R.4.8 Zdefiniowana klasa kontrolki o cechach: szerokość 150px, marginesy zewnętrzne 10px
ok. 1 min
Polecenie z arkusza
Zdefiniowana klasa kontrolki o cechach: szerokość 150 px, marginesy zewnętrzne 10 px. Klasa jest przypisana do wszystkich elementów formularza (listy rozwijane, pole edycyjne, przycisk).
Selektor klasy z kropką. Wszystkie cztery kontrolki mają już klasę - teraz mają równą szerokość, jak na ilustracji 2 (R.4.8).
R.4.9 Zdefiniowana klasa buty o cechach: szerokość 70%, marginesy zewnętrzne 15px, marginesy wewnętrzne 7px, obramowanie linią ciągłą o szerokości 1px i kolorze Sienna, zaokrąglenie rogów 30px
R.4.10 Gdy kursor znajdzie się na bloku produktu jego kolor tła zmienia się na Linen np. dla .buty:hover
ok. 2 min
Polecenie z arkusza
Zdefiniowana klasa buty o cechach: szerokość 70%, marginesy zewnętrzne 15 px, marginesy wewnętrzne 7 px, obramowanie linią ciągłą o szerokości 1 px i kolorze Sienna, zaokrąglenie rogów 30 px. Gdy kursor znajdzie się na bloku produktu (klasa buty) jego kolor tła zmienia się na Linen.
Styl bloków produktów, które wygeneruje Skrypt 2 - na razie nie ma ich na stronie, więc w podglądzie nic się nie zmienia. .buty:hover łączy klasę z pseudoklasą: zmiana tła tylko dla bloku pod kursorem (R.4.9, R.4.10).
R.3.1 Układ bloków po uruchomieniu w przeglądarce jest zgodny z ilustracją 2 w arkuszu egzaminacyjnym oraz obrazy są opływane zawartością po prawej stronie
R.4.6 Ustawione marginesy wewnętrzne (padding) 5px dla bloku nagłówkowego i stopki oraz margines zewnętrzny prawy (margin-right) 30px dla selektora img
ok. 1 min
Polecenie z arkusza
Dla selektora obrazu: opływany po prawej stronie zawartością (obraz po lewej stronie), margines zewnętrzny prawy 30 px.
float: left - obraz przy lewej krawędzi bloku, a nagłówki stają po jego prawej stronie (R.3.1, R.4.6). Selektor znacznika img, jak wymaga uwaga arkusza.
Kroki 29-41 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 29: Skrypt 1: połączenie z bazą obuwie
Kryteria: ,
R.5.1 Skrypt jest 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 obuwie
ok. 2 min
Polecenie z arkusza
Łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie obuwie.
Skrypt 1 piszesz wewnątrz<select> - to, co wypisze, stanie się opcjami listy. mysqli_connect z czterema argumentami łączy się z serwerem i wybiera bazę; uchwyt połączenia trzymasz w $connection, bo użyje go też Skrypt 2 (R.5.1, R.5.2). Podgląd od tego kroku to wynik prawdziwego uruchomienia strony w PHP.
R.5.6 Skrypt 1 wyświetla w liście rozwijalnej nazwy modeli pobrane z bazy
ok. 2 min
Polecenie z arkusza
Wyświetla pobrane zapytaniem wartości jako elementy listy rozwijanej z modelami obuwia.
mysqli_fetch_row przy każdym wywołaniu oddaje kolejny wiersz jako tablicę, a gdy wierszy zabraknie - null, co kończy pętlę while. Dla każdego modelu wypisujesz <option> z jego nazwą. Rozwiń listę „Model” w podglądzie: cztery modele z bazy, pierwszy O-23-45 - jak na ilustracji 2 (R.5.6).
Krok 32: Skrypt 2: zapytanie 2 i zamknięcie połączenia
Kryteria: ,
R.5.3 Ostatnią operacją na bazie jest jej zamknięcie
R.5.4 Na stronie głównej skrypt 1 zawiera instrukcję wysyłającą do bazy zapytanie 1 lub skrypt 2 - zapytanie 2
ok. 2 min
Polecenie z arkusza
Skrypt 2 w pliku index.php wysyła do bazy danych zapytanie 2. Na końcu zamykane jest połączenie z serwerem.
Skrypt 2 stoi pod formularzem i korzysta z tego samego połączenia $connection. Wysyła zapytanie 2, a na samym końcu mysqli_close zamyka połączenie - to ostatnia operacja na bazie na tej stronie (R.5.3, R.5.4).
R.2.7 W bloku głównym umieszczony obraz z tekstem alternatywnym "but męski" (w HTML lub skrypcie )
R.3.4 Wszystkie elementy formularza mają przypisaną klasę kontrolki oraz przynajmniej jeden blok produktu ma przypisaną klasę buty
ok. 3 min
Polecenie z arkusza
Dla każdego zwróconego zapytaniem wiersza tworzy blok produktu, zawierający obraz o nazwie pliku pobranej zapytaniem i tekście alternatywnym „but męski”.
Dla każdego wiersza wypisujesz blok <div class="buty"> - styl tej klasy już czeka w CSS - a w nim obraz. Kolumny wyniku mają numery w kolejności z SELECT: $row[0] model, [1] nazwa, [2] cena, [3] nazwa pliku - ten ostatni idzie do atrybutu src. Cudzysłowy atrybutów HTML wewnątrz napisu PHP poprzedzasz ukośnikiem: \" (R.2.7, R.3.4). Najedź na blok w podglądzie - tło zmienia się na Linen.
R.2.8 Na stronie głównej w bloku głównym umieszczone <h4> i <h5> (w HTML lub skrypcie )
R.5.7 Skrypt 2 dla każdego zwróconego zapytaniem rekordu danych wyświetla blok zawierający: obraz, którego źródło pobrane jest z bazy, nazwę produktu, model i cenę
R.5.10 W skryptach zastosowana przynajmniej jedna zmienna lub funkcja oraz nazwy wszystkich funkcji i zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania
ok. 3 min
Polecenie z arkusza
Nagłówek drugiego stopnia zawierający zwróconą zapytaniem nazwę produktu. Nagłówek piątego stopnia o treści: „Model: <model>”. Nagłówek czwartego stopnia o treści: „Cena: <cena>”, gdzie wartość w nawiasach <> oznacza dane pobrane zapytaniem.
Trzy nagłówki w kolejności z arkusza: <h2> z nazwą, <h5> z modelem i <h4> z ceną - ten ostatni dostaje brązowy pasek ze stylu h4. Podgląd pokazuje cztery bloki: PÓŁBUTY WIZYTOWE, TRZEWIKI SZNUROWANE, TRAMPKI SLIP ON i OBUWIE TRENINGOWE; cena ma dwa miejsca po przecinku (188.00), bo tak przechowuje ją pole float(5,2) (R.2.8, R.5.7, R.5.10).
Kolejność bloków może się różnić od ilustracji 2: zapytanie nie ma ORDER BY, a bez niego baza nie gwarantuje kolejności wierszy złączenia - zależy ona od tego, którą tabelę serwer przegląda pierwszą. W tym podglądzie (prawdziwe uruchomienie w XAMPP) pierwsze są OBUWIE TRENINGOWE, na ilustracji PÓŁBUTY. Klucz sprawdza cztery bloki z danymi, nie ich kolejność; gdyby kolejność była wymagana, wystarczyłoby dopisać np. ORDER BY kod_produktu.
R.3.1 Układ bloków po uruchomieniu w przeglądarce jest zgodny z ilustracją 2 w arkuszu egzaminacyjnym oraz obrazy są opływane zawartością po prawej stronie
ok. 1 min
Polecenie z arkusza
Podział zrealizowany za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z ilustracją 2.
Sprawdź całość: nagłówek, blok główny o wysokości 700 px z paskiem przewijania (cztery bloki się nie mieszczą), stopka. W blokach zdjęcia stoją po lewej, a nazwy po prawej - obraz opływany treścią, jak wymaga klucz (R.3.1).
Krok 36: Skrypt 3: połączenie na stronie zamówienia
Kryteria: ,
R.5.2 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy obuwie
R.5.3 Ostatnią operacją na bazie jest jej zamknięcie
ok. 2 min
Polecenie z arkusza
Skrypt 3 w pliku zamow.php. Na końcu zamykane jest połączenie z serwerem.
zamow.php to osobna strona - własne połączenie z bazą na początku Skryptu 3 i zamknięcie na końcu. Podgląd tej strony pokazuje stan po wysłaniu formularza z ilustracji 3: model T-02-44, rozmiar 42, 4 pary.
Formularz wysłał dane metodą POST, więc czekają w tablicy $_POST pod nazwami z atrybutów name: model, size, pairs.
Typowe błędy
Otwarcie zamow.php wprost z paska adresu, bez wysłania formularza, daje serię ostrzeżeń „Undefined array key” i „Trying to access array offset on value of type null” zamiast danych zamówienia (sprawdzone w PHP 8.2). Klucz tego nie sprawdza - zabezpieczenie jest w etapie „Dobre praktyki”.
Krok 38: Skrypt 3: zapytanie 3 z modelem z formularza
Kryteria:
R.5.5 Na stronie zamówień skrypt 3 zawiera instrukcję wysyłającą do bazy zmodyfikowane zapytanie 3, w ten sposób, że w warunku sprawdzany jest model wybrany w formularzu
ok. 3 min
Polecenie z arkusza
Wysyła zmodyfikowane zapytanie 3, w ten sposób, że w warunku sprawdzany jest model buta wybrany w formularzu.
Zapytanie 3, w którym zamiast P-59-03 stoi $model - w apostrofach, bo w SQL porównujesz tekst. Wynik ma jeden wiersz, więc wystarczy jedno mysqli_fetch_row, bez pętli. Kolumny: $row[0] nazwa, [1] cena, [2] kolor, [3] kod, [4] materiał, [5] plik (R.5.5).
R.5.8 Skrypt 3 dla modelu buta pobranego z formularza wyświetla obraz, którego źródło pobrane jest z bazy oraz pozostałe informacje pobrane z bazy: nazwę produktu, kolor, materiał
ok. 2 min
Polecenie z arkusza
Dane ze zwróconego zapytaniem wiersza są wyświetlane na stronie: obraz o nazwie pliku pobranej zapytaniem i tekście alternatywnym „but męski”, nagłówek drugiego stopnia z nazwą produktu pobraną z bazy.
Obraz z pliku z bazy ($row[5]) i nazwa w <h2> - dla T-02-44 to TRZEWIKI SZNUROWANE (R.5.8).
R.5.9 Skrypt 3 wyświetla rozmiar buta oraz obliczony koszt jako wynik mnożenia ceny buta pobranej z bazy i liczby par pobranej z formularza
ok. 2 min
Polecenie z arkusza
Paragraf o treści: „cena za <liczbaPar> par: <wartośćCałkowita> zł", gdzie <liczbaPar> oznacza wartość pobraną z formularza, a <wartośćCałkowita> oznacza obliczony koszt za podaną liczbę par wybranego buta.
Cena z bazy razy liczba par z formularza. Obie wartości przychodzą jako tekst („399.00” i „4”), ale operator * w PHP zamienia je na liczby: 399 × 4 = 1596 - jak na ilustracji 3 (R.5.9).
Typowe błędy
Wysłanie formularza z pustym polem „Liczba par” kończy się w PHP 8 błędem krytycznym „Unsupported operand types: string * string” przy mnożeniu ceny przez liczbę par - strona urywa się po nazwie buta (sprawdzone w PHP 8.2). Klucz tego nie sprawdza - zabezpieczenie ((int)) jest w etapie „Dobre praktyki”.
R.5.8 Skrypt 3 dla modelu buta pobranego z formularza wyświetla obraz, którego źródło pobrane jest z bazy oraz pozostałe informacje pobrane z bazy: nazwę produktu, kolor, materiał
R.5.9 Skrypt 3 wyświetla rozmiar buta oraz obliczony koszt jako wynik mnożenia ceny buta pobranej z bazy i liczby par pobranej z formularza
R.5.10 W skryptach zastosowana przynajmniej jedna zmienna lub funkcja oraz nazwy wszystkich funkcji i zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania
ok. 2 min
Polecenie z arkusza
Paragraf o treści: ”Szczegóły produktu: <kolor>, <materiał>”, gdzie wartości w nawiasach <> oznaczają dane pobrane zapytaniem. Paragraf o treści: „Rozmiar: <rozmiar>”, gdzie wartość w nawiasach <> oznacza dane pobrane z formularza.
Kolor i materiał z bazy ($row[2], $row[4]), rozmiar z formularza. Podgląd pokazuje komplet z ilustracji 3: brązowy, skóra naturalna - zamsz, rozmiar 42 (R.5.8, R.5.9, R.5.10).
Kroki 42-43 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 42: Zamówienie: zapytanie przygotowane i sprawdzenie danych
ok. 5 min
Polecenie z arkusza
Wykorzystuje dane wysłane z formularza.
Wersja z egzaminu ufa wszystkiemu, co przyszło z formularza. Poprawki:
zapytanie przygotowane (mysqli_prepare, ? w miejscu modelu, mysqli_stmt_bind_param z typem "s"): model idzie do bazy osobno od treści zapytania, więc tekst wpisany w żądanie nie zmieni zapytania,
(int) na rozmiarze i liczbie par oraz warunek: rozmiar 40 - 43, co najmniej jedna para, a model musi istnieć w bazie - inaczej komunikat zamiast pustej strony z błędami,
?? "" - brak pola w $_POST (wejście na zamow.php bez formularza) nie kończy się ostrzeżeniem,
mysqli_fetch_assoc - pola po nazwach ($shoe["cena"]) zamiast numerów,
htmlspecialchars przy wypisywaniu danych i number_format dla kwoty: 1 596,00 zł.
Wersja z egzaminu zostaje w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
Krok 43: Strona główna: pola po nazwach i htmlspecialchars
ok. 3 min
Polecenie z arkusza
Dla każdego zwróconego zapytaniem wiersza tworzy blok produktu.
W Skrypcie 2 mysqli_fetch_assoc zamiast mysqli_fetch_row: $shoe["nazwa_pliku"] czyta się lepiej niż $row[3] i nie psuje się, gdy ktoś zmieni kolejność kolumn w SELECT. Wszystko, co przychodzi z bazy, wypisujesz przez htmlspecialchars - także w opcjach listy w Skrypcie 1. Podgląd wygląda tak samo jak wcześniej, bo dane są te same. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
Krok 44 · po tym etapie masz 40 z 40 kryteriów (pkt)
Krok 44: 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 strony.
W folderze z numerem zdającego: index.php, zamow.php, style.css, kwerendy.txt, import.jpg, kw1.png - kw4.png, zdjęcia butów i przeglądarka.txt. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.
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.