Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
EE.09-04-21.06-SGCzerwiec 2021 · 30 kroków · ok. 74 min · 35 kryteriów z klucza
Rozwiązanie krok po kroku: Panel administratora portalu społecznościowego (Nowoczesny kod (flex, PDO))
To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza dane4 z czterema zapytaniami, wykadrowane zdjęcie 100 × 100 px i strona users.php z listą użytkowników i kartą osoby wybranej w formularzu - i tak samo spełnia każde kryterium klucza. Inna jest droga:
flexbox zamiast float: strona zawija bloki - baner i stopka zajmują cały rząd, bloki lewy i prawy po 50% stoją obok siebie bez clear,
zmienne CSS dla kolorów z arkusza, etykieta <label for> przy polu formularza,
PHP na PDO na górze pliku users.php, przed HTML-em, a dane połączenia w osobnym pliku config.php,
identyfikator z formularza sprawdzony jako liczba (filter_input) i wstawiony do zapytania przygotowanego - wstrzyknięcie SQL nie przejdzie,
komunikat, gdy osoby o podanym identyfikatorze nie ma w bazie, a wpisany identyfikator zostaje w polu po wysłaniu,
szablon z pętlą foreach: HTML stoi w pliku jak zwykły HTML, a PHP wstawia tylko wartości - każdą przez htmlspecialchars.
To arkusz EE.09 z czerwca 2021 - kwalifikacji formuły 2017, którą zastąpiła INF.03. Kroki bazy, grafiki i pliku settings.html są takie same jak w wersji podstawowej. Baza i zdjęcia pochodzą z oryginalnego archiwum CKE zad4.zip (załącznik na stronie arkusza), zapytania i zrzuty są policzone na MariaDB 10.4, a podgląd od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 7.4.8 - użyte konstrukcje działają w obu wersjach). Wiek w podglądzie jest liczony od roku 2026.
Jak liczą się punkty. Klucz ma 35 kryteriów (R.1.1 - R.5.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 27 punktów. Przy każdym kroku jest napisane, które kryteria spełnia; klucz przyjmuje zarówno mysqli, jak i PDO.
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 35 kryteriów (pkt)
Krok 1: Folder zdającego i archiwum zad4
ok. 2 min
Polecenie z arkusza
Na pulpicie znajduje się archiwum ZIP o nazwie zad4.zip zabezpieczone hasłem: *Uzytkownicy^Portalu$ Należy utworzyć folder o nazwie odpowiadającej numerowi PESEL zdającego lub w przypadku jego braku innemu numerowi, którym został podpisany arkusz. Archiwum należy rozpakować do tego folderu.
Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum zad4.zip otwierasz programem 7-Zip (albo innym programem do archiwów ZIP) i rozpakowujesz do tego folderu, podając hasło *Uzytkownicy^Portalu$ - z gwiazdką na początku i znakiem dolara na końcu. W środku jest plik dane.sql i osiem zdjęć: osoba1.jpg - osoba8.jpg.
Pliki strony muszą leżeć w tym samym folderze co zdjęcia - skrypt wstawi nazwę zdjęcia z bazy bez żadnej ścieżki.
Typowe błędy
Pliki zapisane poza folderem zdającego (np. w htdocs bez kopii w folderze) nie trafią na płytę - a ocenia się tylko to, co jest na płycie.
Krok 2: XAMPP i pusta baza dane4
ok. 2 min
Polecenie z arkusza
Uruchom usługi MySQL i Apache za pomocą XAMPP Control Panel. Za pomocą narzędzia phpMyAdmin wykonaj podane operacje na bazie danych: Utwórz bazę danych o nazwie dane4
W XAMPP Control Panel klikasz Start przy Apache i MySQL, potem w przeglądarce otwierasz http://localhost/phpmyadmin. Nowa w lewym panelu, nazwa dane4 (z cyfrą na końcu), Utwórz. Porównywanie napisów możesz zostawić domyślne - tabele z pliku i tak przyniosą własne kodowanie (latin1).
Typowe błędy
Baza dane (bez cyfry) to strata R.1.1 i R.5.1 - skrypt łączy się z bazą po nazwie, a klucz sprawdza nazwę dane4.
Krok 3: Import pliku dane.sql i zrzut egzamin.jpg
Kryteria:
R.1.1 Wykonano import tabel do bazy danych dane4 , czynność udokumentowano plikiem o nazwie egzamin w formacie JPEG
ok. 3 min
Polecenie z arkusza
Do bazy dane4 zaimportuj plik dane.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w folderze z numerem PESEL lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz, w formacie JPEG i nazwij egzamin. 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
Zaznacz bazę dane4, karta Import, Wybierz plik → dane.sql, Wykonaj. Plik tworzy pięć tabel: hobby (16 rekordów), osoby (40 rekordów) oraz puste producenci, produkty i rodzaje - do zadania potrzebne są tylko dwie pierwsze.
„Elementy wskazujące na poprawnie wykonany import” to zielony komunikat o sukcesie i lista tabel w lewym panelu albo na karcie Struktura bazy. Zrzut całego ekranu z paskiem zadań zapisujesz jako egzamin.jpg - w tym arkuszu w formacie JPEG, a zrzuty zapytań w PNG.
Typowe błędy
Ten zrzut ma nazwę egzamin i format JPEG. Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).
Podgląd strony po tym kroku
Krok 4: Zapytanie 1: pierwsze 30 osób
Kryteria: ,
R.1.2 Zapisano plik tekstowy o nazwie kwerendy zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Utworzono zapytanie 1 wybierające jedynie pola id, imie, nazwisko, rok_urodzenia, zdjecie z tabeli osoby . Kwerenda wybiera początkowe 30 wierszy, jawnie wskazana liczba wierszy. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, imie, nazwisko, rok_urodzenia, zdjecie FROM osoby LIMIT 30; oraz wynik działania zapytania udokumentowano zrzutem, na którym widocznych jest dokładnie 30 rekordów jedynie pola id, imie, nazwisko, rok_urodzenia, zdjecie
ok. 3 min
Polecenie z arkusza
Zapisz i wykonaj zapytania SQL działające na bazie dane4. Zapytania zapisz w pliku kwerendy.txt, w folderze z numerem PESEL lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie PNG i nadaj im nazwy kw1, kw2, kw3, kw4. Zrzuty powinny obejmować cały ekran monitora z widocznym paskiem zadań. Zapytanie 1: wybierające jedynie pola id, imie, nazwisko, rok_urodzenia, zdjecie z tabeli osoby. Kwerenda wybiera pierwsze 30 wierszy, należy jawnie wskazać liczbę wierszy
Zaznacz bazę dane4, karta SQL:
SELECT id, imie, nazwisko, rok_urodzenia, zdjecie - pięć kolumn z arkusza („jedynie” wyklucza SELECT *, które dołożyłoby Hobby_id i opis),
FROM osoby,
LIMIT 30 - jawnie wskazana liczba wierszy. Tabela ma 40 osób, a phpMyAdmin sam pokazuje 25 wierszy na stronę - dlatego limit musi stać w zapytaniu.
Wynik: 30 rekordów, od id 2 (Monika Kowalska) do id 31 (Grzegorz Roh). Zapytanie kopiujesz do pliku kwerendy.txt, a cały ekran zapisujesz jako kw1.png - przy 30 wierszach przewiń wynik tak, żeby było widać komunikat „Pokazano wiersze 0 - 29 (30 łącznie)”. To zapytanie wyśle skrypt w bloku lewym.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT id, imie, nazwisko, rok_urodzenia, zdjecie FROM osoby LIMIT 30;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: dane osoby o id 10 z nazwą hobby
Kryteria:
R.1.4 Utworzono zapytanie 2 wybierające jedynie pola imie, nazwisko, rok_urodzenia, opis, zdjecie z tabeli osoby oraz odpowiadające im pole nazwa z tabeli hobby dla osoby o id równym 10. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, rok_urodzenia, opis, zdjecie, nazwa FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id WHERE osoby.id = 10; możliwe INNER JOIN lub bez JOIN (porównanie kluczy w where) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest dokładnie jeden rekord: Roksana Rybnik 1995 pozdrawiam osoba3.jpg biegi
ok. 4 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie pola imie, nazwisko, rok_urodzenia, opis, zdjecie z tabeli osoby oraz odpowiadające im pole nazwa z tabeli hobby dla osoby o id równym 10
SELECT imie, nazwisko, rok_urodzenia, opis, zdjecie, nazwa - pięć kolumn z osoby i nazwa hobby z hobby,
FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id - złączenie: do osoby dołączany jest wiersz hobby o numerze z jej kolumny Hobby_id,
WHERE osoby.id = 10 - kolumna id jest w obu tabelach, więc trzeba wskazać tabelę.
Wynik: jeden rekord - Roksana Rybnik, 1995, pozdrawiam, osoba3.jpg, biegi, dokładnie jak w kluczu. Zrzut: kw2.png. To zapytanie wyśle skrypt w bloku prawym, z identyfikatorem z formularza w miejscu liczby 10.
Typowe błędy
Samo WHERE id = 10 przy złączeniu kończy się błędem #1052 („Column 'id' in where clause is ambiguous”).
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT id, imie, nazwisko, rok_urodzenia, zdjecie FROM osoby LIMIT 30;-- Zapytanie 2SELECT imie, nazwisko, rok_urodzenia, opis, zdjecie, nazwa FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id WHERE osoby.id = 10;
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: średni, najniższy i najwyższy rok urodzenia
Kryteria:
R.1.5 Utworzono zapytanie 3 liczące średni rok urodzenia oraz najniższy i najwyższy rok urodzenia z tabeli osoby . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT AVG(rok_urodzenia), MIN(rok_urodzenia), MAX(rok_urodzenia) FROM osoby; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne są jedynie dane: 1992.7 1967 2009 (pierwsza wartość z dowolnym zaokrągleniem)
ok. 2 min
Polecenie z arkusza
Zapytanie 3: liczące średni rok urodzenia oraz najniższy i najwyższy rok urodzenia z tabeli osoby
Trzy funkcje agregujące w jednym SELECT: AVG(rok_urodzenia) - średnia, MIN(…) - najmniejsza wartość, MAX(…) - największa. Funkcja agregująca zamienia całą tabelę w jeden wiersz wyniku.
Wynik: 1992.7000, 1967, 2009 - zgodnie z kluczem (1992,7 w dowolnym zaokrągleniu, najstarsza osoba urodziła się w 1967, najmłodsza w 2009). Zrzut: kw3.png.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT id, imie, nazwisko, rok_urodzenia, zdjecie FROM osoby LIMIT 30;-- Zapytanie 2SELECT imie, nazwisko, rok_urodzenia, opis, zdjecie, nazwa FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id WHERE osoby.id = 10;-- Zapytanie 3SELECT AVG(rok_urodzenia), MIN(rok_urodzenia), MAX(rok_urodzenia) FROM osoby;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: nowy opis dla osób z hobby 4
Kryteria:
R.1.6 Utworzono zapytanie 4 aktualizujące pole opis z tabeli osoby dla osób, których pole Hobby_id jest równe 4. Wartość pola opis dowolna. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE osoby SET opis="..." WHERE Hobby_id = 4; (dowolny wpis w miejscu kropek) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnie wykonanym zapytaniu lub tabela ze zmienionymi danymi
ok. 2 min
Polecenie z arkusza
Zapytanie 4: aktualizujące pole opis z tabeli osoby dla osób, których pole Hobby_id jest równe 4. Wartość nowego wpisu w polu opis jest dowolna będąca możliwym hobby
UPDATE osoby - zmiana istniejących rekordów,
SET opis = 'akrobatyka' - nowa wartość pola; arkusz pozwala wpisać dowolne hobby,
WHERE Hobby_id = 4 - tylko osoby z hobby numer 4 (gimnastyka).
W bazie jest jedna taka osoba - Anna Kowalska z id 25 - więc phpMyAdmin melduje 1 wiersz zmieniony. Zrzut: kw4.png (komunikat albo tabela ze zmienionym opisem). Plik kwerendy.txt ma komplet czterech zapytań.
Typowe błędy
UPDATE bez WHERE zmienia opis wszystkim 40 osobom - phpMyAdmin nie pyta o potwierdzenie, a cofnąć to można tylko ponownym importem.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT id, imie, nazwisko, rok_urodzenia, zdjecie FROM osoby LIMIT 30;-- Zapytanie 2SELECT imie, nazwisko, rok_urodzenia, opis, zdjecie, nazwa FROM osoby JOIN hobby ON osoby.Hobby_id = hobby.id WHERE osoby.id = 10;-- Zapytanie 3SELECT AVG(rok_urodzenia), MIN(rok_urodzenia), MAX(rok_urodzenia) FROM osoby;-- Zapytanie 4UPDATE osoby SET opis = 'akrobatyka' WHERE Hobby_id = 4;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-16 · po tym etapie masz 18 z 35 kryteriów (pkt)
Krok 8: Grafika: kadr 1:1 z twarzą
ok. 2 min
Polecenie z arkusza
Plik osoba1.jpg, wypakowany z archiwum, skadrowany do proporcji 1:1, tak aby była widoczna twarz osoby.
osoba1.jpg z archiwum ma 300 × 200 px - jest poziomy, a pozostałe zdjęcia są kwadratowe. W GIMP-ie narzędzie Zaznaczenie prostokątne z opcją Stała: proporcje 1:1, zaznaczenie 200 × 200 px (cała wysokość zdjęcia) przesunięte tak, żeby twarz była w środku - tutaj od x = 35 px - i Obraz → Przytnij do zaznaczenia. Podgląd pokazuje kadr przed skalowaniem.
Typowe błędy
Kadr z lewej krawędzi zdjęcia (x = 0) ucina twarz z prawej strony - klucz wymaga, żeby twarz była widoczna (R.2.1).
Podgląd strony po tym kroku
Krok 9: Grafika: rozmiar dokładnie 100 × 100 px
Kryteria:
R.2.1 Plik osoba1.jpg zawiera widoczną twarz osoby, rozmiar zdjęcia dokładnie 100 px na 100 px
ok. 2 min
Polecenie z arkusza
Przeskalowany do rozmiaru dokładnie 100 px na 100 px. Pozostałe pliki graficzne są przygotowane i nie należy ich zmieniać
Obraz → Skaluj obraz: szerokość 100, wysokość 100 - kadr jest kwadratowy, więc proporcje się nie zmieniają. Zapis pod tą samą nazwą: Plik → Nadpisz osoba1.jpg (zwykłe Zapisz w GIMP-ie zapisuje format .xcf). Zdjęcia osoba2.jpg - osoba8.jpg mają już 100 × 100 px i zostają bez zmian.
Typowe błędy
Skalowanie całego zdjęcia 300 × 200 do 100 × 100 bez kadrowania spłaszczy twarz.
Podgląd strony po tym kroku
Krok 10: Plik settings.html
ok. 1 min
Polecenie z arkusza
Odsyłacz o treści „Inne ustawienia” prowadzący do strony settings.html (należy utworzyć plik settings.html i zapisać w nim treść: „strona w trakcie budowy”)
Najpierw cel odsyłacza: w edytorze tworzysz plik settings.html z jednym zdaniem: strona w trakcie budowy. Arkusz każe zapisać w nim tylko tę treść, więc bez szkieletu HTML - przeglądarka i tak wyświetli tekst. Sam odsyłacz powstanie w bloku lewym.
settings.htmlHTMLnowy plik
strona w trakcie budowy
Podgląd strony po tym kroku (settings.html)
Krok 11: Plik users.php i kodowanie polskich znaków
Kryteria: ,
R.2.2 Witrynę internetową zapisano w pliku PHP o nazwie users.php
R.2.3 Zastosowano właściwy standard kodowania polskich znaków dla witryny
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie users.php. Zastosowany właściwy standard kodowania polskich znaków
Plik users.php w folderze zdającego, obok zdjęć - rozszerzenie .php, bo na jego górze stanie skrypt. Szkielet HTML5 z lang="pl" i od razu <meta charset="UTF-8"> jako pierwszy element <head>; sam plik zapisujesz w UTF-8 (R.2.2, R.2.3).
R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl4.css , formatowanie pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy źle przypisano co najmniej jednen selektor do bloku (np. kropka zamiast #)
ok. 2 min
Polecenie z arkusza
Tytuł strony widoczny na karcie przeglądarki: „Panel administratora”. Arkusz stylów w pliku o nazwie styl4.css prawidłowo połączony z kodem strony
<title> z napisem na karcie przeglądarki (R.2.4) i <link> do pliku styl4.css - z cyfrą w nazwie (R.3.5). Linia viewport to dodatek spoza arkusza: telefon pokazuje stronę w swojej szerokości, zamiast pomniejszać widok komputera.
R.2.5 Wygląd strony zdefiniowano dzieląc ją na bloki: baner, lewy i prawy, stopka. Zastosowano znaczniki sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: baner, lewy i prawy, stopka. 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. Zawartość banera: nagłówek trzeciego stopnia o treści „Portal Społecznościowy - panel administratora”
Znaczniki semantyczne w kolejności z obrazu 2: <header> z nagłówkiem <h3> (w tym arkuszu trzeciego stopnia), dwa bloki <section> z identyfikatorami left i right (po angielsku - arkusz ich nie narzuca) i <footer> (R.2.5).
Krok 14: Blok lewy: nagłówek i odsyłacz „Inne ustawienia”
Kryteria:
R.3.2 Na stronie umieszczono odnośnik "Inne ustawienia", po jego wybraniu otwiera się strona settings.html
ok. 1 min
Polecenie z arkusza
Zawartość bloku lewego: Nagłówek czwartego stopnia o treści „Użytkownicy”. Efekt działania skryptu 1. Odsyłacz o treści „Inne ustawienia” prowadzący do strony settings.html
<h4> i odsyłacz do pliku settings.html z kroku wyżej (R.3.2). Lista użytkowników stanie między nimi - wypisze ją szablon w części PHP.
Krok 15: Blok prawy: nagłówek, formularz i linia pozioma
Kryteria: , , ,
R.2.6 W bloku banera zapisano nagłówek h3: "Portal Społecznościowy - panel administratora" oraz w bloku lewym nagłówek h4: "Użytkownicy" i w bloku prawym nagłówek h4: "Podaj id użytkownika"
R.2.7 W bloku prawym umieszczono formularz z polem edycyjnym i przyciskiem, zastosowano zancznik <form> oraz jego zamknięcie
R.3.3 Formularz wysyła dane do tego samego pliku metodą POST
R.3.4 Pole edycyjne formularza jest typu number, przycisk ZOBACZ wysyła dane z formularza (np. typ submit dla input lub button albo button bez typu)
ok. 4 min
Polecenie z arkusza
Zawartość bloku prawego: Nagłówek czwartego stopnia o treści „Podaj id użytkownika”. Formularz wysyłający dane metodą post do tego samego pliku i zawierający: pole edycyjne typu numerycznego, przycisk wysyłający dane o treści "ZOBACZ”. Linia pozioma
<h4> - komplet nagłówków strony: <h3> w banerze i dwa <h4> (R.2.6),
<form method="post"> bez action wysyła dane do tego samego pliku (R.3.3),
<label for="id"> podpisuje pole - kliknięcie napisu ustawia kursor w polu, a czytnik ekranu odczyta, czego pole dotyczy. Atrybut for musi równać się id pola,
<input type="number"> z name="id" - pod tą nazwą wartość trafi do PHP, a min="1" nie pozwoli przeglądarce wysłać zera ani liczby ujemnej,
R.2.8 W stopce umieszczono napis „Stronę wykonał: ”, dalej wstawiony numer PESEL zdającego
ok. 1 min
Polecenie z arkusza
Zawartość stopki: napis o treści „Stronę wykonał: ”, dalej wstawiony numer PESEL zdającego lub w przypadku jego braku inny numer, którym został podpisany arkusz
Na egzaminie po dwukropku wpisujesz swój numer PESEL - tu w jego miejscu stoi Bartosz Bryniarski (R.2.8).
Kroki 17-21 · po tym etapie masz 27 z 35 kryteriów (pkt)
Krok 17: Plik styl4.css: kolory jako zmienne i krój Helvetica
Kryteria:
R.4.1 Ustawiono domyślny krój czcionki dla całej strony na Helvetica (dla selektora * lub body lub html lub kontenera całej strony)
ok. 2 min
Polecenie z arkusza
Cechy formatowania CSS: Domyślne dla całej strony: krój czcionki Helvetica
Na górze pliku zmienne CSS w :root - dwa kolory z arkusza, każdy wpisany raz, reguły sięgają po nie przez var(--dark-red). Potem selektor * z krojem Helvetica - obejmuje też pole i przycisk formularza (R.4.1).
Krok 18: Baner i stopka: tło, kolor, wyśrodkowanie, wysokość
Kryteria: ,
R.4.3 Ustawiono biały kolor czcionki dla banera i stopki
R.4.6 Ustawiono wyrównanie tekstu do środka dla banera i stopki
ok. 2 min
Polecenie z arkusza
Dla banera i stopki: kolor tła #AF4448, biały kolor czcionki, wyrównanie tekstu do środka, wysokość 20 px
Jedna reguła dla obu bloków (R.4.3, R.4.6). Druga reguła - margin: 0 dla <h3> w banerze - to dodatek wynikający z flexboksa z następnych kroków: element flexboksa trzyma marginesy nagłówka w sobie, więc bez zera napis zsunąłby się w pasku 20 px i wystawał na bloki poniżej. line-height: 20px wyrównuje wysokość linii nagłówka do wysokości paska - domyślna linia <h3> ma 22 px i wystawałaby o 2 px.
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z Obrazem 2 w arkuszu egzaminacyjnym
ok. 2 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
body jako flexbox z zawijaniem: baner i stopka z flex: 1 1 100% zajmują każdy cały rząd, a bloki lewy i prawy po 50% mieszczą się razem w rzędzie pomiędzy nimi - jak na obrazie 2 (R.3.1). Nie ma float, więc stopka nie potrzebuje clear.
Kroki 22-28 · po tym etapie masz 35 z 35 kryteriów (pkt)
Krok 22: Plik config.php i połączenie PDO na górze strony
Kryteria:
R.5.1 Skrypt realizuje połączenie z serwerem bazy danych i wybór bazy dane4
ok. 4 min
Polecenie z arkusza
Skrypt łączy się z serwerem bazy danych na localhost, użytkownik root bez hasła, baza danych o nazwie dane4
Dane połączenia trafiają do osobnego pliku config.php jako stałe: adres w formacie PDO (mysql:host=localhost;dbname=dane4;charset=utf8mb4 - serwer, baza dane4 i kodowanie), użytkownik root i puste hasło. Strona dołącza go instrukcją require.
Oba „skrypty” z arkusza korzystają z jednej bazy, więc w wersji nowoczesnej całe PHP stoi na górze users.php, przed <!DOCTYPE html>: najpierw pobiera dane, potem HTML je wyświetla w miejscach z obrazu 2. new PDO(…) łączy się z serwerem i wybiera bazę (R.5.1); z opcją ERRMODE_EXCEPTION każdy błąd bazy jest wyjątkiem, który łapie blok catch.
Od tego kroku podgląd to wynik prawdziwego uruchomienia w PHP 8.2 - na razie bez zmian.
config.phpPHPnowy plik
<?php// dane połączenia z bazą - w jednym miejscu, poza plikiem stronyconst DB_DSN = 'mysql:host=localhost;dbname=dane4;charset=utf8mb4';const DB_USER = 'root';const DB_PASSWORD = '';
users.phpPHPzmienione: 11 linii
<?phprequire'config.php';$users = [];$error = '';try {$pdo = new PDO(DB_DSN, DB_USER, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);} catch (PDOException $exception) {$error = 'nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę';}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Panel administratora</title> <linkrel="stylesheet"href="styl4.css"></head><body> <header> <h3>Portal Społecznościowy - panel administratora</h3> </header> <sectionid="left"> <h4>Użytkownicy</h4> <ahref="settings.html">Inne ustawienia</a> </section> <sectionid="right"> <h4>Podaj id użytkownika</h4> <formmethod="post"> <labelfor="id">id</label> <inputtype="number"id="id"name="id"min="1"> <buttontype="submit">ZOBACZ</button> </form> <hr> </section> <footer> Stronę wykonał: Bartosz Bryniarski </footer></body></html>
Podgląd strony po tym kroku (users.php)
Krok 23: Skrypt 1: zapytanie 1 i lista użytkowników z szablonu
Kryteria: , ,
R.5.2 Ostatnią operacją na bazie jest jej zamknięcie (zgodne ze składnią)
R.5.3 Skrypt 1 wysyła do bazy danych zapytanie 1 lub skrypt 2 wysyła zapytanie 2 zmodyfikowane w ten sposób, że w warunku jest przypisane id podane w formularzu
R.5.5 Skrypt 1 Wyświetla każdy zwrócony zapytaniem wiersz w osobnej linii o treści: "<id>. <imie> <nazwisko>" gdzie pola <id>, <imie>, <nazwisko> zostały pobrane z bazy (wiek nie jest sprawdzany w tym kryterium)
ok. 4 min
Polecenie z arkusza
Działanie skryptu 1 w panelu lewym: Wysyła do bazy danych zapytanie 1. Dla każdego wiersza zwróconego zapytaniem: Wyświetla w osobnej linii treść: <id>. <imie><nazwisko>, < wiek> lat, gdzie pola <id>, <imie>, <nazwisko> zostały pobrane z bazy, a <wiek> oznacza obliczony wiek osoby
$pdo->query('…')->fetchAll(PDO::FETCH_ASSOC) wysyła zapytanie 1 z kwerendy.txt (R.5.3) i od razu odczytuje 30 wierszy do tablicy $users - z kluczami z nazw kolumn: id, imie, nazwisko, rok_urodzenia, zdjecie,
PDO nie ma funkcji close - połączenie zamyka $pdo = null w bloku finally, który wykona się zawsze (R.5.2),
funkcja e() to krótsza nazwa dla htmlspecialchars,
w bloku lewym szablon: <?php foreach ($users as $row): ?> … <?php endforeach; ?> i jedna linia HTML na osobę - <?= … ?> wstawia wartość, <br> kończy linię (R.5.5).
Podgląd: 30 linii, od „2. Monika Kowalska” do „31. Grzegorz Roh”.
users.phpPHPzmienione: 11 linii
<?phprequire'config.php';$users = [];$error = '';try {$pdo = new PDO(DB_DSN, DB_USER, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);$users = $pdo->query('SELECT id, imie, nazwisko, rok_urodzenia, zdjecie FROM osoby LIMIT 30;')->fetchAll(PDO::FETCH_ASSOC);} catch (PDOException $exception) {$error = 'nie udało się połączyć z bazą danych, spróbuj ponownie za chwilę';} finally {$pdo = null;}functione(?string $text): string{returnhtmlspecialchars($text ?? '', ENT_QUOTES, 'UTF-8');}?><!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Panel administratora</title> <linkrel="stylesheet"href="styl4.css"></head><body> <header> <h3>Portal Społecznościowy - panel administratora</h3> </header> <sectionid="left"> <h4>Użytkownicy</h4><?phpforeach ($usersas$row): ?><?= e($row['id']) ?>. <?= e($row['imie']) ?><?= e($row['nazwisko']) ?><br><?phpendforeach; ?> <ahref="settings.html">Inne ustawienia</a> </section> <sectionid="right"> <h4>Podaj id użytkownika</h4> <formmethod="post"> <labelfor="id">id</label> <inputtype="number"id="id"name="id"min="1"> <buttontype="submit">ZOBACZ</button> </form> <hr> </section> <footer> Stronę wykonał: Bartosz Bryniarski </footer></body></html>
Podgląd strony po tym kroku (users.php)
Krok 24: Skrypt 1: wiek z roku urodzenia
Kryteria:
R.5.4 Skrypt 1 oblicza wiek osoby na podstawie jej roku urodzenia, np. z wykorzystaniem funkcji date('Y') lub wykorzystując rok 2019 lub 2021
ok. 2 min
Polecenie z arkusza
Oblicza wiek osoby na podstawie jej roku urodzenia
Bieżący rok jest odczytany raz, na górze pliku: (int) date('Y'). W szablonie od niego odejmowany jest rok urodzenia - zamieniony na liczbę rzutowaniem (int), bo PHP 7.4 z XAMPP wskazanego w kluczu zwraca liczby z bazy jako tekst (PHP 8.1 i nowsze - już jako liczby; rzutowanie działa w obu przypadkach) (R.5.4). Wynik jest liczbą obliczoną przez skrypt, więc nie potrzebuje e().
Podgląd liczy od roku 2026: Monika Kowalska z rocznika 1976 ma 50 lat (obraz 2 w arkuszu powstał w 2019 roku).
Krok 25: Skrypt 2: identyfikator, zapytanie przygotowane i nagłówek
Kryteria:
R.5.6 Skrypt 2 wyświetla nagłówek h2 o treści <id>. <imie> <nazwisko>, gdzie pole <id> jest identyfikatorem pobranym z formularza, a pola <imie>, <nazwisko> są polami pobranymi z bazy
ok. 5 min
Polecenie z arkusza
Działanie skryptu 2 w panelu prawym wykonywanego po wypełnieniu formularza: Wysyła do bazy danych zapytanie 2, zmodyfikowane w ten sposób, że w warunku zamiast przypisanego numeru id równego 10, jest numer id przesłany z formularza. Wyświetla nagłówek drugiego stopnia o treści <id>. <imie><nazwisko>, gdzie pole <id> jest identyfikatorem pobranym z formularza, a pola <imie>, <nazwisko> są polami pobranymi z bazy
filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT, …) odczytuje pole id z formularza i zwraca liczbę całkowitą od 1 w górę - albo false, gdy przyszło coś innego, i null, gdy formularz nie był wysłany. Do zapytania trafia tylko prawdziwa liczba,
zapytanie 2 jako zapytanie przygotowane: w miejscu liczby 10 stoi parametr :id, a execute(['id' => $id]) przekazuje wartość osobno - baza nigdy nie potraktuje jej jak fragmentu SQL,
fetch() odczytuje jedyny wiersz; przy braku osoby zwraca false, które ?: null zamienia w null,
połączenie zamyka finally - także obiekt zapytania ($statement = null).
W bloku prawym, pod linią: <?php if ($user): ?> - karta pokaże się tylko wtedy, gdy osoba została znaleziona - i nagłówek <h2> z identyfikatorem z formularza oraz imieniem i nazwiskiem z bazy (R.5.6). Podgląd: formularz wysłany z wartością 10, jak na obrazie 2.
R.5.8 Skrypt 2 wyświetla trzy paragrafy (akapity) z rokiem urodzenia, opisem i hobby, wartości zostały pobrane z bazy
ok. 2 min
Polecenie z arkusza
Wyświetla trzy paragrafy (akapity) o treści, kolejno: Rok urodzenia: <rok_urodzenia>, gdzie pole <rok_urodzenia> jest pobrane zapytaniem; Opis: <opis>, gdzie pole <opis> jest pobrane zapytaniem; Hobby: <nazwa>, gdzie pole <nazwa> jest pobrane zapytaniem
Trzy <p> z wartościami z wiersza $user, każda przez e() - opis to wpis użytkownika portalu i może zawierać znaczniki (R.5.8). Strona spełnia wszystkie kryteria arkusza.
Krok 28: Komunikaty: brak osoby, zły identyfikator, baza niedostępna
ok. 3 min
Dodatek spoza arkusza - klucz go nie ocenia. Nad kartą osoby stoi łańcuch warunków if / elseif:
baza nie odpowiada - komunikat ze zmiennej $error (sprawdzone ze złym hasłem w config.php: reszta strony działa, treść błędu z bazy nie trafia na ekran),
formularz wysłany, ale filter_input odrzucił wartość - prośba o liczbę. Sprawdzone: wartość 0 OR osoby.id = 2, która w wersji podstawowej wstrzykiwała SQL, kończy się tym komunikatem,
poprawny identyfikator, którego nie ma w bazie - „Nie ma użytkownika o identyfikatorze 99.” zamiast pustej karty.
Pole formularza dostaje value z wysłanym identyfikatorem - po kliknięciu „ZOBACZ” numer zostaje w polu i można go zmienić strzałką o jeden. Podgląd: wysłany identyfikator 99.
Krok 29 · po tym etapie masz 35 z 35 kryteriów (pkt)
Krok 29: Co jest inaczej i którą wersję wybrać na egzaminie
ok. 3 min
Obie wersje dają komplet 35 punktów. Różnice:
wersja podstawowa
wersja nowoczesna
układ
float: left bloków, clear stopki
body jako flexbox z zawijaniem
kolory
wpisane w każdej regule
zmienne --dark-red, --pink
formularz
samo pole i przycisk
label for, min="1", wysłany numer zostaje w polu
biblioteka
mysqli (tabela 1 arkusza)
PDO z wyjątkami, dane połączenia w config.php
gdzie jest skrypt
dwa bloki PHP w miejscach z obrazu 2, HTML w echo
jeden blok na górze pliku, w blokach strony szablon
identyfikator z formularza
wklejony w treść zapytania
filter_input + zapytanie przygotowane z :id
brak osoby o tym id
ostrzeżenia PHP
komunikat
wypisywanie danych
wprost (w etapie „Dobre praktyki” - htmlspecialchars)
każda wartość przez e()
zamknięcie bazy
mysqli_close na końcu drugiego skryptu
$pdo = null w finally, przed HTML-em
Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 arkusza i łatwiej ją napisać bez dokumentacji. Wersja nowoczesna nie przepuszcza wstrzyknięcia SQL, nie wywraca się na pustym polu ani na nieistniejącym identyfikatorze - a klucz przyjmuje obie.
Krok 30 · po tym etapie masz 35 z 35 kryteriów (pkt)
Krok 30: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
UWAGA: po zakończeniu pracy utwórz w folderze z numerem PESEL lub w przypadku jego braku w folderze z innym numerem, którym został podpisany arkusz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt nazwa przeglądarki, w której sprawdzana była strona. W folderze z numerem zdającego: egzamin.jpg, kw1.png - kw4.png, kwerendy.txt, users.php, config.php (bez niego strona nie połączy się z bazą), settings.html, styl4.css, osoba1.jpg - osoba8.jpg 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.